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,29 @@
# Tasks
## 1. Image dependency
- [x] 1.1 Install `openssl` explicitly in the `Containerfile` and verify it is present in the built image (`podman run --rm --entrypoint sh <image> -c 'command -v openssl'` prints a path)
## 2. Certificate generation, installation and documentation
- [x] 2.1 Build the SAN list from the container host name, its `.local` form, the Avahi-advertised FQDN (D-Bus `GetHostNameFqdn`), `localhost`, `localhost.localdomain`, `host.containers.internal`, `127.0.0.1` and `CERT_EXTRA_NAMES`, sorted and deduplicated; verify the entrypoint log line `certificate SANs: …` lists all of them for a test container started with `CERT_EXTRA_NAMES=192.168.100.20`
- [x] 2.2 Generate the self-signed certificate and key with `openssl` (CN = host name, `basicConstraints=critical,CA:TRUE`, validity from `CERT_DAYS`) when the certificate directory has none; verify `/etc/cups/ssl/server.crt` exists in the container and `openssl x509 -noout -ext subjectAltName` lists the expected names
- [x] 2.3 Make CUPS serve that certificate: add `ServerCertificate`/`ServerKey` to `cupsd.conf` when absent (repairing a `cupsctl`-rewritten file) and write copies to `<host name>.crt`/`.key` and `<Avahi FQDN>.crt`/`.key`; verify from outside the container that `openssl s_client -connect host:port -servername <advertised name>` shows the advertised name in the presented certificate's SANs
- [x] 2.4 Reuse the certificate whenever every required name is already covered, reissue only when one is missing, never reorder-triggered; verify a restart logs `TLS certificate is up to date`, and that adding a `CERT_EXTRA_NAMES` entry makes the next start generate a new certificate
- [x] 2.5 Warn instead of exiting when the certificate cannot be written; verify with a read-only `/etc/cups` mount that the entrypoint logs the warning and CUPS still serves plain IPP
- [x] 2.6 Document `CERT_EXTRA_NAMES`/`CERT_DAYS`, the certificate, how to inspect it and how to trust it on macOS/iOS in `README.md`; verify the environment-variable table and the certificate section match `entrypoint.sh`
## 3. Startup robustness
- [x] 3.1 Start D-Bus based on whether `dbus-daemon` is running and remove its stale socket/PID file first; verify that after `podman restart` the container is `running` and `pgrep -x dbus-daemon` inside it succeeds
- [x] 3.2 Apply the same stale-state cleanup to Avahi and downgrade a start failure to a warning; verify that after a restart `avahi-browse -rt _ipp._tcp` inside the container lists the queue and the container stays up even when avahi cannot start
## 4. Integration verification
- [x] 4.1 On a fresh named volume, start the image and verify the client-visible result: the served certificate covers the Avahi-advertised name, the queue is advertised over mDNS after a restart, and the restart logs `TLS certificate is up to date`
- [x] 4.2 Verify an existing deployment volume is repaired on first start: with a volume whose `cupsd.conf` has no `ServerCertificate` directive and whose `<host name>.crt` is a stale foreign certificate, start the container and verify the directive is added and the stale certificate is replaced
## Workflow follow-up
- Archive this change (`/opsx-archive`) so the delta merges into `openspec/specs/printserver/cups/spec.md`.
- Commit the implementation together with the archived change using `jj`.