This commit is contained in:
1 parent
7f26ca4f2f
commit
db23feada5
8 files changed
+561
-15
No files matched your search
@@ -42,7 +42,7 @@ becomes:
|
||||
| --- | --- |
|
||||
| `Containerfile` | Image definition (Debian base, CUPS + cups-filters + Avahi, BR-Script3 PPD) |
|
||||
| `cupsd.conf` | Container CUPS configuration (listen on all interfaces, share printers) |
|
||||
| `entrypoint.sh` | Starts D-Bus, Avahi and CUPS, then registers the printer queue |
|
||||
| `entrypoint.sh` | Starts D-Bus, Avahi and CUPS, generates the `_ipps` certificate, then registers the printer queue |
|
||||
| `assets/Brother HL-4150CDN/ppd/` | Official BR-Script3 PPD used for the queue |
|
||||
| `assets/Brother HL-4150CDN/Windows/` | Vendor Windows driver the PPD was extracted from |
|
||||
|
||||
@@ -85,6 +85,8 @@ podman run -d --name printserver \
|
||||
| `PRINTER_NAME` | `HL4150CDN` | CUPS queue name. Also used as the name advertised via AirPrint/DNS-SD. |
|
||||
| `PRINTER_DESCRIPTION` | *(empty)* | CUPS printer description (`lpadmin -D`), shown in the CUPS web UI. |
|
||||
| `PPD_FILE` | `/usr/share/cups/model/BR4150_2.PPD` | PPD used for the queue. |
|
||||
| `CERT_EXTRA_NAMES` | *(empty)* | Comma-separated extra DNS names and/or IP addresses to put into the generated `_ipps` certificate. |
|
||||
| `CERT_DAYS` | `3650` | Validity of the generated certificate, in days. |
|
||||
|
||||
No queue is created when neither `PRINTER_IP` nor `PRINTER_URI` is set.
|
||||
|
||||
@@ -121,6 +123,51 @@ set `PRINTER_DESCRIPTION` (this does not change the advertised name):
|
||||
-e PRINTER_NAME=HL4150CDN -e PRINTER_DESCRIPTION="Brother HL-4150CDN (Office)"
|
||||
```
|
||||
|
||||
### TLS certificate for `_ipps`
|
||||
|
||||
CUPS advertises the queue twice over mDNS: `_ipp._tcp` (plain) and `_ipps._tcp`
|
||||
(TLS). macOS and iOS prefer the secure one, and *validate the certificate
|
||||
against the name they connected to*. The name clients see is Avahi's
|
||||
`<host>.local`, which is not necessarily the container's host name — so the
|
||||
entrypoint installs its own self-signed certificate instead of leaving it to
|
||||
CUPS. Its SANs cover the container host name, `<host name>.local`, Avahi's
|
||||
FQDN, `localhost`, `127.0.0.1` and everything in `CERT_EXTRA_NAMES`:
|
||||
|
||||
```sh
|
||||
-e CERT_EXTRA_NAMES=192.168.100.20,print.example.org
|
||||
```
|
||||
|
||||
The certificate lives in `/etc/cups/ssl` (so that directory must be writable:
|
||||
use a named volume, see the bind-mount caveat under *Notes and limitations*)
|
||||
and is only regenerated when one of the names it must cover is missing, so a
|
||||
restart normally logs `TLS certificate is up to date`. Inspect what the server
|
||||
actually presents:
|
||||
|
||||
```sh
|
||||
podman cp printserver:/etc/cups/ssl/server.crt .
|
||||
openssl x509 -in server.crt -noout -subject -ext subjectAltName
|
||||
echo | openssl s_client -connect localhost:631 -servername "$(hostname).local" \
|
||||
| openssl x509 -noout -subject -ext subjectAltName
|
||||
```
|
||||
|
||||
Because the certificate is self-signed, a fully validating client (macOS/iOS
|
||||
AirPrint, `curl` without `-k`) rejects it until you trust it. CUPS' own tools
|
||||
(`lpadmin`, `ipptool`) are lenient, so plain printing works without this step:
|
||||
|
||||
- **macOS** (needs your password):
|
||||
|
||||
```sh
|
||||
sudo security add-trusted-cert -d -r trustRoot \
|
||||
-k /Library/Keychains/System.keychain ./server.crt
|
||||
```
|
||||
|
||||
- **iOS/iPadOS**: AirDrop or mail `server.crt` to the device, install the
|
||||
profile, then enable full trust under *Settings → General → About →
|
||||
Certificate Trust Settings*.
|
||||
|
||||
Alternatively, keep using plain IPP (port 631 without TLS) — printing and
|
||||
duplex/colour options work there too.
|
||||
|
||||
## Printing options
|
||||
|
||||
The BR-Script3 PPD exposes the HL-4150CDN's hardware options. Common ones:
|
||||
@@ -147,7 +194,7 @@ podman exec printserver lp -d HL4150CDN \
|
||||
|
||||
| Platform | Path | Notes |
|
||||
| --- | --- | --- |
|
||||
| macOS | AirPrint / IPP Everywhere | Discovered via mDNS; no driver needed |
|
||||
| macOS | AirPrint / IPP Everywhere | Discovered via mDNS; no driver needed. If *Use:* shows *Generic PostScript Printer*, see [Troubleshooting](#macos-adds-the-printer-as-a-generic-postscript-printer) |
|
||||
| iOS / iPadOS | AirPrint | Discovered via mDNS; no driver needed |
|
||||
| Linux | IPP / IPP Everywhere | Native or with the shared PPD |
|
||||
| Windows | IPP or raw 9100 | Install Brother's **BR-Script3** Windows driver, pointed at the printer or the shared queue |
|
||||
@@ -251,15 +298,57 @@ the firewall.
|
||||
|
||||
If plain IPP works but the *secure* connection fails, this is the `_ipps`
|
||||
service: macOS prefers `_ipps._tcp`, which CUPS advertises unconditionally
|
||||
(also when no certificate exists). CUPS creates its TLS certificate lazily on
|
||||
the first TLS connection, in `/etc/cups/ssl` — so that directory must be
|
||||
writable. If it is not, CUPS logs
|
||||
`Unable to encrypt connection: Unable to create server credentials` and the
|
||||
secure connection fails while plain IPP keeps working. Use a **writable (named)
|
||||
volume** for `/etc/cups`; see the bind-mount caveat under *Notes and
|
||||
limitations*. After changing anything, remove the printer in macOS and add it
|
||||
(also when no certificate exists). The certificate lives in `/etc/cups/ssl`, so
|
||||
that directory must be writable — use a **writable (named) volume**; see the
|
||||
bind-mount caveat under *Notes and limitations*. If it is not writable, CUPS
|
||||
logs `Unable to encrypt connection: Unable to create server credentials` and the
|
||||
secure connection fails while plain IPP keeps working.
|
||||
|
||||
The other cause is the certificate itself: clients only accept it when the name
|
||||
they connected to is in its SANs *and* they trust it (see *TLS certificate for
|
||||
`_ipps`*). Typical symptoms: `curl https://<host>.local:631/` ends with
|
||||
`(60) SSL certificate problem`, or `ipptool -tv ipps://…` succeeds while
|
||||
macOS/iOS refuse. Add the missing name via `CERT_EXTRA_NAMES` or trust the
|
||||
certificate. After changing anything, remove the printer in macOS and add it
|
||||
again — macOS caches the failed attempt.
|
||||
|
||||
### macOS adds the printer as a Generic PostScript printer
|
||||
|
||||
Symptom: the queue prints, but *Use:* shows **Generic PostScript Printer** and
|
||||
the print dialog offers no duplex, no colour and no tray 2 — while iOS, which
|
||||
queries the printer live, offers all of them. On the Mac,
|
||||
`lpoptions -p <queue> -l` lists only `APOptionalDuplexer` plus
|
||||
`Duplex`/`PageSize`/`ManualFeed`/`InputSlot`, and
|
||||
`/etc/cups/ppd/<queue>.ppd` contains `*PCFileName: "Generic.ppd"`.
|
||||
|
||||
macOS only takes its driverless AirPrint path when it accepts the printer's
|
||||
secure `_ipps` service; if that fails it silently falls back to its bundled
|
||||
generic PostScript driver. Duplex then stays hidden, because the generic PPD
|
||||
gates it behind `APOptionalDuplexer False`. The usual cause is the certificate
|
||||
(see *TLS certificate for `_ipps`*), so check that first:
|
||||
|
||||
```sh
|
||||
podman exec printserver avahi-browse -rt _ipps._tcp # what is advertised
|
||||
podman cp printserver:/etc/cups/ssl/server.crt . &&
|
||||
openssl x509 -in server.crt -noout -subject -ext subjectAltName
|
||||
```
|
||||
|
||||
A verified way around it is to add the queue from the command line, driverless
|
||||
over the same secure service (`ipptool -tv ipp://<host>:631/printers/<queue>`
|
||||
prints the UUID; drop the `urn:uuid:` prefix):
|
||||
|
||||
```sh
|
||||
sudo lpadmin -x <queue>
|
||||
sudo lpadmin -p <queue> -E -m everywhere \
|
||||
-v "dnssd://<queue>%20%40%20<host>._ipps._tcp.local./?uuid=<printer-uuid>"
|
||||
lpoptions -p <queue> -l # Duplex, ColorModel and tray 2 show up now
|
||||
```
|
||||
|
||||
In the GUI, remove the printer and add it again, then pick **AirPrint** (not
|
||||
*Generic PostScript Printer*) under *Use*. If only the generic entry is offered,
|
||||
the secure connection is still being rejected — fix the certificate, or add the
|
||||
queue from the command line as above.
|
||||
|
||||
## CUPS 3 and the future of PPDs
|
||||
|
||||
Adding the queue with a PPD makes `lpadmin` print:
|
||||
|
||||
Reference in new issue
Block a user