用 Linux 搭一个家用打印服务器:CUPS + AirPrint + 扫码打印一条龙

用 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 客户端,不装任何驱动

  1. 设置 → 蓝牙和设备 → 打印机和扫描仪 → 添加设备
  2. 点"我需要的打印机不在列表中"
  3. 选"按 TCP/IP 地址或主机名添加打印机"
  4. 设备类型:IPP 设备(重要,别选 TCP/IP 设备)
  5. URL:http://<服务器IP>:631/printers/OfficeJet
  6. 驱动列表里选"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. 防火墙

家用路由器通常自带防火墙,要给打印服务器放行两个端口

协议端口用途
TCP631IPP 打印 + Web UI
UDP5353mDNS / 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 行。

现成方案

  1. Paperless-ngx(文档管理 + 打印):主业是文档归档,但支持"接收邮件附件自动打印"和 Web 上传 → 打印
  2. PrintBot / OctoPrint 这种 偏工业,pass
  3. 最简方案:自建一个 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 分钟搞定):

  1. 装 CUPS + Avahi
  2. cupsd.confPort 631 + Browsing On
  3. Web UI 加打印机(everywhere 驱动)
  4. 防火墙开 TCP 631 + UDP 5353

进阶玩法(半天):

  • 扫码上传打印(Flask 50 行)
  • Paperless-ngx 做文档归档
  • 手机/平板全平台自动发现

家用和小团队(20 人以下)这套方案完全够用,比买一台"网络打印机"自带的服务稳定得多,而且打印机死了换一台就行,配置都在 Linux 上。

我自己的小团队跑了 2 年,掉过 2 次链(一次是 Avahi 升级后没自启,一次是打印机本身卡纸),都比"网络打印机自带服务"出问题好修。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码绘春秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值