How Linux Works: What Every Superuser Should Know

12.5 CUPS

With these preliminaries out of the way, let's look at CUPS. CUPS has several interfaces, including a Web-based status and administration tool. The Web interface is very good for normal maintenance and operation, but unfortunately , if your needs lie outside the abilities of the interface, you still have to know how the system works and where the various configuration files reside.

You can install CUPS anywhere you like. Most distributions use a /usr installation prefix, so the clients are in /usr/bin , the system programs are in /usr/sbin , and so on. This book assumes that your directory prefix is /usr . Here are the directory locations and contents:

12.5.1 Configuring cupsd

The central server and scheduler in CUPS is named cupsd , and the central configuration file is cupsd.conf . You normally do not need to do anything to get a working cupsd , but a stock configuration file isn't usually very secure (see Section 12.5.2).

Examine the configuration file to get an overview of the things you can change. If you have ever configured the Apache Web server, you will immediately observe similarities between the httpd configuration files and the CUPS files.

Your cupsd.conf file contains a lot of information, but first look for the AccessLog path and change it if you want the log file in some other place:

AccessLog /var/log/cups/access_log

The default IPP port is 631, so you should see the following line:

Port 631

You should not need to change this. However, you may wish to add more ports with the Listen keyword.

The following parameters select the user and group that run all tasks except the cupsd server. You likely do not need to change these, but you may need to add the user and group to your system:

User lp Group sys

12.5.2 CUPS Security

Before you start CUPS, you should get a handle on security matters. Configured and installed from source code, CUPS does not have an enviable level of security, and you should do something about that before you even start the server. If your CUPS installation came with a Linux distribution, you should still take a look through this section to verify that you have a practical level of security.

This section covers how to configure digest authentication, the most useful type of authentication available for the CUPS Web administration interface. Run through the following steps on a new installation:

  1. Scan your cupsd.conf for a section that looks like this:

    <Location /admin> AuthType Basic AuthClass System ## Restrict access to local domain Order Deny,Allow Deny From All Allow From 127.0.0.1 #Encryption Required </Location>

  2. Change AuthType Basic to AuthType Digest . Basic authentication sets up a Web browser to send Unix user passwords as plain text. As earlier in the networking chapters, this is a really bad idea.

  3. Run the following command to add an admin user to the CUPS digest password file ( /etc/cups/passwd.md5 ):

    lppasswd -a admin

  4. When prompted, choose a password containing at least six characters and one number.

Certificate Authentication (for Command-Line Utilities)

You are now set up to use the CUPS Web interface securely. However, you will inevitably turn to command-line administration programs such as lpadmin when managing CUPS. These utilities also require authentication because they operate through the same network port as the Web interface. However, you may notice that you don't need a password to run these command-line programs as the superuser. Why is this so?

The answer is that CUPS has another form of authentication called certificate authentication, used primarily by the command-line programs and internal server communication. The CUPS scheduler places identifiers in the certificate directory /etc/cups/certs for various purposes, but the one you care most about is /etc/cups/certs/0 . Any user that can read this file can run administrative programs without a password, because these programs send the certificate instead of a username and password.

Note  

Don't use chmod to allow administrative access for non-root users because you may inadvertently allow administrative access for anyone on the system. Instead, add the desired users to the Unix group specified by the Group directive from Section 12.5.

12.5.3 Starting CUPS

With your security situation now under control, you're ready to start the CUPS scheduler and add some printers. To start CUPS, all you need to do is run cupsd as the superuser. If you compile CUPS from source code, you should take careful note that the install procedure modifies your init.d and rc.d boot directories to make CUPS part of your startup sequence.

To test your installation, access the Web interface by pointing a Web browser to CUPS at this URL (notice that this is the IPP port on your machine):

http://localhost:631/

This should yield a screen with several printing options. There are no printers in a new CUPS installation, so adding a printer is your first order of business.

12.5.4 Adding and Editing Printers

The easiest way to add a printer is with the Web interface (there is an Add Printer button on the printer list page). The first time you try to do any administration task, CUPS asks you for a username and password. Use the admin user and password that you configured in Section 12.5.2.

To add a printer with the command-line interface, use the lpadmin command. The bare minimum command for adding a printer without a print filter is as follows :

lpadmin -p name -v device

Depending on your configuration, you may need the -E option to specify encryption.

Adding a Test Printer

As is the case with most Unix utilities, commands like lpadmin do nothing more than modify text files (except that with CUPS, lpadmin opens a network connection to the CUPS server, sends some data, and then the server changes the files). You should know exactly what happens when you run lpadmin .

Add a dummy test printer by going through the following steps:

  1. Run lpadmin to add the printer:

    lpadmin -p test -v file:/dev/null

  2. Use lpstat to verify that the printer is there:

    lpstat -p

    Your new printer should show up as follows:

    printer test disabled since Jan 01 00:00 - reason unknown

  3. Examine /etc/cups/printers.conf . You should see an entry like this:

    <DefaultPrinter test> Info test DeviceURI file:/dev/null ... ... </Printer>

  4. Activate your printer:

    lpadmin -p test

    The lpstat -p command should now report the printer as idle rather than disabled.

  5. Send a test job to the printer:

    echo test lp -d test

  6. Verify that the job started by looking at /var/log/cups/error_log . The file-name is somewhat misleading, because error_log also contains normal diagnostic messages. You should see some entries that look like this:

    I [05/Oct/2003:14:44:46 -0700] Started "/usr/lib/cups/cgi- bin/printers.cgi" (pid=17156) I [05/Oct/2003:14:46:23 -0700] Adding start banner page "none" to job 1. I [05/Oct/2003:14:46:23 -0700] Adding end banner page "none" to job 1. I [05/Oct/2003:14:46:23 -0700] Job 1 queued on 'test' by ' user '.

  7. The job should also complete. Use the following command to make sure this is the case:

    lpstat -W completed -l test

    The output should look like this:

    test-1 user 1024 Sun Oct 5 14:46:23 2003 queued for test

  8. Remove the test printer when you're finished by using this command:

    lpadmin -x test

This lengthy procedure confirms that your CUPS server is running and that you can add and modify printers.

Adding a Real Printer

Now that you have some familiarity with the process, you are ready to add a real printer with a particular model using this command:

lpadmin -p name -v device -m model

The model parameter is extremely important because it provides printer-specific information, including the printer driver specification. If you do not use the -m parameter, CUPS uses a "raw" print model, sending unfiltered input directly to the printer. You almost certainly do not want this, because printers can generate copious amounts of garbage upon receiving bad input.

If you want to make the new printer the default, run this command:

lpoptions -d name

For the most part, you provide a PostScript Printer Description (PPD) filename as model . You can get a list of PPD files with this command:

lpinfo -m

However, in a stock CUPS installation, it's unlikely that the output list will contain an appropriate PPD entry for your printer, even though some of the entries may look tempting. Before discussing PPD files (see Section 12.5.6 for more information on those), let's briefly look at how to specify a device for the -v option in the earlier lpadmin command.

12.5.5 Printer Devices (Backend Specifications)

As you might surmise from the file:/dev/null specification in the test printer you created, you specify devices with Uniform Resource Identifiers (URIs). You can get a partial list of URI options with the lpinfo command:

lpinfo -v

The output looks something like this:

network socket network http network ipp network lpd direct parallel:/dev/lp0 direct scsi serial serial:/dev/ttyS0?baud=115200 serial serial:/dev/ttyS1?baud=115200 ... ...

The right-hand column contains backend types and complete URIs. You might see the following backends:

CUPS does not let you choose a backend that it knows it cannot reach. For example, if your kernel does not have parallel port support, CUPS does not list parallel ports when you run lpinfo -v . However, the system isn't perfect; a port showing up in the list does not mean that support actually exists.

Each one of these backend specifications uses its own separate backend program located in /usr/lib/cups/backend . The backend comes in at the very end of the print process.

12.5.6 PPD Files

After choosing an appropriate device, you can complete the printer definition with a PPD file. CUPS uses PPD files for its printer database.

A PPD file is in plain text and describes a printer's capabilities. CUPS keeps its default PPD files in /usr/share/cups/model ; to make the options in a new PPD file available to the CUPS Web interface, put the file in /usr/share/cups/model and send your cupsd a HUP signal. When you import a PPD file into the CUPS PPD file database with lpadmin -m , CUPS makes a copy of the file in /etc/cups/ppd .

The PPD file gives you fine control over printing options. Notice that if you choose the raw interface (that is, no PPD file), you get no options with the Configure Printer button in the CUPS Web interface, so you cannot change media, duplex, banner page, and other settings.

Here is the general printer and file information from the PPD file of an Apple LaserWriter 16/600:

*FormatVersion: "4.3" *FileVersion: "1.1" *LanguageVersion: English *LanguageEncoding: ISOLatin1 *PCFileName: "POSTSCRI.PPD" *Manufacturer: "Apple" *Product: "(LaserWriter 16/600)"

Looking elsewhere in the file, you might see some information on page sizes:

*PageSize Letter/US Letter: "<</PageSize[612 792]/ImagingBBox null>>setpagedevice" *PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"

A standard PPD file should also contain font information:

*DefaultFont: Courier *Font AvantGarde-Book: Standard "(001.006S)" Standard ROM *Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM *Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM *Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM *Font Bookman-Demi: Standard "(001.004S)" Standard ROM *Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM *Font Bookman-Light: Standard "(001.004S)" Standard ROM *Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM *Font Courier: Standard "(002.004S)" Standard ROM *Font Courier-Bold: Standard "(002.004S)" Standard ROM

The preceding excerpts are from a GPL version of a PPD file. PostScript printer manufacturers provide PPD files for their products, and for the most part, these should work fine with CUPS. However, non-PostScript printers do not normally come with PPD files, so they need a third-party PPD file that specifies a print filter to rasterize PostScript. You can get CUPS PPD files at sites such as http://www.linuxprinting.org/.

12.5.7 Specifying a Filter

One of the most frequently encountered problems with CUPS is that many of the PPD files you find on the Internet contain CUPS-specific print filter parameters that you may not have on your system. You should be able to recognize these parameters and have an idea of how to correct or delete them as you go.

CUPS filters convert file formats in two ways:

CUPS Filters and mime.convs

CUPS comes with a number of filters in /usr/lib/cups/filter that transform various intermediate file formats into printer-ready data. However, it is difficult to see where and how CUPS runs these filters.

When you print a file, you can observe something like the following in the log file (this example is for a text file):

Started filter /usr/lib/cups/filter/texttops (PID 3999) for job 25. Started filter /usr/lib/cups/filter/pstops (PID 4000) for job 25.

To get this detailed logging, the LogLevel parameter in your cupsd.conf must be a minimum of info . However, info does not log the initial input file type; you need to set the parameter to debug in order to log this additional information.

In the log, you can see some filters running, and from the names of the filters, you know that CUPS has some sort of idea about the job's file type. Unfortunately, the actual workings of the conversion mechanism aren't terribly obvious from the log file output. Here's how the sequence works:

  1. CUPS determines the output format that the backend needs to send to the printer by looking at the PPD file.

  2. CUPS determines the input file type with the help of /etc/cups/ mime.types . In the preceding example log output, the application/ postscript rule in /etc/cups/mime.types matched.

  3. CUPS looks through the /etc/cups/mime.convs file for a suitable filter to perform the conversion between the input file format and the format that the backend needs. Consider this line from mime.convs that transforms plain-text files to PostScript output:

    text/plain application/postscript 33 texttops

    The four columns here are the input MIME type, the output MIME type, the estimated cost, and the name of the filter program that converts the input to the output.

  4. CUPS runs the filter or filter sequence required for the printer backend. If there are no suitable entries in mime.convs , CUPS logs this message:

    Unable to convert file 0 to printable format for job n !

  5. CUPS runs any necessary additional filter before handing the final output to the backend (see the next section).

Specifying a Backend Filter in the PPD File

Just before sending the job to the printer backend, CUPS may run a backend filter from the PPD file.

Backend filters are set with the cupsFilter parameter in the PPD file. Here is an example from the PPD file that you saw earlier:

*cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"

As you can see, the cupsFilter parameter's value consists of three parts :

  1. An expected MIME type. In the preceding example, the type is PostScript. The default is application/vnd.cups-postscript .

  2. The relative cost of the filter (set this to 0).

  3. The filter's executable name.

The preceding cupsFilter parameter is very typical for printers that do not understand PostScript. Foomatic is a print filter that handles many different kinds of printers.

There are a few gotchas with the cupsFilter setting:

There is good news, though. Most PPD files that you find on the Web work fine if all of your software (Ghostscript, Foomatic, CUPS, and so on) is installed correctly.

12.5.8 Foomatic (for Non-PostScript Printers)

If your printer does not have native PostScript support, there may still be one more piece of the puzzle to configure ” the rasterizer filter. There are several options here, but the most popular system at the moment is Foomatic.

Before going into details about Foomatic, you should be clear on the end goal here: you want a print filter to run a Ghostscript ( gs ) command to render PostScript input into bitmap form to send to the printer. The command arguments look something like this:

gs -q -dSAFER -dNOPAUSE -dBATCH device_options -sOutputFile=- -

This seems simple enough, but unfortunately, device_options can be a tremendous mess. There are countless combinations of printer data formats and options. Foomatic attempts to resolve these problems with a database containing options for nearly every printer model out there. You may see references to this database all over the Web but very little information on how to actually use the database.

What most documentation fails to mention is that most administrators and users don't even interact with the database. All you need to worry about is building printer configuration data, such as PPD files. In fact, this work is already done for you when you visit http://www.linuxprinting.org/ to get a PPD file for your printer. All of the information that the Foomatic filter program ( foomatic-rip ) needs is in that PPD file. For example, here is a portion of the HP LaserJet 1100 PPD file that contains Ghostscript arguments:

*FoomaticRIPCommandLine: "gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPA&& USE -sDEVICE=ijs -sIjsServer=hpijs%A%B%C -dIjsUseOutputFD%Z -sOutputFi&& le=- -" *End

Note  

See Section 12.6.3 for notes on certain HP printer drivers.

Testing Foomatic

To use Foomatic as a filter, you need the foomatic-rip program in lib/cups/filter (a symbolic link to another location works fine). You can verify that Foomatic produces the correct printer output by running foomatic-rip on the command line, generating printer output by hand. You can then send this data directly to the printer, bypassing the print spooler.

First, locate your printer's PPD file ( ppd_file ) and find a test PostScript file to test with ( test_file .ps ). Run this command to create printer data in test.prn :

foomatic-rip -v --ppd ppd_file test_file .ps > test.prn

The -v option specifies verbose operation so that you can see exactly what the filter is doing. If everything goes well, you should see the following at the end of the diagnostic messages:

KID4 exited with status 0 Renderer exit stat: 0 Renderer process finished Closing foomatic-rip.

Successful completion also means that test.prn should now be a gigantic (probably binary) file that you can send directly to the printer device.

12.5.9 Administrative Command Overview

With the mess of print filters hopefully behind you, it's time to learn some commands for day-to-day tasks. Compared to other Unix server systems, it isn't terribly important that you know the syntax of every last command, because the Web administration interface does an adequate job in most cases (and is sometimes far preferable to the command line ” for example, when doing printer media option configuration).

However, you should develop at least a passing familiarity with the following commands (remember that each command has a manual page):

12.5.10 Client Access Control

By default, CUPS allows printer and administration access only to localhost. If you have a network of machines that you want to grant access to your CUPS server, then you have to change your cupsd.conf file to reflect this.

To get an idea of how per-client access control works, edit your cups.conf file and search for the line that reads <Location /> . It should start with a section that looks like this:

<Location /> Order Deny,Allow Deny From All Allow From 127.0.0.1 </Location>

The Location / section defines global access-control parameters for the CUPS server. In the preceding example, the directives work together to give access to localhost (127.0.0.1) and nothing else:

If you want to allow access for all of your printers to more clients, you can just add another rule directive after the Allow From 127.0.0.1 line. The following rule directive grants access to the subnet defined by 10.0.1.0/255.255.255.0 :

Allow From 10.0.1.0/255.255.255.0

You may have as many Allow From client lines as you like, and you can specify the client parameter in several ways. The following five specification types are the most useful:

Remember that the Location / section is for global access, including printer job control and other client tasks. Administrative tasks, on the other hand, have their own Location section ( <Location /admin> ) that specifically excludes connections from all hosts except localhost. In fact, you have already seen this section when you forced CUPS to digest authentication. Search for it in your cupsd.conf to verify that it allows administrative access to localhost, and to nothing else.

Note  

You can specify per-printer client access by adding <Location /printers/name> access control sections, where name is the name of a printer. You'll probably need to experiment for a while to get it to work perfectly .

12.5.11 Auto-Discovery

One of the more interesting CUPS features is automatic network printer discovery. This is called browsing . Most CUPS installations have browsing active by default, meaning that CUPS listens for messages from other print servers on the network. The cupsd.conf parameter is Browsing :

Browsing On

However, without additional help, your CUPS server will likely not make itself known to the other print servers on the network. To make your CUPS server broadcast its presence, you need a BrowseAddress broadcast address parameter in cupsd.conf . For example, to send notification packets to as many hosts on the network as possible ( essentially , as many as your routers allow), use this parameter:

BrowseAddress 255.255.255.255

You can think of a numeric broadcast address as a sort of inverse subnet combined with an IP address. For example, to send packets to the subnet defined by 10.1.2.0/255.255.255.0, try this:

BrowseAddress 10.1.2.255

This said, the best choice is likely the "local" interface selection that sends broadcast packets out to all network interfaces except PPP links:

BrowseAddress @LOCAL

If you have a server with several Ethernet interfaces, but do not want to broadcast on all of these interfaces, use @IF . For example, here's how to broadcast to eth1 :

BrowseAddress @IF(eth1)

12.5.12 Running an LPD-Compatible Server

Browsing and broadcasting goes a long way toward allowing communication between various CUPS servers on a network, but if you want older clients running Berkeley LPD printing systems to be able to print to your CUPS server, you need to configure your server to allow jobs from these clients.

To do this, run a special LPD server frontend called cups-lpd located in /usr/lib/cups/daemon . This is an inetd service (see Section 6.3), so you want a line like this in your /etc/inetd.conf (or the xinetd equivalent):

printer stream tcp nowait cups-user /usr/lib/cups/daemon/cups-lpd cups-lpd

cups-user is your CUPS User parameter from cupsd.conf (usually lp ). There is no built-in access control in cups-lpd , but like any other network service, you want to make sure that your firewall rules have adequate coverage; see Section 5.13. Remember that printer is defined in /etc/services as port 515.

12.5.13 Troubleshooting CUPS

When you have a problem with CUPS, it's particularly important to take things one step at a time. You may find this sequence helpful:

  1. Make sure that CUPS is working properly by creating a test printer with no filters (raw mode) and a device of file:/dev/null . Send a test file to the printer with the Web interface and lp , and verify that the jobs complete with lpstat :

    lpstat -W completed -o test_printer_name lpstat -o test_printer_name

  2. Use your printer's PPD file to activate your filter. See Sections 12.5.4 and 12.5.6 for more detail if something goes wrong. Print more test files, again making sure that the jobs finish.

  3. Add the printer's actual device, and then try another test job. If necessary, try printing to a file, then sending the file directly to the printer.

If a test print job fails and stalls, the printer state changes to "not ready," and you need to start the printer again to retry the job or run any new jobs. Do this with enable printer or the Web interface. Before you start changing files around, though, you should look at your log files, which are described in the next section.

Error Messages

The complex nature of the print spooler and filters makes it crucial that you pay careful attention to your log messages. The most important log file is /var/log/cups/error_log (the name is slightly misleading because the file also contains normal diagnostic messages).

Looking at the log reveals this format:

I [ timestamp ] Started filter /usr/lib/cups/filter/pstops (PID 3434) for job 26. D [ timestamp ] ProcessIPPRequest: 10 status_code=0 E [ timestamp ] [Job 26] unable to open print file - : Permission denied

The letter at the start of the line indicates the message severity or priority. The three letters in the preceding example are as follows:

You can change the log level with the LogLevel parameter in the cupsd.conf file. The default level is info in most installations. If you want the debugging messages, you must use debug . If you change your LogLevel parameter, remember to reload your configuration file after making any changes by sending a HUP signal to cupsd .

Filter Problems

The first thing you should do after running into trouble in the print filter stage is to make sure that the CUPS filters in /etc/cups/mime.convs function properly.

To do this, first disable any filters that you might have in your printer's PPD file so that you can eliminate the backend filter from the list of things that can go wrong. You will probably only have such filters if you are using a non-PostScript printer. If that's the case, edit your printer's PPD file (the one in /etc/cups/ppd ), looking for a cupsFilter parameter (see Section 12.5.7). Comment out the parameter by adding a % just after the * ; for example:

*%cupsFilter: "application/vnd.cups-postscript 0 foomatic-rip"

After making this change (and making cupsd re-read its configuration with a HUP signal), submit a test job to see if data can make it past the mime.convs filter stage to the printer device. Although you are not likely to run into any trouble with the CUPS-supplied filter programs in mime.convs , this process may help you uncover spool directory permissions problems (discussed in the next section) because these sorts of problems usually show up in the initial print filter stages.

Having worked out any kinks not involving the cupsFilter filter, re-enable this parameter and look for more trouble:

Spool Directory Permission Errors

Look for this message in your error log:

E [ timestamp ] [Job n ] unable to open print file - : Permission denied

CUPS normally runs its filters as the pseudo-user lp and the group sys, so this user must have access to the spool directory /var/spool/cups in order to access intermediate data. When fixing the permissions, look for these problems:

Device Problems

After running through the filter gauntlet, you are ready to send output to devices. Fortunately, there is relatively little that can go wrong at this final stage:

Категории