Advertise a valid IPPS certificate for AirPrint
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
juergen committed 2026-10-18 22:35:48 +02:00
1 parent 7f26ca4f2f
commit db23feada5
8 files changed
+561 -15

No files matched your search

@@ -0,0 +1,67 @@
# Proposal
## Why
macOS adds the shared queue as its bundled *Generic PostScript Printer* instead
of driverlessly over AirPrint, so the print dialog offers no duplex, no colour
and no tray selection — while iOS, which queries the printer live, does offer
them. The cause is the secure `_ipps` service: CUPS serves a certificate issued
for the container's host name, which is not the `<host>.local` name Avahi
advertises and that clients validate. Anything that checks the name (macOS/iOS
AirPrint, `curl`) rejects the secure add and macOS silently falls back to the
generic driver; CUPS' own tools are lenient, so the server looks healthy.
Testing the fix surfaced a second, independent defect: restarting the container
(`podman restart`, or a systemd `Restart=` of the quadlet) leaves stale D-Bus
and Avahi PID files and sockets in `/run`. Both daemons then refuse to start
and `set -e` stops the entrypoint, so the print server stays dead until the
container is recreated.
## What Changes
- Generate and install the `_ipps` certificate in the entrypoint: self-signed,
with SANs covering the container host name, `<host name>.local`, the name
Avahi advertises, `localhost`, `localhost.localdomain`,
`host.containers.internal` and `127.0.0.1`, plus whatever `CERT_EXTRA_NAMES`
lists; `CERT_DAYS` sets its validity.
- Install the certificate where CUPS actually looks for it: as
`ServerCertificate`/`ServerKey` (added to `cupsd.conf` when missing, also
repairing a file rewritten by `cupsctl`) and as `<name>.crt`/`.key` for the
host name and the Avahi FQDN, because CUPS 2.4 keeps serving its own
`<host name>.crt` even when `ServerCertificate` is set.
- Reuse an existing certificate when it already covers every required name, so
a restart does not reissue it and clients that trusted it do not have to
trust it again.
- Add `openssl` explicitly to the image; it was only a transitive dependency of
`ca-certificates`.
- Remove stale D-Bus and Avahi runtime state (socket, PID file) before starting
those daemons, and warn instead of exiting when Avahi cannot start.
- Document the certificate, `CERT_EXTRA_NAMES`/`CERT_DAYS`, the client trust
step and the macOS generic-driver fallback in the README. Documentation only,
no spec behaviour.
Non-goals: shipping a publicly trusted certificate or a private CA, changing the
`_ipp` (plain) service, and changing how jobs are converted or sent to the
printer.
## Capabilities
### New Capabilities
<!-- None: the certificate and restart behaviour extend the existing capability. -->
### Modified Capabilities
- `printserver/cups`: the image dependency requirement now includes the TLS
tooling, and the capability gains requirements for a secure AirPrint
certificate that matches the advertised name and for starting cleanly when
stale runtime state is left behind by a previous run.
## Impact
- `entrypoint.sh`: certificate generation/installation, D-Bus and Avahi startup.
- `Containerfile`: explicit `openssl`.
- `README.md`: `CERT_EXTRA_NAMES`/`CERT_DAYS`, a certificate section, and the
macOS generic-driver fallback under Troubleshooting.
- Clients: macOS/iOS can validate the secure service; plain IPP and existing
client-side Windows driver setups are unaffected.
- Existing deployments: an existing `/etc/cups` volume is repaired on the next
start (the stale certificate is replaced); no volume reset is needed.