- CUPS
- Linux
Setting up a Printer Server with CUPS
Printing in Linux
Reading is very much like other activities, it comes better when you are doing it off a screen. But in order to do that, first you need to print.
Enters the Common Unix Printing System; CUPS for friends.
CUPS takes care to send whatever your client applications wants to print to the actual printer by passing it through a series of filters, which converts it to a format that your printer can understand and transmitting it via a suitable protocol.
If you decide to centralize your printer management by using a printer server, then you will have your central instance(s) of cupsd
and each end-user workstation will have its local cupsd
daemon that responds only to localhost (the latter being the default configuration).
The cupsd
on the workstations will accept the print jobs of the local users and send them via IPP to your central cupsd
instance(s). Your central cupsd
instance(s) will then forward them to the correct printer(s).
Drivers will need to be installed both on the Printer Server instance(s) of cupsd
as well as on the workstations instance(s); this is because every system in the chain will need at some point one or more pieces of this information:
– PostScript Printer Definition files (what kind of paper, does your printer support duplex..)
– Filters (translate this PDF into the funky language the remote printers understands)
– Backends (send this raw data via AppSocket/JetDirect, parallel port…)
The driver situation is current as of CUPS version 2.4.11; in a later major version of CUPS many things will be simplified as the printer industry is converging on the Internet Printing Protocol. IPP runs on top of HTTP as a transport protocol and uses a few standardized formats to encode the document being transmitted.
With recent printers that fully support IPP Everywhere (that is IPP/2.0, PWG raster, JPEG and PDF as encoding formats) you can do away with drivers.
My glorious HP LaserJet M401dn has just reached adolescence (she’s thirteen this may 2025), and since I would not (usually) kill an adolescent, I’ve stuck to drivers and backends.
Can you at least spare me a bit of headache?
No. CUPS is well documented; I’m not going to tell you how to install it and make a basic configuration work; I just want to share a few things that are not obvious at first look.
cups
will search for it’s TLS certificate in a hardcoded way
It will search for two files:
– hostname.crt for the public key with all the intermediate CAs, encoded in PEM format.
– hostname.key for the private key.
hostname is as it is provided by the hostname(1)
command, which means usually an fqdn. As far as I know there is no way to have cupsd
search for a different set of files, it is what it is.
You can use the ServerKeychain
directive in cups-files.conf
but that only changes the directory cupsd
will look into, not the format nor the name of the files.
How to locate the right printer driver for your printer
Use the lpinfo
command; for example lpinfo -E -m | grep M401
How to add, configure and remove a printer
Use the lpadmin
command; for example:
lpadmin -p M401dn -E -v ipp://itmil01pb001.corp.cavanasystems.com/ipp/print -m lsb/usr/HP/hp-laserjet_400_m401-ps.ppd.gz -o cupsIPPSupplies=true -o PageSize=A4 -o Duplex=DuplexNoTumble -o MediaType=Plain
Behind the curtains a PPD file is created into /etc/cups/ppd
. That file contains all the nitty-gritty details about your printer and the defaults you just configured.
What can trick me into thinking I configured a printer default, while I did something else instead?
Using the lpoptions
command.
The following command will set the same defaults as above, for the same printer:
lpoptions -E -p M401dn -o PageSize=A4 -o Duplex=DuplexNoTumble -o MediaType=Plain
The trick is, it doesn’t. What it does set are defaults for the Berkeley and System V commands (like lp
and lpr
) that you can use directly on your printer server, which is likely never. The behavior is documented in the man
.
What you probably want is to change the printer default for the users: in that case, use lpadmin
.
I want to print from Windows
Do yourself a favor and use Linux.
But if you really need to, you have two options.
– Use SAMBA so you can share your printers by using Named Pipes over SMB. Wouldn’t recommend.
– Add the IPP support to Windows and submit your print jobs to cupsd
via IPP. That’s what I did.
CUPS is not the only one moving away from Printer Drivers, also Microsoft is doing that and they have published a timeline for that, after which they will not accept new printer drivers to be published to Windows Update by manufacturers.
But you should really do yourself a favor and move to Linux.
Update: Printing with IPP Everywhere
Shortly after I first wrote this post my printer decided to wear out its pressure roller; while I’m waiting for the spare part I borrowed a Brother MFC-L2960DW which is a shiny new printer which supports IPP Everywhere.
It’s that easy to add it to the CUPS (since it uses TLS don’t forget to load a trusted certificate on the box):
lpadmin -p Brother -E -v ipps://itmil01pm001.corp.cavanasystems.com:443/ipp/print -m everywhere -o cupsIPPSupplies=true
CUPS will query the printer capabilities via IPP and create the printer PPD correctly. That’s it.
If you want to interrogate the printer the way CUPS does, feel free to:
ipptool -tv ipps://itmil01pm001.corp.cavanasystems.com get-printer-attributes.test
You can play around with the printer options on the printer menu or web server and see how the settings are reported back to CUPS.
When installing the new printer on my Fedora clients I noticed that the builtin KDE printer manager tries to add it as it were a local printer and not a remote printer. Just use lpadmin
instead:
lpadmin -p Brother -E -v ipps://cups-printing.corp.cavanasystems.com:631/printers/Brother -m everywhere
