Files
obsidian-vault/personal/tech/mac-print-shared-services.md

17 KiB
Raw Permalink Blame History

type, topic, tags, created, updated
type topic tags created updated
tech print
print
printer
samsung
cups
macos
2026-08-26T00:00:00.000Z 2026-09-02T00:00:00.000Z

Печать и общие сервисы (Mac + сеть)

Проверка службы печати 2026-08-26: «не видит принтер с телефона».

Состояние на момент проверки

На Mac (admin, macOS 26.6.1, arm64) в системе зарегистрированы два принтера:

Принтер Способ подключения Статус
Samsung CLX-216x Сетевой ipp://192.168.2.197/printers/Samsung_CLX-216x_Series, драйвер Generic PostScript не pингуется в текущей сети
Samsung M2020 Series (SEC84251974A6B3) AirPrint dnssd://…_ipp._tcp.local., дефолтный, PPD Samsung M2020 Series-AirPrint не отвечает по сети

Системный дефолт: Samsung_M2020_Series__SEC84251974A6B3_ (idle, enabled 2026-07-29).

Ключевые находки

  • CUPS слушает только локально: в /etc/cups/cupsd.confListen localhost:631 + Listen /private/var/run/cupsd. Наружу (по сети, для AirPrint) служба печати НЕ отдаётся.
  • Шеринг печати выключен (SharePrinters в cupsd.conf закомментирован/неактивен; в system_profiler оба принтера Shared: No, System Printer Sharing: No).
  • Порт 631 наружу закрыт: nc -z 192.168.2.197 631 → closed.
  • Сеть Мака — 192.168.6.x (адрес 192.168.6.173, шлюз 192.168.6.1). Принтер прописан в подсети 192.168.2.x.

⚠️ Важное наблюдение (пересечение с TrueNAS)

Адрес 192.168.2.197 — это TrueNAS (truenas_admin, SSH через mallexxx.duckdns.org), НЕ сам принтер. Samsung CLX-216x физически подключён к TrueNAS (USB) и печатается через docker-контейнер cups-splix (драйвер splix). Запись ipp://192.168.2.197/printers/Samsung_CLX-216x_Series в системе Мака — результат обнаружения расшаренной печати TrueNAS на этом адресе.

НаСТОЯЩИЙ ДИАГНОЗ (2026-08-26, подтверждено SSH на TrueNAS)

Корень проблемы: cups-splix контейнер НЕ запущен на TrueNAS.

  • На TrueNAS нет ни одной работающей службы печати: lpstat/cupsd в системе не установлены, порт 631 закрыт (и локально, и снаружи).
  • Ни одного docker-контейнера по печати в docker ps нет (cup/sprint/ipp — пусто). Официальный список контейнеров (docker ps -a): immich(redis/server/postgres), modbus-bridge, mbusd, zigbee2mqtt, webdav, vless-proxy, hermes-taiga, portainer(-mcp), homeassistant, caddy, watchtower, transmission, syncthing, ser2net, rclone, nodered, mosquitto, library, inpxer, inpx-web, gitea, filebrowser. cups-splix отсутствует.
  • Образ cups-splix не собран (docker images | grep cups|splix → пусто).

Конфиг cups-splix (цел, на месте)

Папка /mnt/RED_2TB/docker/cups/: Dockerfile, docker-compose.yml, docker build.txt, data/, cache/, spool/, uld/.

docker-compose.yml:

services:
  cups-splix:
    image: cups-splix
    container_name: cups-splix
    command: ["/usr/sbin/cupsd", "-f"]
    network_mode: host
    privileged: true
    volumes:
      - /dev/bus/usb:/dev/bus/usb
      - /mnt/RED_2TB/docker/cups/data:/etc/cups
      - /mnt/RED_2TB/docker/cups/cache:/var/cache/cups
      - /mnt/RED_2TB/docker/cups/spool:/var/spool/cups
    restart: unless-stopped

Dockerfile (debian:12-slim): ставит cups-daemon cups-client cups-common printer-driver-splix avahi-utils dbus usbutils nano, пользователь cupsadmin:admin (в группе lpadmin), EXPOSE 631, CMD cupsd -f.

Как поднять (из доки, раздел «Сборка»):

cd /mnt/RED_2TB/docker/cups/
docker build -t cups-splix .
docker compose up -d   # или docker run из build.txt
# проверить: порт 631 открылся, принтер подцепился

Почему выпал

.ix-apps вызов docker data-root при пересоздании пула НЕ переносился → образы (=кеш) потеряны, перекачиваются заново. cups-splix — локальная сборка, она не «перекачается», нужно пересобрать. Конфиги целы.

РЕЗОЛЮЦИЯ (2026-08-26, выполнено)

cups-splix поднят, печать восстановлена. Шаги, фактически выполненные на TrueNAS:

cd /mnt/RED_2TB/docker/cups
docker build -t cups-splix .          # образ собран успешно (~225s), splix установлен
docker compose up -d                  # контейнер запущен
docker exec cups-splix lpstat -p -d   # printer Samsung_CLX-216x_Series ... idle, enabled
docker exec cups-splix lpstat -a      # ... accepting requests
nc -z 192.168.2.197 631               # 631 OPEN снаружи
  • Принтер подключён по USB к TrueNAS: usb://Samsung/CLX-216x%20Series?serial=9566BAGQ213134Z.&interface=1 (Bus 002 Device 008, 04e8:3425 Samsung CLX-216x).
  • CUPS-конфиг сохранился в /mnt/RED_2TB/docker/cups/data (это /etc/cups) → принтер прописан и подцепился после рестарта сам.
  • Образ собрался без ошибок → раньше его просто не запускали собирать (не поломка Dockerfile), а потеряли при восстановлении стека вместе с .ix-apps.
  • Порт 631 открыт наружу → печать доступна по сети на 192.168.2.197:631.

Условие для телефона: телефон должен быть в сети 192.168.2.x (той же, что и TrueNAS), чтобы увидеть принтер. Если телефон в другой подсети (напр. 192.168.6.x) — это сетевой вопрос, не печатный.

Полный рецепт на будущее продублирован в truenas-infrastructure.md → раздел «Печать / cups-splix».

Печать PDF извне сети TrueNAS (когда клиент НЕ в подсети, mallexxx.duckdns.org:631 закрыт)

Когда принтер физически в TrueNAS, а клиент НЕ в подсети 192.168.2.x → прямой IPP до :631 закрыт. Печатать через SSH mallexxx.duckdns.org в контейнер cups-splix (проверено 2026-09-02):

# 1. Залить PDF на TrueNAS
scp -i ~/.ssh/id_rsa file.pdf truenas_admin@mallexxx.duckdns.org:/tmp/evrika_print.pdf
# 2. Скопировать внутрь контейнера
ssh -i ~/.ssh/id_rsa truenas_admin@mallexxx.duckdns.org \
  'docker cp /tmp/evrika_print.pdf cups-splix:/tmp/evrika_print.pdf'
# 3. Отправить в очередь (CUPS сам конвертит PDF→vnd.cups-postscript→pstoqpdl; gs+pdftops в контейнере есть)
ssh -i ~/.ssh/id_rsa truenas_admin@mallexxx.duckdns.org \
  'docker exec cups-splix lp -d Samsung_CLX-216x_Series -o media=A4 /tmp/evrika_print.pdf'

Проверка успеха: lpstat -W completed | grep "<reqid>" (искомый job появляется строкой Samsung_CLX-216x_Series-<N> <user> <bytes> ... <дата>), очередь пуста (lpstat -o), принтер idle … Rendering completed. access_log контейнера: Create-Job successful-ok + Send-Document successful-ok.

Важно: lp -d <printer> file.pdf сам создаёт job (Create-Job) — НЕ комбинировать с отдельным print-job-id, иначе client-error-not-found. PPD CLX-216x принимает application/vnd.cups-postscript (*cupsFilter: 0 pstoqpdl), поэтому чистый PDF конвертится автоматически. Job в lpstat -W completed показывает владельцем root (выполняется через docker по SSH) — это нормально.

Полный шаги: залить → docker cpdocker exec cups-splix lp → проверить completed → убрать временные файлы (/tmp/... на хосте и внутри контейнера).

⚠️ ТОПОЛОГИЯ ИЗМЕНЕНА (2026-08-31) — TrueNAS больше НЕ в локальной сети

TrueNAS ушла из локальной сети и доступна только через публичный DNS mallexxx.duckdns.org (внешка 90.189.160.148). Локальный 192.168.2.197 физически недостижим (пинг 100% потеря) — TrueNAS не в 192.168.2.x и не в сети телефона.

Подтверждено SSH на TrueNAS (2026-08-31):

  • cups-splix Up (4 days), принтер Samsung_CLX-216x_Series idle / enabled / accepting requests.
  • Принтер подключён по USB: usb://Samsung/CLX-216x%20Series?serial=9566BAGQ213134Z.&interface=1.
  • CUPS слушает 0.0.0.0:631 (все интерфейсы, network_mode: host).
  • CUPS config: Port 631, WebInterface Yes, ServerAlias * (раздел cupsd.conf).
  • Снаружи mallexxx.duckdns.org:631 — CLOSED (наружу не проброшен).

Реальная картина печати:

  • Samsung Mobile Print (app) — печатает. У приложения адрес вписан вручную/закэширован (не обязательно 192.168.2.197).
  • Штатная Android print service — добавлял вручную ipp://192.168.2.197:631/printers/Samsung_CLX-216x_Series«недоступен». Ожидаемо: TrueNAS ушла из локальной сети, а адрес 192.168.2.197 из телефона недостижим.

Вывод: «недоступен» в штатной службе — НЕ баг настройки и НЕ проблема порта. Это прямое следствие того, что CUPS-хост (TrueNAS) физически вне сети телефона: локального пути нет, а публичный mallexxx.duckdns.org:631 закрыт. Android-штатная служба не умеет удалённый IPP через интернет без открытого наружу порта.

ОТКРЫТЫЙ ВОПРОС (не разобран, нет доступа к настройкам приложения): по какому именно адресу Samsung Mobile Print реально шлёт печать, раз 631 снаружи закрыт. Гипотезы: (1) приложение кэширует соединение с времён, когда TrueNAS была локально; (2) используется другой публичный путь (реверс-прокси Caddy на ином порту/HTTPS), не записанный в доках. Для полного разбора нужен адрес/хост из настроек принтера внутри Samsung Mobile Print. Отмечено: лог CUPS access_log показывает, что практически вся печать шла с IP 192.168.2.141 (26-30 авг, POST /printers/... Print-Job → 200 successful-ok) — т.е. Samsung Mobile Print ходил по локальному IP, когда TrueNAS ещё была в сети. Похоже, приложение реально кэшировало локальное соединение.

НАСТОЯЩИЙ МЕХАНИЗМ «недоступен» в Android print service (2026-08-31, подтверждено ipptool)

Дополнительная проверка внутри контейнера (ipptool -tv → CUPS) дала ключевой факт:

  • printer-dns-sd-name = no-value
  • В контейнере cups-splix НЕ запущен avahi-daemon (процессы: только cupsd; ps aux | grep avahi — пусто). Пакеты dbus + avahi-utils в образе есть, но avahi-daemon не установлен и не стартует, а CMD — только cupsd -f.

Механика: Samsung Mobile Print — вендорское приложение, ходит на CUPS напрямую по IPP (POST Print-Job по IP) → работает даже без mDNS. Android штатная служба печати (Mopria/Default) даже при ручном добавлении по IP затем делает mDNS/AirPrint-проверку принтера (_ipp._tcp / _ipps._tcp.local), чтобы получить printer-uuid и capabilities. Если mDNS-анонса нет (printer-dns-sd-name = no-value, avahi не запущен) — Android помечает принтер «недоступен», даже если IPP по-IP физически отвечает. Полный ответ CUPS на Get-Printer-Attributes — successful-ok [PASS], принтер idle/accepting/shared — подтверждает: CUPS здоров, всё дело в отсутствии mDNS-анонса.

РЕЗУЛЬТАТ (2026-08-31, выполнен полностью): mDNS поднят через avahi-daemon

Место: папка /mnt/RED_2TB/docker/cups/.

Выполнено и проверено (все шаги):

  • Бэкап конфига: /mnt/RED_2TB/docker/cups/backup_20260831-003619.tar.gz (создан внутри контейнера tardocker cp; md5 0e303a6a57ae767d1e14cd72c8039fe4). Внутри: /etc/cups, /var/spool/cups, /var/cache/cups. Дубль в /tmp/cups_backup_<ts>.tar.gz на хосте.
  • Новый Dockerfile (в cups/, заменил старый): в apt добавлен avahi-daemon + procps; добавлен COPY entrypoint.sh /entrypoint.sh; ENTRYPOINT ["/entrypoint.sh"] вместо CMD ["cupsd","-f"].
  • entrypoint.sh (в cups/): стартует dbus-daemon --system --fork, затем avahi-daemon --no-drop-root --syslog в фоне, затем exec cupsd -f.
  • cupsd.conf: Browsing OffBrowsing On + BrowseLocalProtocols dnssd (бэкап cupsd.conf.pre-avahi). Валидность: /usr/sbin/cupsd -t → OK.
  • Образ: собрал cups-splix-new, затем пометил старый образ как cups-splix-old (откат), а новый — как cups-splix.
  • Контейнер пересоздан: docker stop cups-splix && docker rm cups-splix && docker compose up -d.

Проверка mDNS (всё сошлось):

  • ps aux: запущены cupsd (PID1), dbus-daemon --system, avahi-daemon: running [truenas.local].
  • ipptool Get-Printer-Attributes: printer-dns-sd-name больше не no-value → теперь анонс зарегистрирован.
  • avahi-browse -rt -p _ipp._tcp: на физическом интерфейсе ;enp3s0;IPv4; по адресу 192.168.2.197;631 с TXT mopria-certified=1.3, pdl=application/pdf,..., rp=printers/Samsung_CLX-216x_Series, UUID=68e3b8c6-....
  • CUPS по-прежнему слушает 0.0.0.0:631, принтер idle/enabled/accepting.

Pitfall (важно): НЕ использовать docker restart cups-splix после правки конфига — он убивает avahi-daemon (становится <defunct>), dbus тоже пропадает. Подъём ТОЛЬКО полным пересозданием: docker stop cups-splix && docker rm cups-splix && docker compose up -d, чтобы entrypoint.sh выполнился с нуля.

Pitfall (compose): docker-compose.yml в cups/ — -rw------- root:root (600), truenas_admin перезаписать не может (Permission denied) → compose НЕ менял. Это ок: ENTRYPOINT переопределяет command, лишний cupsd не стартует (скрипт сам делает exec cupsd -f, аргументы $@ игнорирует). Если потребуется убрать command из compose — править через root/UI.

Pitfall (бэкап): data/ cache/ spool/ под TrueNAS — drwx------ root:lp (0700), truenas_admin их напрямую не читает → бэкап делать ТОЛЬКО через контейнер (docker exec ... tardocker cp), либо через /admin (root).