第 7 章:打印共享与发现
第 7 章:打印共享与发现
打印共享是企业环境中的核心需求。本章将详细介绍 CUPS 的打印机发现机制、共享配置以及跨网络打印方案。
7.1 打印机发现机制概览
7.1.1 发现协议对比
| 协议 | 全称 | 版本支持 | 说明 |
|---|---|---|---|
| DNS-SD | DNS Service Discovery | CUPS 1.2+ | 推荐,基于 mDNS/Bonjour |
| Browse | CUPS Browse Protocol | CUPS 1.0-1.5 | 已废弃,仅 CUPS 1.x |
| LDAP | Lightweight Directory Access Protocol | CUPS 1.2+ | 企业目录集成 |
| SLP | Service Location Protocol | CUPS 1.1+ | 较少使用 |
| cups-browsed | cups-browsed 服务 | CUPS 2.x+ | 自动发现远程打印机 |
7.1.2 发现协议演进
CUPS 1.0 (1999): Browse 协议 (UDP 广播)
│
CUPS 1.2 (2006): 添加 DNS-SD 支持
│
CUPS 1.6 (2012): Browse 协议被废弃,推荐 DNS-SD
│
CUPS 2.x (2015+): cups-browsed + DNS-SD
│
CUPS 3.x (2024+): 完全基于 DNS-SD/IPP Everywhere
7.2 DNS-SD (DNS Service Discovery)
7.2.1 DNS-SD 概述
DNS-SD 使用 mDNS(多播 DNS)在本地网络中发现服务:
┌─────────────────────────────────────────────────┐
│ mDNS 工作原理 │
│ │
│ 打印机发布服务: │
│ HP-LaserJet._ipp._tcp.local. → 192.168.1.100 │
│ │
│ 客户端查询服务: │
│ _ipp._tcp.local.? → 发现所有 IPP 打印机 │
│ │
│ 多播地址: 224.0.0.251 (IPv4) │
│ 端口: 5353 (UDP) │
└─────────────────────────────────────────────────┘
7.2.2 使用 avahi-daemon
# 安装 Avahi
sudo apt install -y avahi-daemon avahi-utils
# 启动 Avahi 服务
sudo systemctl start avahi-daemon
sudo systemctl enable avahi-daemon
# 查看 Avahi 状态
sudo systemctl status avahi-daemon
7.2.3 使用 avahi-browse 发现打印机
# 发现所有 IPP 服务
avahi-browse -t -r _ipp._tcp
# 输出示例:
# + eth0 IPv4 HP LaserJet Pro M404 @ server1 Internet Printer local
# = eth0 IPv4 HP LaserJet Pro M404 @ server1 Internet Printer local
# hostname = [HP-LaserJet.local]
# address = [192.168.1.100]
# port = [631]
# txt = ["rp=ipp/print" "ty=HP LaserJet Pro M404" "pdl=application/pdf"]
# 发现特定打印机
avahi-browse -t -r _ipp._tcp | grep "LaserJet"
# 静默模式(只输出结果)
avahi-browse -t -r -p _ipp._tcp
# 发现 HTTP 服务(Web 管理界面)
avahi-browse -t -r _http._tcp
# 发现所有服务类型
avahi-browse -t -a
7.2.4 使用 avahi-publish 发布服务
# 手动发布 IPP 服务
avahi-publish -s "My Printer" _ipp._tcp 631 \
"rp=ipp/print" "ty=My Printer" &
# 发布带子类型的服务
avahi-publish -s "My Printer" _ipp._tcp 631 \
--subtype=_universal._sub._ipp._tcp \
"rp=ipp/print" &
# 发布 AirPrint 服务
avahi-publish -s "AirPrint Printer" _ipp._tcp 631 \
--subtype=_universal._sub._ipp._tcp \
"rp=ipp/print" "txtvers=1" "URF=DM3" \
"pdl=application/pdf,image/jpeg" "Color=T" "Duplex=T" &
7.2.5 使用 avahi-resolve 解析
# 解析主机名
avahi-resolve -n HP-LaserJet.local
# 输出: HP-LaserJet.local 192.168.1.100
# 解析服务
avahi-resolve -n _ipp._tcp.local
# 反向解析
avahi-resolve -a 192.168.1.100
7.3 Avahi 配置
7.3.1 Avahi 配置文件
# 主配置文件
cat /etc/avahi/avahi-daemon.conf
配置示例:
[server]
# 主机名(默认使用系统主机名)
# host-name=printserver
# 使用 IPv4
use-ipv4=yes
# 使用 IPv6
use-ipv6=yes
# 允许点对点接口
allow-point-to-point=yes
[wide-area]
# 启用广域 DNS-SD
enable-wide-area=yes
[publish]
# 发布工作站
publish-workstation=no
# 发布打印机(重要!)
publish-printers=yes
# 发布 DNS 服务器
publish-dns-servers=
# 发布地址
publish-addresses=yes
# 发布 HINFO
publish-hinfo=yes
[reflector]
# 启用反射器(跨子网)
enable-reflector=no
[rlimits]
# 资源限制
rlimit-nproc=3
rlimit-nofile=768
7.3.2 配置 Avahi 发布 CUPS 打印机
# 方法 1: CUPS 自动发布(推荐)
# 确保 cups-browsed 已安装并运行
sudo apt install -y cups-browsed
sudo systemctl enable cups-browsed
sudo systemctl start cups-browsed
# 方法 2: 手动创建服务文件
# /etc/avahi/services/ 目录下创建 .service 文件
# 为每个打印机创建服务文件
for printer in $(lpstat -p | awk '{print $2}'); do
sudo tee /etc/avahi/services/airprint-${printer}.service << EOF
<?xml version="1.0" standalone="no"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">${printer} on %h</name>
<service>
<type>_ipp._tcp</type>
<subtype>_universal._sub._ipp._tcp</subtype>
<port>631</port>
<txt-record>rp=ipp/print</txt-record>
<txt-record>txtvers=1</txt-record>
<txt-record>qtotal=1</txt-record>
<txt-record>Transparent=T</txt-record>
<txt-record>URF=DM3</txt-record>
</service>
</service-group>
EOF
done
# 重启 Avahi
sudo systemctl restart avahi-daemon
7.3.3 Avahi 服务文件详解
<?xml version="1.0" standalone="no"?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<!-- 服务名称,%h 会被替换为主机名 -->
<name replace-wildcards="yes">My Printer on %h</name>
<service>
<!-- 服务类型 -->
<type>_ipp._tcp</type>
<!-- 子类型(AirPrint 需要) -->
<subtype>_universal._sub._ipp._tcp</subtype>
<!-- 服务端口 -->
<port>631</port>
<!-- TXT 记录 -->
<txt-record>rp=ipp/print</txt-record> <!-- 资源路径 -->
<txt-record>txtvers=1</txt-record> <!-- TXT 版本 -->
<txt-record>qtotal=1</txt-record> <!-- 队列总数 -->
<txt-record>Transparent=T</txt-record> <!-- 透明打印 -->
<txt-record>URF=DM3</txt-record> <!-- Apple Raster 标签 -->
<txt-record>kind=document,envelope</txt-record> <!-- 支持的介质类型 -->
<txt-record>product=(CUPS Printer)</txt-record> <!-- 产品名称 -->
<txt-record>pdl=application/pdf,image/jpeg</txt-record> <!-- 支持的格式 -->
<txt-record>Color=T</txt-record> <!-- 支持彩色 -->
<txt-record>Duplex=T</txt-record> <!-- 支持双面 -->
</service>
</service-group>
7.4 cups-browsed
7.4.1 cups-browsed 概述
cups-browsed 是 CUPS 的自动打印机发现服务:
| 功能 | 说明 |
|---|---|
| 自动发现 | 通过 DNS-SD 发现网络打印机 |
| 自动添加 | 将发现的打印机自动添加到本地 CUPS |
| 负载均衡 | 支持打印机组负载均衡 |
| 高可用性 | 自动切换到可用的打印机 |
7.4.2 cups-browsed 配置
# 安装 cups-browsed
sudo apt install -y cups-browsed
# 配置文件
sudo vim /etc/cups/cups-browsed.conf
配置示例:
# 自动发现本地网络打印机
BrowsePoll cups-server.local:631
# 指定远程 CUPS 服务器
BrowsePoll 192.168.1.100
BrowsePoll cups2.example.com
# 只发现特定类型的打印机
BrowseProtocols dnssd
# 创建本地队列(默认:是)
CreateIPPPrinterQueues Yes
# 保留队列(默认:是)
# 设置为 No 可在打印机离线时自动删除队列
AutoShutdownOnIdle No
# 日志级别
LogLevel info
# 只发现特定域
BrowseRemoteDNSSDSubTypes _universal
# 忽略特定打印机
IgnorePrinters regex1,regex2
# 自动删除离线打印机
# (秒数,0 表示禁用)
RemoteTimeout 300
7.4.3 cups-browsed 管理
# 启动 cups-browsed
sudo systemctl start cups-browsed
# 设置开机自启
sudo systemctl enable cups-browsed
# 查看状态
sudo systemctl status cups-browsed
# 重启服务
sudo systemctl restart cups-browsed
# 查看日志
journalctl -u cups-browsed -f
# 查看发现的打印机
lpstat -p
# 查看 cups-browsed 创建的队列
lpstat -v | grep "cups-browsed"
7.4.4 cups-browsed 高级配置
# /etc/cups/cups-browsed.conf
# 负载均衡配置
LoadBalancing on
# 可选值:
# on - 在队列中的所有打印机间负载均衡
# QueueOnRemotePrinters - 远程队列负载均衡
# QueueBySubsystem - 按子系统负载均衡
# None - 不负载均衡
# 创建 IPP Everywhere 打印机
CreateIPPPrinterQueues Yes
# 使用 IPP 优先
IPPPrinterQueueType Auto
# 只发现特定制造商
BrowseFilter manufacturer "HP"
# 排除特定打印机
BrowseFilter reject "Old Printer"
# 配置默认选项
# DefaultOption media A4
# DefaultOption sides two-sided-long-edge
# 自动删除空闲打印机
AutoShutdownTimeout 60
# 保留时间(秒)
RemoteTimeout 600
7.5 Browse 协议(已废弃)
注意:Browse 协议已在 CUPS 1.6 中被废弃,仅在旧版本中使用。
7.5.1 Browse 协议工作原理
┌──────────────┐ UDP 广播 ┌──────────────┐
│ CUPS 服务器 A │ ─────────▶│ CUPS 服务器 B │
│ (发布者) │ 端口 631 │ (订阅者) │
└──────────────┘ └──────────────┘
│ │
│ │
▼ ▼
打印机列表 打印机列表
(本地+远程) (本地+远程)
7.5.2 Browse 协议配置(旧版本)
# CUPS 1.5 及更早版本配置
# /etc/cups/cupsd.conf
# 启用 Browse(发布打印机)
BrowseAddress @LOCAL
# 或指定地址
# BrowseAddress 192.168.1.255
# 接收 Browse(发现打印机)
BrowseAllow all
# 或指定网络
# BrowseAllow 192.168.1.0/24
# 设置 Browse 协议
BrowseProtocols cups
# 或使用 LDAP
# BrowseProtocols ldap
# 设置 Browse 超时
BrowseTimeout 300
7.6 跨网络打印共享
7.6.1 多子网打印架构
┌─────────────────────────────────────────────────┐
│ 子网 A (192.168.1.0/24) │
│ ┌─────────┐ ┌─────────┐ │
│ │ 工作站1 │ │ 工作站2 │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ └───────┬───────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ CUPS 服务器 A│ │
│ │ (主) │ │
│ └──────┬──────┘ │
└───────────────┼─────────────────────────────────┘
│
┌───────┴───────┐
│ 路由器/防火墙 │
└───────┬───────┘
│
┌───────────────┼─────────────────────────────────┐
│ 子网 B (192.168.2.0/24) │
│ │ │
│ ┌──────▼──────┐ │
│ │ CUPS 服务器 B│ │
│ │ (备份) │ │
│ └──────┬──────┘ │
│ ┌───────┴───────┐ │
│ │ │ │
│ ┌────▼────┐ ┌────▼────┐ │
│ │ 工作站3 │ │ 工作站4 │ │
│ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────┘
7.6.2 跨子网配置
# 方法 1: 使用 cups-browsed 跨子网
# 在子网 B 的 cups-browsed 中配置
# /etc/cups/cups-browsed.conf
BrowsePoll 192.168.1.100:631
# 方法 2: 使用 Avahi 反射器
# 在路由器上启用 Avahi 反射器
# /etc/avahi/avahi-daemon.conf
[reflector]
enable-reflector=yes
# 方法 3: 使用 VPN
# 配置 OpenVPN 或 WireGuard 隧道
# 打印机流量通过 VPN 传输
# 方法 4: 使用 DNS 转发
# 配置 DNS 服务器转发 mDNS 查询
7.6.3 使用 Avahi 反射器
# 在连接两个子网的主机上配置
sudo vim /etc/avahi/avahi-daemon.conf
[reflector]
enable-reflector=yes
reflect-ipv=no
# 重启 Avahi
sudo systemctl restart avahi-daemon
# 验证跨子网发现
# 在子网 B 的主机上运行
avahi-browse -t -r _ipp._tcp
# 应该能看到子网 A 的打印机
7.6.4 使用 OpenVPN 隧道
# 服务器端 (192.168.1.100)
# /etc/openvpn/server.conf
server 10.8.0.0 255.255.255.0
push "route 192.168.1.0 255.255.255.0"
# 客户端
# /etc/openvpn/client.conf
remote vpn.example.com 1194
# 客户端添加打印机
sudo lpadmin -p VPNPrinter -E \
-v "ipp://192.168.1.100/printers/myprinter" \
-m "everywhere"
7.7 访问控制
7.7.1 CUPS 访问控制层级
┌─────────────────────────────────────────────────┐
│ CUPS 访问控制模型 │
│ │
│ 1. IP 地址过滤 │
│ Allow/Deny IP 地址范围 │
│ │
│ 2. 用户认证 │
│ Basic/Digest/证书认证 │
│ │
│ 3. 操作权限 │
│ Read/Write/Admin 权限 │
│ │
│ 4. 打印机级别 │
│ 每个打印机独立的访问控制 │
└─────────────────────────────────────────────────┘
7.7.2 IP 地址过滤
# /etc/cups/cupsd.conf
# 允许本地访问
<Location />
Order allow,deny
Allow localhost
Allow 127.0.0.1
Allow @LOCAL
</Location>
# 允许特定网络
<Location /printers>
Order allow,deny
Allow localhost
Allow 192.168.1.0/24
Allow 10.0.0.0/8
</Location>
# 允许特定 IP
<Location /admin>
Order allow,deny
Allow localhost
Allow 192.168.1.100
Allow 192.168.1.101
</Location>
# 拒绝特定 IP
<Location />
Order deny,allow
Deny 192.168.1.50
Allow all
</Location>
7.7.3 用户认证配置
# /etc/cups/cupsd.conf
# 基本认证
DefaultAuthType Basic
# 摘要认证(更安全)
DefaultAuthType Digest
# 本地认证(使用系统用户)
AuthType Default
# 管理界面认证
<Location /admin>
AuthType Default
Require user @SYSTEM
</Location>
# 配置文件认证
<Location /admin/conf>
AuthType Default
Require user @SYSTEM
</Location>
# 打印机级别认证
<Printer secret-printer>
AuthType Default
Require user john mary bob
</Printer>
# 组认证
<Printer finance-printer>
AuthType Default
Require group finance
</Printer>
7.7.4 创建 CUPS 用户
# 添加用户到 lpadmin 组(管理权限)
sudo usermod -aG lpadmin username
# 创建 CUPS 特定用户(使用 htdigest)
sudo htdigest /etc/cups/passwd "CUPS" username
# 或使用 Samba 用户
# 需要配置 PAM
# 查看 CUPS 用户
cat /etc/cups/passwd
# 删除 CUPS 用户
sudo htdigest /etc/cups/passwd "CUPS" username
7.7.5 打印机级别的访问控制
# 为特定打印机设置访问控制
sudo lpadmin -p myprinter \
-u allow:john,mary,bob \
-u deny:guest
# 允许所有用户
sudo lpadmin -p myprinter -u allow:all
# 只允许特定组
sudo lpadmin -p myprinter -u allow:@finance
# 拒绝所有用户(禁用打印机)
sudo lpadmin -p myprinter -u deny:all
# 查看打印机访问控制
lpstat -p myprinter -l
7.8 Samba 打印共享
7.8.1 安装 Samba
# 安装 Samba
sudo apt install -y samba samba-common
# 配置 Samba
sudo vim /etc/samba/smb.conf
7.8.2 配置 Samba 共享打印机
# /etc/samba/smb.conf
[global]
workgroup = WORKGROUP
server string = Print Server
security = user
map to guest = bad user
# 打印机配置
printing = cups
printcap name = cups
load printers = yes
cups server = localhost
[printers]
comment = All Printers
path = /var/spool/samba
browseable = no
guest ok = no
writable = no
printable = yes
create mask = 0700
[print$]
comment = Printer Drivers
path = /var/lib/samba/printers
browseable = yes
read only = yes
guest ok = no
# 创建 Samba 打印机共享
sudo mkdir -p /var/spool/samba
sudo chmod 1777 /var/spool/samba
# 创建驱动目录
sudo mkdir -p /var/lib/samba/printers
sudo chmod 755 /var/lib/samba/printers
# 添加 Samba 用户
sudo smbpasswd -a username
# 重启 Samba
sudo systemctl restart smbd nmbd
7.8.3 Windows 客户端连接
# Windows 连接到 Samba 共享打印机
# 方法 1: 资源管理器
\\linux-server\printer-name
# 方法 2: 添加打印机向导
# 设置 → 设备 → 打印机和扫描仪 → 添加打印机
# 选择 "按名称选择共享打印机"
# 输入: \\linux-server\printer-name
# 方法 3: 命令行
rundll32 printui.dll,PrintUIEntry /in /n \\linux-server\printer-name
7.9 LDAP 集成
7.9.1 CUPS LDAP 配置
# 安装 LDAP 支持
sudo apt install -y libnss-ldap libpam-ldap
# 配置 CUPS 使用 LDAP
# /etc/cups/cupsd.conf
# LDAP 认证
AuthType Default
AuthLDAPURL ldap://ldap.example.com/ou=people,dc=example,dc=example?uid
# LDAP 组认证
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
# 使用 LDAP 进行打印机发现
# BrowseProtocols ldap
# BrowseLDAPServer ldap.example.com
# BrowseLDAPBase ou=printers,dc=example,dc=com
7.9.2 LDAP 打印机条目示例
# 打印机 LDAP 条目
dn: cn=HP-LaserJet,ou=printers,dc=example,dc=com
objectClass: printer
objectClass: top
cn: HP-LaserJet
printer-uri: ipp://192.168.1.100/ipp/print
printer-location: 3rd Floor
printer-make-and-model: HP LaserJet Pro M404
printer-type: 8425492
7.10 业务场景
7.10.1 场景一:办公室打印共享
# 需求:为 50 人办公室配置集中打印
# 步骤 1: 配置 CUPS 服务器
sudo cupsctl --share-printers
sudo cupsctl BrowseLocalProtocols=dnssd
# 步骤 2: 配置防火墙
sudo ufw allow 631/tcp
sudo ufw allow 5353/udp
# 步骤 3: 安装 cups-browsed
sudo apt install -y cups-browsed
sudo systemctl enable cups-browsed
# 步骤 4: 客户端自动发现
# 客户端只需要安装 cups-browsed
# 打印机将自动出现在打印机列表中
7.10.2 场景二:多部门打印隔离
# 需求:不同部门只能访问自己的打印机
# 配置部门打印机
sudo lpadmin -p Finance-Printer -E \
-v socket://192.168.1.100:9100 \
-u allow:@finance
sudo lpadmin -p HR-Printer -E \
-v socket://192.168.1.101:9100 \
-u allow:@hr
sudo lpadmin -p IT-Printer -E \
-v socket://192.168.1.102:9100 \
-u allow:@it
# 创建部门共享打印机(所有部门可用)
sudo lpadmin -p Shared-Printer -E \
-v socket://192.168.1.103:9100 \
-u allow:all
7.10.3 场景三:跨站点打印
# 需求:北京和上海办公室共享打印服务
# 北京 CUPS 服务器配置
# /etc/cups/cups-browsed.conf
BrowsePoll cups-shanghai.example.com:631
# 上海 CUPS 服务器配置
# /etc/cups/cups-browsed.conf
BrowsePoll cups-beijing.example.com:631
# 客户端配置(两个站点)
# /etc/cups/cups-browsed.conf
BrowsePoll cups-local.example.com:631
BrowseRemoteProtocols cups
7.11 扩展阅读
| 资源 | 链接 |
|---|---|
| Avahi 项目 | https://avahi.org/ |
| DNS-SD 规范 | https://datatracker.ietf.org/doc/html/rfc6763 |
| mDNS 规范 | https://datatracker.ietf.org/doc/html/rfc6762 |
| cups-browsed 手册 | man cups-browsed |
| Samba 文档 | https://www.samba.org/samba/docs/ |
| CUPS 共享文档 | https://www.cups.org/doc/sharing.html |
7.12 本章小结
| 主题 | 关键要点 |
|---|---|
| DNS-SD | 基于 mDNS 的服务发现,推荐使用 |
| Avahi | Linux 的 mDNS/Bonjour 实现 |
| cups-browsed | 自动发现和添加远程打印机 |
| Browse 协议 | 已废弃,仅用于旧版 CUPS |
| 跨网络 | 使用 Avahi 反射器、VPN 或 DNS 转发 |
| 访问控制 | IP 过滤、用户认证、打印机级别权限 |
下一章预告:我们将深入学习 CUPS 的过滤器和后端系统,包括 MIME 类型检测、文档转换和自定义过滤器开发。
7.13 练习题
发现题:使用
avahi-browse发现网络中的所有 IPP 打印机,并记录其 URI。共享题:配置 CUPS 共享打印机,使同一子网内的其他计算机可以自动发现并使用。
安全题:为打印机配置访问控制,只允许特定用户组打印。
跨网络题:配置 Avahi 反射器,实现两个子网之间的打印机发现。
Samba 题:配置 Samba 共享打印机,使 Windows 客户端可以连接使用。