用 Linux 搭一个家用打印服务器:CUPS + AirPrint + 扫码打印一条龙
写在前面
家里/小团队要共享打印机,最实用的方案就是把一台 Linux 主机(甚至树莓派)变成打印服务器。一台 24 小时开机的旧笔记本/小盒子,配上 CUPS + Avahi,能做到:
- iPhone / iPad / macOS 弹窗直接选打印机(AirPrint)
- Windows 10/11 不装任何驱动,添加网络打印机就行(IPP Everywhere)
- Android 通过系统打印服务或第三方 App(默认服务从 Android 12 起已内置 IPP)
- 自带 Web 管理界面(
https://打印服务器IP:631) - 进阶:二维码扫码上传文件打印(家用超实用)
整套方案 CUPS 一个软件搞定核心,本文按"能用 → 好用 → 进阶"三段写。
0. 准备工作
硬件三种接法
| 接法 | 适用 | 是否需要驱动 |
|---|---|---|
| A. USB 直连 Linux 主机 | 老式喷墨/激光(无网口) | 需要从 Linux 装驱动 |
| B. 网线/WiFi 联网打印机(自带有 IP) | 主流家用打印机 | 99% 无需驱动(IPP Everywhere) |
| C. 树莓派/小盒子 + 蓝牙或 USB 转接 | 没有多余电脑 | 同 A |
强烈建议 B:2020 年后的打印机基本都自带 AirPrint/IPP,你只要给它一个 IP,Linux 端都不用装驱动。买打印机时认准"支持 AirPrint"或"IPP Everywhere"字样。
操作系统
我用 Ubuntu 24.04 LTS 演示,Debian 12 / CentOS Stream 9 同理。CUPS 在所有主流发行版仓库里都有。
1. 安装 CUPS(一行命令)
sudo apt update
sudo apt install cups cups-browsed avahi-daemon -y
三个包各管一摊:
- cups:打印服务本体
- cups-browsed:客户端用,本机作为客户端去发现其他网络打印机时需要(服务端可装可不装,但装了没坏处)
- avahi-daemon:mDNS/Bonjour,让 iPhone/macOS 能"看见"这台打印服务器
启动并设开机自启:
sudo systemctl enable --now cups avahi-daemon
systemctl status cups --no-pager # 看到 active (running) 就 OK
2. CUPS 服务端配置(核心)
配置文件 /etc/cups/cupsd.conf,我只改必须改的 4 处,不动其他默认:
sudo cp /etc/cups/cupsd.conf /etc/cups/cupsd.conf.bak # 先备份
sudo vim /etc/cups/cupsd.conf
① 监听所有网卡(不只是 localhost)
# 找到这一行
# Listen localhost:631
# 改成
Port 631
Listen /var/run/cups/cups.sock
② 开启共享广播
Browsing On
BrowseLocalProtocols dnssd
这一对让 CUPS 主动把打印机广播到 mDNS(关键)。
③ 放行局域网访问
默认配置里 <Location /> 是 Allow @LOCAL,只要你的客户端和服务器在同一子网(家用 192.168.x.x 那种),就能直接访问。如果是公司网或者跨网段,需要显式加 Allow 192.168.0.0/16 这种。
如果想偷懒(家用网络,反正是信任的):
<Location />
Order allow,deny
Allow all
</Location>
<Location /admin>
AuthType Default
Require user @SYSTEM
Order allow,deny
Allow all
</Location>
⚠️ 上面
Allow all是家用方案,公司/对外服务别这么写,至少加 IP 段限制。
④ 启用 ServerAlias
ServerAlias *
让 Avahi 广播的 SRV 记录里带上所有 hostname。
重启 CUPS
sudo systemctl restart cups
3. 添加打印机
3.1 接法 A:USB 直连
插上 USB 打印机,Linux 识别后:
lsusb # 看到打印机设备就行
打开浏览器访问 https://<服务器IP>:631,点 Administration → Add Printer,用 root 账号登录(Debian/Ubuntu 默认就是当前 sudo 用户)。
注意:第一次访问会看到"连接不安全"的证书警告,CUPS 默认自签证书。家用环境**点"高级"→"继续访问"**就行,不要点"拦截"。
点 Add Printer 后会看到本地打印机(Local Printers 下),CUPS 会自动推荐驱动(everywhere 优先),按提示走完。
3.2 接法 B:联网打印机
# 用 avahi 看一下网络里有哪些打印机
avahi-browse -a -t | grep -i print
# 输出示例:
# + eth0 IPv4 HP LaserJet M211 _ipp._tcp local
# 看到 _ipp._tcp 服务就说明支持 IPP,CUPS 能直接连
打开 Web UI → Add Printer → Discovered Network Printers 里会列出找到的所有打印机,选 IPP/IPPS 协议的那个(不是 LPD 也不是 Socket),driver 选 everywhere,完事。
3.3 命令行备选方案
不想用 Web 界面,可以 lpadmin 一行命令搞定:
sudo lpadmin -p OfficeJet \
-E \
-v ipp://192.168.1.100/ipp/print \
-m everywhere \
-L "客厅打印机" \
-o printer-is-shared=true
# -E 启用并接受任务
# -m everywhere 用 IPP Everywhere 通用驱动
# -o printer-is-shared=true 让 CUPS 把这台打印机通过 mDNS 广播
sudo cupsenable OfficeJet
sudo cupsaccept OfficeJet
3.4 验证:打一张测试页
lp -d OfficeJet /usr/share/cups/data/testprint
或者 Web UI 上点 “Print Test Page”。
4. 各平台客户端怎么连
4.1 iPhone / iPad / macOS(AirPrint)
不需要任何配置。
打印机在 CUPS 启用 printer-is-shared=true 后,Avahi 会通过 mDNS 把打印机广播到 _ipp._tcp 服务里。Apple 设备自动发现:
- macOS:系统设置 → 打印机与扫描仪 → 看到打印机直接点+
- iOS:任何 App 的"打印"按钮 → 选打印机
踩坑提示:iPhone 找不到打印机,90% 是 mDNS 没广播成功。检查:
avahi-browse -a -t | grep _ipp._tcp有输出 = 没问题;没输出 = 防火墙拦了 UDP 5353(见第 6 节)。
4.2 Windows 10 / 11(IPP Everywhere)
从 Windows 10 1809 起内置 IPP 客户端,不装任何驱动:
- 设置 → 蓝牙和设备 → 打印机和扫描仪 → 添加设备
- 点"我需要的打印机不在列表中"
- 选"按 TCP/IP 地址或主机名添加打印机"
- 设备类型:IPP 设备(重要,别选 TCP/IP 设备)
- URL:
http://<服务器IP>:631/printers/OfficeJet - 驱动列表里选"Generic / MS Publisher Color Printer"(Windows 自带通用驱动)
如果 Windows 提示需要驱动:说明打印机没有走 IPP,走的是旧 SMB。改 URL 为
ipp://试试。Windows 11 22H2+ 对 IPP 支持最完善。
4.3 Android
- Android 12+(2021 年起):系统设置 → 连接与共享 → 打印 → 默认打印服务(Android 系统打印服务),自动发现 IPP 打印机
- Android 11 及更早:装 Mopria Print Service(Mopria 联盟的免费插件,标准 IPP 客户端)
4.4 Linux 客户端
sudo apt install cups cups-browsed system-config-printer -y
sudo systemctl enable --now cups-browsed
# 等几秒,打印机自动出现在 gnome-control-center / 打印设置里
5. Web 管理界面(自带)
CUPS 自带 Web UI,是管理打印机最方便的方式:
- 主页:
http://<服务器IP>:631/ - 打印机列表:
/printers - 管理页:
/admin(需要 root 账号登录) - 任务历史:
/jobs
支持的常用操作:
- 加/删/改打印机
- 看任务状态、取消任务
- 改共享状态、改默认打印机
- 上传 PPD 驱动(极少数不支持 everywhere 的老型号需要)
6. 防火墙
家用路由器通常自带防火墙,要给打印服务器放行两个端口:
| 协议 | 端口 | 用途 |
|---|---|---|
| TCP | 631 | IPP 打印 + Web UI |
| UDP | 5353 | mDNS / Bonjour(没这个 iPhone 找不到打印机) |
# ufw (Ubuntu 默认)
sudo ufw allow 631/tcp
sudo ufw allow 5353/udp
# firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-port=631/tcp
sudo firewall-cmd --permanent --add-port=5353/udp
sudo firewall-cmd --reload
7. 进阶:扫码打印(家用超实用)
场景:家里老人/小孩用手机拍了文档/收据想打印,不用学 AirPrint,直接扫码上传。
我不推荐自己写(Web 上传 → 后端接收 → 转 PDF → 调 CUPS 提交)—— 看似简单实际上传、文件类型、PDF 转换、错误处理、并发限制能写 1000 行。
现成方案:
- Paperless-ngx(文档管理 + 打印):主业是文档归档,但支持"接收邮件附件自动打印"和 Web 上传 → 打印
- PrintBot / OctoPrint 这种 偏工业,pass
- 最简方案:自建一个 Flask 小应用(50 行)
下面给最简方案的实现思路,直接能跑:
# app.py
from flask import Flask, request, render_template_string
import subprocess, uuid, os
app = Flask(__name__)
UPLOAD_DIR = "/var/spool/print-jobs"
os.makedirs(UPLOAD_DIR, exist_ok=True)
PRINTER = "OfficeJet" # 你的 CUPS 打印机名
HTML = """
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" accept=".pdf,.jpg,.png" required>
<button>打印</button>
</form>
<p>{{ msg }}</p>
"""
@app.route("/", methods=["GET", "POST"])
def index():
msg = ""
if request.method == "POST":
f = request.files["file"]
path = os.path.join(UPLOAD_DIR, str(uuid.uuid4()) + "_" + f.filename)
f.save(path)
# -t 让 CUPS 自行转换(PDF/图片都能打)
result = subprocess.run(["lp", "-d", PRINTER, path], capture_output=True, text=True)
msg = "✓ 已提交:" + (result.stdout.strip() or result.stderr.strip())
return render_template_string(HTML, msg=msg)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
pip install flask
sudo python3 app.py
# 浏览器访问 http://<服务器IP>:5000
接上二维码:
- 静态二维码:把这台打印服务器的 URL 打印一张贴墙上(最省事)
- 动态二维码:用草料二维码生成 URL 即可
生产化建议:
- 加 nginx 反代 + HTTPS(防上传文件明文传输)
- 加白名单 IP(不是所有人都能提交任务)
- 加限速(防恶意刷请求)
8. 安全清单
家用网络相对宽容,但有几条该做的:
- CUPS 管理员密码必须设:Web UI 的 admin 操作需要认证
- 不要把 CUPS 暴露到公网:631 端口开在公网 = 任何人都能往你打印机塞东西
- 开启 CUPS 的 TLS(IPPS):让传输加密(CUPS 2.4+ 一行配置)
- 打印机固件保持最新:联网打印机自身的漏洞(CVE-2017-13082 那批广域网打印机蠕虫就是反例)
- 定期看
/jobs页面:发现异常打印任务说明可能被人蹭了
# 启用 IPPS(HTTPS 打印)
# /etc/cups/cupsd.conf
DefaultEncryption IfRequested
9. 常见问题排查
Q1:iPhone 死活找不到打印机
# 1. 看 CUPS 是否把打印机设为共享
lpstat -p OfficeJet -l | grep -i shared
# 应该有 "shared" 字样
# 2. 看 mDNS 是否在广播
avahi-browse -a -t | grep _ipp._tcp
# 没输出 = UDP 5353 被防火墙拦了
# 3. 看手机和服务器是否同一子网
# iPhone 的 WiFi IP 应该是 192.168.x.x,服务器也得是
# 跨网段 mDNS 转发需要单独配置(一般路由器不支持)
Q2:Windows 添加打印机报错
- 错误 0x00000709:URL 写错了,必须是
ipp://或ipps://开头 - 错误 0x0000011b(Win11 22H2 那个著名补丁):临时方案是装 Bonjour Print Services,或在打印机高级选项里关掉 SMB1 强制签名
Q3:打印任务一直卡在队列里
# 看任务状态
lpstat -o
# 取消卡住的任务
cancel <job-id>
# 或者重置打印机
cupsenable OfficeJet
cupsdisable OfficeJet # 再 enable
sudo systemctl restart cups
Q4:CUPS 2.4 的 CVE-2025-58364(DoS)
2025 年 8 月的漏洞,子网内未授权用户能触发 CUPS 崩溃。升级到 2.4.13+ 即可。Ubuntu 24.04 的 apt 已包含修复:
sudo apt update && sudo apt upgrade cups
总结
最小可用方案(30 分钟搞定):
- 装 CUPS + Avahi
- 改
cupsd.conf:Port 631+Browsing On - Web UI 加打印机(
everywhere驱动) - 防火墙开 TCP 631 + UDP 5353
进阶玩法(半天):
- 扫码上传打印(Flask 50 行)
- Paperless-ngx 做文档归档
- 手机/平板全平台自动发现
家用和小团队(20 人以下)这套方案完全够用,比买一台"网络打印机"自带的服务稳定得多,而且打印机死了换一台就行,配置都在 Linux 上。
我自己的小团队跑了 2 年,掉过 2 次链(一次是 Avahi 升级后没自启,一次是打印机本身卡纸),都比"网络打印机自带服务"出问题好修。
611

被折叠的 条评论
为什么被折叠?



