Synopsis #
Use the BSD printing system (lpd) or CUPS (Common UNIX Printing System) to print on OpenBSD. The procedures below cover local and network printers, drivers, filters, PDF output, and print servers.
Overview of Printing in OpenBSD #
The base system includes lpd(8), a lightweight line printer daemon that handles print spooling and basic filtering. More complex setups, such as those requiring drivers, graphical administration, or network browsing, are better handled using CUPS, which is available as a package.
Common printer types supported:
- USB printers connected via
/dev/ulpt0 - Network printers supporting IPP, JetDirect (port 9100), or LPD
- PostScript printers that require no additional drivers
- Host-based printers (e.g., some HP, Samsung) via driver packages
Filters such as a2ps(1), enscript(1), and ghostscript are commonly used to prepare print jobs for printers that do not support plain text or PostScript natively.
Configuring Printing with lpd #
Configure printers manually in /etc/printcap. Use a filter when the printer needs format conversion, such as plain text to PostScript. Choose CUPS below for graphical administration or additional printer drivers.
Enabling lpd #
Enable the base printing system using rcctl:
doas rcctl enable lpd
doas rcctl start lpd
Ensure the printing device (such as /dev/ulpt0) is writable by the daemon user:
doas chown daemon /dev/ulpt0
doas chmod 600 /dev/ulpt0
Configuring /etc/printcap #
The printcap(5) file describes available printers.
Example for a local USB printer:
lp|Local USB Printer:\
:lp=/dev/ulpt0:\
:sd=/var/spool/output/lpd:\
:lf=/var/log/lpd-errs:
Create and prepare the spool directory:
doas mkdir -p /var/spool/output/lpd
doas chown daemon:daemon /var/spool/output/lpd
To print to a remote LPD server:
remotehp:\
:rm=192.0.2.10:\
:rp=raw:\
:sd=/var/spool/output/remotehp:\
:lf=/var/log/lpd-errs:
Adding Print Filters #
For a PostScript-capable printer that does not accept plain text, use an if= filter to convert text to PostScript. A printer requiring a different raster language needs its own driver.
Install enscript and ghostscript:
doas pkg_add enscript ghostscript
Create a filter script:
doas vi /usr/local/libexec/psfilter
Example content:
#!/bin/sh
exec /usr/local/bin/enscript -o -
This text-only filter sends PostScript to the printer. Do not use it as a universal PDF or raster-printer filter; use CUPS with the appropriate driver for those formats. Errors remain visible to the spooler.
Make it executable:
doas chmod +x /usr/local/libexec/psfilter
Update /etc/printcap:
lp:\
:lp=/dev/ulpt0:\
:if=/usr/local/libexec/psfilter:\
:sd=/var/spool/output/lpd:\
:lf=/var/log/lpd-errs:
Printing from the Command Line #
Send a job:
lpr file.txt
Check the queue:
lpq
Remove jobs:
lprm -
Printing with CUPS #
CUPS provides a web interface, automatic printer discovery, and support for many printer protocols and drivers. Install it from packages for USB inkjet printers, printers that need PPD files, or network setups that need these features.
Installing and Enabling CUPS #
Install CUPS and supporting drivers:
doas pkg_add cups gutenprint foomatic-db splix hplip
Enable and start the daemon:
doas rcctl enable cupsd
doas rcctl start cupsd
Accessing the Web Interface #
The CUPS web interface is accessible at:
http://localhost:631
The packaged CUPS configuration uses the wheel system group for browser administration. Authenticate with an authorized account; a doas command rule does not grant access to the CUPS web interface.
Printers can be added via the web interface or with lpadmin. Select a queue under Printers to view its status and jobs.

For USB printers, follow the installed CUPS README under /usr/local/share/doc/pkg-readmes/. The _cups account needs access to the matching /dev/ugenN.* and /dev/usbN devices; the ulpt driver may need to be disabled for libusb access. Identify the actual device before changing permissions. Base /usr/bin/lpr, lpq, and lprm target lpd; use the /usr/local/bin/ CUPS variants for CUPS queues.
Driver and Backend Support #
Check backends:
lpinfo -v
List available models and drivers:
lpinfo -m
CUPS backends support protocols such as:
socket://— JetDirectipp://orhttp://— IPP printersusb://— for local printers
Printing with CUPS #
To print:
lp -d PRINTER file.pdf
Set the default printer:
lpoptions -d PRINTER
View jobs:
lpstat -o
Cancel a job:
cancel JOBID
Setting Up an OpenBSD Print Server #
lpd-Based Print Server #
Enable lpd and configure /etc/printcap with exported printers. Add trusted client hosts to /etc/hosts.lpd:
192.0.2.15
client.example.org
Configure a local /etc/printcap entry named remoteprinter with rm=printserver.example.net and rp=printer, plus a local spool directory, then use:
lpr -Premoteprinter file.txt
CUPS-Based Print Server #
Edit /etc/cups/cupsd.conf:
Listen *:631
Browsing On
BrowseLocalProtocols all
<Location />
Order allow,deny
Allow all
</Location>
Restart the daemon:
doas rcctl restart cupsd
On client systems, configure:
/etc/cups/client.conf
with:
ServerName printserver.example.net
CUPS clients use /usr/local/bin/lp or /usr/local/bin/lpr; base lpd clients are not interchangeable with them.
Printing to PDF #
From Graphical Applications #
Most applications with GTK, Qt, or X11 print dialogs can print to a file. Select “Print to File” or “Print to PDF” and choose a destination.
Using Command-Line Tools #
Convert text to PDF using enscript and ghostscript:
enscript file.txt -p - | ps2pdf - output.pdf
Or use PostScript directly:
ps2pdf input.ps output.pdf
Virtual PDF Printer with CUPS #
Install the virtual backend:
doas pkg_add cups-pdf
Add a new printer called “PDF” in the CUPS web interface. The output will be written to:
${HOME}
The output directory can be changed in /etc/cups/cups-pdf.conf.
Remote Printing #
To a Remote lpd Server #
Use /etc/printcap:
remote:\
:rm=printserver.example.net:\
:rp=lp:\
:sd=/var/spool/output/remote:\
:lf=/var/log/lpd-errs:
To a Remote CUPS Server #
Create a configuration file:
/etc/cups/client.conf
With contents:
ServerName cups.example.net
Alternatively, set the environment variable:
export CUPS_SERVER=cups.example.net
Printing to Windows Shared Printers #
Install samba:
doas pkg_add samba
Use a device URI like:
smb://WORKGROUP/username:password@host/sharename
CUPS can use smbspool as a backend for SMB printing. Ensure credentials are embedded if printing unattended.
Troubleshooting #
- For
lpd, check/var/log/lpd-errs - For CUPS, use:
tail -f /var/log/cups/error_log
- Ensure printer device permissions:
doas ls -l /dev/ulpt0
- Restart the service after changes:
doas rcctl restart lpd
doas rcctl restart cupsd
- For failed jobs, verify that the correct driver or filter is installed
- Check if spool directories exist and are writable by
daemon(forlpd) or the CUPS user