使用飞牛实现HP1020 打印机配置真无线打印
HP1020打印机真扛造,本来就是收的二手的,成色就像是从垃圾站捡来的,又放了一年多没用,这次拿出来还掉了了好多零件,但是打印功能一切正常,所以还是很值得折腾一下的。这台打印机最不方便的地方就是不能无线打印,之前接群晖可以在局域网内使用,但是只能电脑端使用,而且还需要安装驱动,这次目的,就是要实现真无线,不接网线,打印机随便放(有插线板就行),电脑、手机都能无线免驱打印。
这次能实现无线打印,要依赖这个小东西:

这是一台迷你无线路由器,型号是 GL-MT300N-v2,有无线功能,有 usb 口。但是它性能太弱鸡了,只能安装 p910nd 做一个打印终端,无法安装 cups,这时候就需要飞牛了,在飞牛的 Docker 中安装打印服务器,电脑和手机连接飞牛,然后飞牛再连接这个小路由器。这一套配置是挺复杂的,但是现在有 AI 了,一切都变的简单了,AI 给出的架构图如下:

为什么不直接usb 连接飞牛呢?这不是打印机和飞牛离的太远,而且打印机平时都在吃灰,只是偶尔用一下。
这次需要的设备是 mt300n-v2,局域网内一台飞牛(群晖或者其他的 Nas 也行)。mt300n-v2配置是 128MB 内存+16MB闪存,装不了 cups,如果路由器配置高,不用飞牛也行。使用 tp link的 tl-wr703n这种小路由器也行,体积更小,价格更便宜,但是闪存只有 4MB,配置起来更麻烦。
要做的步骤如下:
mt300n-v2刷 openwrt,主要是为了腾空间,官方 rom 装了一堆软件,剩余空间只有 1-2MB,刷纯净 openwrt 后空间有 9.5MB。
配置好 mt300n 的 ssh 免输密码登录,进入 openwrt 的 web 管理页面,打开:系统-管理,在SSK-Keys 添加本机的 pub key。这一步比较重要,因为这一步 AI 无法操作。
在 mt300n 安装打印服务软件 p910nd 和驱动,编写驱动自动加载脚本。这一步完全交给 AI 就行,做完了可以在电脑上装上驱动测试一下通不通,如果觉得麻烦,也可以下一步安装 cups 服务器的时候一块测。
配置好飞牛的 ssh,这一步也很重要,因为这需要人操作,而且飞牛的 ssh 配置起来比较麻烦,可以让 AI 生成命令,然后复制到 terminal 中执行。
在飞牛安装 cups-airprint,打印测试页,这一步也是完全 AI 来操作。
第 5 步AI 只用了十几分钟,如果我自己操作,怎么也得几个小时。

至此,全部完成,设置好之后在 Mac 就可以直接添加打印机了,不用安装驱动,苹果手机可以直接识别到打印机。


我用的是 claude+glm5.2,这个配置工作对模型的要求不高,我让 AI 总结了一下文档,如果你的 AI 配置的不够理想,可以把这个文档或者这个文章链接直接喂给 AI。以下就是 AI 的总结:
HP LaserJet 1020 家庭打印服务部署指南(MT300N-V2 + fnOS)
把老式 USB 单色激光打印机 HP LaserJet 1020 接入家庭局域网,实现 iOS / Android / macOS / Windows 全平台免驱动打印。
核心思路:职责分离 —— 用一台资源受限的 OpenWrt 路由器做 USB 桥 + 固件加载,用一台资源充足的 NAS 做 PDF→ZjS 渲染 + AirPrint 广播。
总览架构
iPhone/PC
│ AirPrint (mDNS)
▼
┌─────────────────────────┐
│ NAS (Docker) │
│ CUPS :631 │ ← Phase 2:格式转换 + AirPrint
│ ghostscript + foo2zjs │
│ 复用宿主 avahi │
└──────────┬──────────────┘
│ socket://:9100 (RAW 9100)
▼
┌─────────────────────────┐
│ OpenWrt Router │
│ p910nd :9100 │ ← Phase 1:USB 桥 + 固件加载
│ hotplug 自动加载固件 │
└──────────┬──────────────┘
│ USB /dev/usb/lp0
▼
HP LaserJet 1020
(host-based GDI 打印机)
组件角色资源要求HP1020物理打印机vid 03f0 pid 2b17OpenWrt 路由器USB 桥 + 固件加载任何能跑 OpenWrt 的设备,有 USB 口 + WiFiNAS / Linux 主机CUPS + AirPrint 网关x86 / 强 ARM,≥2GB RAM,支持 DockeriPhone/AndroidAirPrint 客户端系统原生,无需 AppWindows/macOSIPP / RAW 9100 客户端系统原生,无需驱动
本方案对 OpenWrt 路由器型号不挑,示例用 GL.iNet MT300N-V2(便宜、稳定、刷不死)。NAS 部分用飞牛 fnOS,任何能跑 Docker 的 Linux 都行(群晖/Unraid/TrueNAS/Debian)。
关键约束(不要尝试以下方向)
❌ 不要让 OpenWrt 路由器直接跑 CUPS —— 资源不够,ghostscript 渲染 PDF 会 OOM
❌ 不要把 USB 打印机直接接 NAS —— 通常 NAS 在机柜、打印机在书房,USB 线 ≤5m 不够长
❌ 不要让 OpenWrt 路由器只装 avahi 不装 CUPS —— HP1020 是 host-based,必须有主机做 PDF→ZjS 光栅化
Phase 1:OpenWrt 路由器(USB 桥 + 固件加载)
目标:路由器 WiFi 接入家庭局域网,USB 接 HP1020,对外暴露 RAW 9100 端口。
1.1 刷 OpenWrt(以 MT300N-V2 为例)
下载 OpenWrt 23.05.5 sysupgrade 镜像(从 https://openwrt.org/toh/start 找你的型号):
# 校验
shasum -a 256 openwrt-*-sysupgrade.bin
# 对比 OpenWrt 官方 sha256sums 文件
# 上传 + 刷写(GL.iNet 官方固件没有 sftp-server,用 cat 管道)
cat openwrt-*-sysupgrade.bin | ssh root@ 'cat > /tmp/fw.bin'
ssh root@ 'sysupgrade -n /tmp/fw.bin' # -n 不保留配置
刷完,OpenWrt 默认 LAN IP 通常 192.168.1.1,WiFi 默认关闭。
救砖(GL.iNet 设备 U-Boot web 恢复,刷不死):
拔电源,网线连电脑 ↔ LAN 口
电脑设静态 IP
192.168.1.2 / 255.255.255.0按住 reset 通电,继续按住 5~8 秒松开
浏览器
http://192.168.1.1→ 上传 sysupgrade.bin → 等 3 分钟
1.2 WiFi STA 模式接入家庭网络
让路由器作为 WiFi 客户端接入家里主 WiFi,拿静态 IP(选一个在主路由 DHCP 池外的地址)。
ssh root@192.168.1.1 # 首次需电脑网线接 LAN 口,空密码先 passwd
# radio 启用 + 删默认 AP iface
uci set wireless.radio0.disabled=0
uci -q delete wireless.default_radio0
# STA 接口连主 WiFi
uci set wireless.sta=wifi-iface
uci set wireless.sta.device=radio0
uci set wireless.sta.network=wwan
uci set wireless.sta.mode=sta
uci set wireless.sta.ssid=YOUR_WIFI_SSID # ← 改成你的 SSID
uci set wireless.sta.encryption=psk2 # WPA2,wpa/wpa2 mixed 用 psk-mixed
uci set wireless.sta.key='YOUR_WIFI_PASSWORD' # ← 改成你的密码
# wwan 接口拿静态 IP
uci set network.wwan=interface
uci set network.wwan.proto=static
uci set network.wwan.ipaddr=192.168.1.76 # ← 改成你的网段,DHCP 池外
uci set network.wwan.netmask=255.255.255.0
uci set network.wwan.gateway=192.168.1.1 # ← 改成你的网关
uci -q delete network.wwan.dns
uci add_list network.wwan.dns=192.168.1.1
# 防火墙:wwan 归 lan zone(信任)
uci set firewall.@zone[0].network="lan wwan"
uci commit
reboot
等约 65 秒,验证:
ping
ssh root@ 'ifstatus wwan | grep address'
1.3 安装 p910nd + USB 打印驱动
⚠️ 如果主路由跑 OpenClash/AdGuard 等会污染 DNS 的服务,
opkg update可能全部失败。解决:从镜像站(清华/中科大)直接下载 ipk 离线装。
正常路径:
ssh root@ '
opkg update
opkg install p910nd luci-app-p910nd kmod-usb-printer
'
离线路径(主路由 DNS 污染时):
从 https://mirrors.tuna.tsinghua.edu.cn/openwrt/releases//packages// 下载:
p910nd_*.ipkluci-app-p910nd_*.ipkkmod-usb-printer_*.ipk(注意匹配你固件的 kernel 版本)
tar cf - *.ipk | ssh root@ 'cd /tmp && tar xf - && opkg install /tmp/*.ipk'
配置 p910nd:
ssh root@ '
uci set p910nd.@p910nd[0].enabled=1
uci set p910nd.@p910nd[0].runas_root=1 # 避免 /dev/usb/lp0 权限问题
uci set p910nd.@p910nd[0].bidirectional=0 # 单向(p910nd 本质)
uci set p910nd.@p910nd[0].device=/dev/usb/lp0
uci commit p910nd
/etc/init.d/p910nd enable && /etc/init.d/p910nd start
'
# 验证 9100 监听
ssh root@ 'netstat -tln | grep 9100'
1.4 HP 1020 固件加载(关键!)
⚠️ 这是整个方案最关键的一步,理解不到位整个链路都不工作。
HP1020 是 GDI/host-based 打印机,没有内置页面语言,每次通电后必须先把固件 sihp1020.dl 发到 /dev/usb/lp0 才会工作。
获取固件(来自 foo2zjs 项目):
curl -sL "https://github.com/inveneo/hub-linux-ubuntu/raw/master/install/overlay/usr/share/foo2zjs/firmware/sihp1020.dl" -o sihp1020.dl
ls -lh sihp1020.dl # 应 ~123K
xxd sihp1020.dl | head -1 # 首字节应 1b252d31...(ESC%-12345X@PJL)
cat sihp1020.dl | ssh root@ 'cat > /etc/sihp1020.dl'
手动加载验证(此时先别插打印机;插上后):
ssh root@ '
/etc/init.d/p910nd stop; sleep 1 # 释放 lp0(p910nd 独占)
cat /etc/sihp1020.dl > /dev/usb/lp0 # 打印机应开始预热、绿灯亮
sleep 8
/etc/init.d/p910nd start
'
打印机有反应(灯变化/预热声)即固件加载成功。
部署 hotplug 自动加载脚本(关键:免去每次手动 cat):
把下面这个脚本放到路由器 /etc/hotplug.d/usb/20-hp1020-firmware(无后缀,可执行):
#!/bin/sh
# HP LaserJet 1020 固件自动加载
# 原理:USB 设备 add 时,检测 vid 03f0 pid 2b17,自动停 p910nd → 加载固件 → 启 p910nd
# mkdir 原子操作作锁,防止 USB 多接口并发触发
[ "$ACTION" = "add" ] || exit 0
case "$PRODUCT" in
3f0/2b17/*)
(
LOCK=/var/lock/hp1020-fw.lock
if ! mkdir "$LOCK" 2>/dev/null; then
logger -t hp1020 "已有加载进程在跑,跳过"
exit 0
fi
trap 'rmdir "$LOCK" 2>/dev/null' EXIT INT TERM
logger -t hp1020 "检测到 HP LaserJet 1020,加载固件"
sleep 2
/etc/init.d/p910nd stop 2>/dev/null
sleep 1
n=0
while [ $n -lt 10 ] && [ ! -c /dev/usb/lp0 ]; do
sleep 1; n=$((n + 1))
done
[ ! -c /dev/usb/lp0 ] && { logger -t hp1020 "lp0 未出现,放弃"; exit 1; }
cat /etc/sihp1020.dl > /dev/usb/lp0 2>/dev/null
logger -t hp1020 "固件已加载,等待就绪"
sleep 8
/etc/init.d/p910nd start
logger -t hp1020 "p910nd 已重启,打印就绪"
) &
;;
esac
exit 0
部署:
cat hp1020-firmware-hotplug.sh | ssh root@ 'cat > /etc/hotplug.d/usb/20-hp1020-firmware && chmod +x /etc/hotplug.d/usb/20-hp1020-firmware'
验证自动加载:关打印机电源再开,等 15 秒:
ssh root@ 'logread | grep hp1020'
# 应看到:检测到 → 固件已加载 → p910nd 已重启
1.5 Windows 客户端配置(Phase 1 完成后的能力)
设置 → 打印机和扫描仪 → 添加设备 → 「我需要的打印机不在列表中」
选「使用 TCP/IP 地址或主机名添加打印机」
IP:
,下一步探测后选「自定义」→「设置」:
协议:Raw,端口 9100
❌ 不勾「为此设备启用 SNMP 状态检测」
厂商 HP → 型号 HP LaserJet 1020(没有就点 Windows Update)
⚠️ 关键:控制面板 → 设备和打印机 → 右键打印机 → 打印机属性 → 端口标签页 → 取消勾选「启用双向支持」
不关会循环打印(p910nd 单向透传,Windows 双向查询触发反复重发)
Phase 2:NAS CUPS AirPrint 网关
目标:NAS 跑 CUPS,把 PDF 转成 ZjS 流通过 socket 发给路由器,Avahi 广播 AirPrint 让手机发现。
2.1 前提自检
✅ Phase 1 完成,Windows 当前能通过
:9100打印✅ NAS 已启用 Docker
✅ NAS 能 ping 通
nc -zv 9100 # 应 succeeded
docker version # 应有 Server 段
2.2 创建配置文件
在 NAS 上创建目录,例如 /opt/cups-airprint/:
ssh @ 'sudo mkdir -p /opt/cups-airprint/{avahi,config,drivers}'
/opt/cups-airprint/docker-compose.yml:
services:
cups-airprint:
image: anujatar/cups:latest
container_name: cups-airprint
restart: unless-stopped
network_mode: host # 必须:host 网络让 mDNS 广播源 IP 正确
volumes:
- ./config:/etc/cups
- ./drivers:/usr/local/share/drivers
environment:
- CUPSADMIN=YOUR_CUPS_PASSWORD # ← 改成你的 CUPS 管理密码
- CUPSFROMANY=true
- CUPSENABLETLS=1
/opt/cups-airprint/avahi/airprint-laserjet1020.service:
<?xml version="1.0" standalone='no'?>
HP LaserJet 1020
_ipp._tcp
_universal._sub._ipp._tcp
nas.local
631
txtvers=1
qtotal=1
rp=printers/HP_LaserJet_1020
ty=HP LaserJet 1020
product=(HP LaserJet 1020)
note=Home Laser Printer
pdl=application/pdf,application/postscript,application/octet-stream,image/urf
URF=none
Color=F
Duplex=F
Scan=F
adminurl=http://:631/printers/HP_LaserJet_1020
UUID=<生成一个新的 UUID:运行 uuidgen>
⚠️ 关键替换点:
:用 NAS 宿主的 hostname(hostname命令输出 +.local),不是容器 hostname
:你 NAS 的 IP
UUID:运行uuidgen生成一个,避免和其他 AirPrint 设备冲突
rp=printers/HP_LaserJet_1020:必须和后面 CUPS 队列名严格一致(大小写、下划线)
2.3 启动容器
ssh @ 'cd /opt/cups-airprint && sudo docker compose up -d'
首次拉镜像约 350MB,1-3 分钟。验证:
ssh @ 'sudo docker ps | grep cups-airprint' # 应 Up
curl -sk -o /dev/null -w "%{http_code}n" https://:631 # 应 200/301
2.4 添加打印机到 CUPS(命令行,无需 Web UI)
ssh @ 'sudo docker exec cups-airprint bash -lc "
lpadmin -p HP_LaserJet_1020
-v socket://:9100
-m foo2zjs:0/ppd/foo2zjs/HP-LaserJet_1020.ppd
-E
-L Home
-D "HP LaserJet 1020"
-o printer-is-shared=true
"'
⚠️ 队列名
HP_LaserJet_1020(下划线,大小写)必须和 avahi service 里的rp=完全一致。
也可通过 Web UI:https://:631/admin,Basic Auth 用户 admin / 密码 = 你在 compose 里设的 CUPSADMIN。
2.5 把 avahi service 挂到宿主(关键!)
⚠️ Phase 2 最大的坑:
anujatar/cups镜像默认不启动 avahi-daemon,所以 service 文件必须放到宿主的/etc/avahi/services/,不是容器里的。
ssh @ 'sudo bash -c "
cp /opt/cups-airprint/avahi/airprint-laserjet1020.service /etc/avahi/services/
systemctl reload avahi-daemon # 或 systemctl restart avahi-daemon
"'
如果 NAS 没装 avahi-daemon:sudo apt install avahi-daemon(Debian/Ubuntu)。
2.6 验证 AirPrint 广播
ssh @ 'avahi-browse -rt _ipp._tcp 2>&1 | grep -E "rp=|pdl=|product="'
应看到:
rp=printers/HP_LaserJet_1020
pdl=application/pdf,...
product=(HP LaserJet 1020)
iOS 上:备忘录 → 分享 → 打印 → 应自动出现 "HP LaserJet 1020"。
2.7 持久化备份(docker commit)
部署完成后立刻备份,避免意外:
ssh @ 'sudo bash -c "
docker commit -m "HP LaserJet 1020 AirPrint gateway" cups-airprint cups-airprint:deployed
docker tag cups-airprint:deployed cups-airprint:v1-$(date +%Y%m%d)
"'
恢复时改 compose 的 image: 为 cups-airprint:deployed 即可。
Phase 3:客户端配置
平台配置是否免驱动iOS / iPadOS同 WiFi 下,任意 App → 分享 → 打印 → 自动出现✅ 系统原生 AirPrintAndroid ≥ 7自带 Mopria Print Service,文档 → 分享 → 打印✅ MopriamacOS系统设置 → 打印机 → 添加 → 自动发现✅ AirPrintWindows 10/11走 IPP:http://:631/printers/HP_LaserJet_1020需选 HP LaserJet 1020 驱动(系统自带)Windows(legacy)直连 :9100 RAW,关闭双向支持需装 HP Hostbased 驱动
端到端验证清单
# 1. OpenWrt 路由器链路
ssh root@ 'pgrep p910nd && netstat -tln | grep 9100'
# 期望:有 PID,9100 LISTEN
# 2. NAS → 路由器 socket 可达
ssh @ 'sudo docker exec cups-airprint nc -zv 9100'
# 期望:succeeded
# 3. CUPS 容器健康
ssh @ 'sudo docker ps | grep cups-airprint'
# 期望:Up
# 4. AirPrint 广播
ssh @ 'avahi-browse -rt _ipp._tcp 2>&1 | grep -E "rp=|pdl="'
# 期望:看到 rp=printers/HP_LaserJet_1020、pdl=application/pdf
# 5. 端到端打印
ssh @ 'sudo docker exec cups-airprint lp -d HP_LaserJet_1020 /usr/share/cups/data/default-testpage.pdf'
# 期望:HP1020 出测试页
# 6. iOS 实测
# 备忘录 → 分享 → 打印 → 看到 "HP LaserJet 1020"
故障排查
Phase 1(OpenWrt 路由器)
症状原因解决Windows 循环打印p910nd 单向 + Windows 双向查询关「启用双向支持」(端口标签页)打印机完全无反应HP1020 固件没加载手动 cat /etc/sihp1020.dl > /dev/usb/lp0(先停 p910nd)cat: Resource busylp0 被 p910nd 独占先 /etc/init.d/p910nd stophotplug 每 N 分钟触发USB error -71(物理问题)换 USB 线、插紧、查打印机电源打印机识别不到没通电 / 线没插HP1020 独立通电,绿灯 Readyopkg update 全失败主路由 DNS 污染(OpenClash 等)从镜像站离线装
Phase 2(NAS CUPS)
症状原因解决iOS 看不到打印机avahi 没广播service 文件必须在宿主 /etc/avahi/services/(不是容器);检查防火墙放行 UDP 5353iOS 看到但打不出CUPS 配错 / socket 连不上docker logs cups-airprint;从容器内 nc -zv 9100iOS 看到但"通信失败"avahi rp= 与 CUPS 队列名不一致严格用 HP_LaserJet_1020(下划线)出乱码或卡纸HP1020 固件没加载走 Phase 1 排查第一次能打第二次卡死p910nd 单连接独占docker restart cups-airprint驱动列表没 foo2zjs容器没装docker exec cups-airprint apt update && apt install -y printer-driver-foo2zjsCUPS Web 需要密码Basic Authadmin / 你设的 CUPSADMINCUPS 日志反复打 "Poppler cannot convert to mono PS"误报,可忽略实际打印正常。详见下面"已知误报"NAS 重启后容器和镜像没了Docker daemon 被重启从 cups-airprint:deployed 镜像重新 compose up
已知误报:Poppler mono 警告
CUPS error_log 会反复出现:
W [Job N] Grayscale/monochrome printing requested for this job but Poppler is not able to convert to grayscale/monochrome PostScript.
W [Job N] Use "pdftops-renderer" option ...
这是误报,实际不影响打印。原因:cups-filters 看到 "HP LaserJet <纯数字>" 老型号会主动切到 Poppler(规避 HP 老 PS 解释器 bug),Poppler 不能输出 mono PS,但会输出 color PS,后续 foo2zjs 自己处理成黑白,链路完整。
page_log 为空也是同一个原因的副作用,无关紧要。所有"修复"(SetEnv / PPD attr / lpadmin option / mime.convs)都不需要做。通过 access_log 的 Send-Document successful-ok 行即可确认任务真的完成。
附录:架构决策记录(简版)
问题答案为什么不让 OpenWrt 路由器直接跑 CUPS?128MB RAM 跑 ghostscript 渲染 PDF 会 OOM;16MB Flash 装不下 CUPS+ghostscript+foo2zjs 全栈为什么不让 NAS 直接接 USB 打印机?物理位置限制,USB 线 ≤5m,通常 NAS 在机柜、打印机在书房为什么用 socket:// 而不是 IPP 连两层?p910nd 跑 RAW 9100,socket:// 是 RAW,天然兼容。IPP 需要 CUPS server,路由器跑不动为什么 avahi 复用宿主,不在容器里跑?anujatar/cups 镜像默认不带 avahi。复用宿主更省事为什么 iOS 不能直连路由器 :9100?iOS AirPrint 要求 IPP + mDNS,RAW 9100 iOS 根本识别不了升级 anujatar/cups 镜像后配置会丢吗?不会。./config/ 持久化 CUPS 状态,宿主 /etc/avahi/services/ 持久化 avahi
关键 IP / 端口清单(填你自己的)
主机IP端口服务OpenWrt 路由器_______22SSHOpenWrt 路由器_______9100/tcpp910nd RAW(打印数据入口)NAS_______22SSHNAS_______631/tcpCUPS IPP + Web 管理NAS_______5353/udpmDNS(AirPrint 广播)
参考资料
HP LaserJet 1020 spec(host-based):https://h10032.www1.hp.com/ctg/Manual/c00378935.pdf
foo2zjs 驱动:http://foo2zjs.lincom.com/
固件 sihp1020.dl 下载:https://github.com/inveneo/hub-linux-ubuntu/raw/master/install/overlay/usr/share/foo2zjs/firmware/sihp1020.dl
OpenWrt Wiki:https://openwrt.org/toh/start
OpenWrt p910nd 文档:https://openwrt.org/docs/guide-user/services/print_server/p910nd.server
anujatar/cups 镜像:https://github.com/anujdatar/cups-docker
CUPS AppSocket/HP JetDirect:https://www.cups.org/doc/network.html#SOCKET
Apple AirPrint 规范:https://developer.apple.com/bonjour/printing-specification/
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
