俗话说,常在河边走,哪有不湿鞋。自踏入家用路由与科学上网的世界,奇奇怪怪的问题从未断过。在这种高度碎片化的环境里,硬件载体、部署方式、网络拓扑的每一点差异,都可能导致截然不同的故障。
- 一、“万物皆可 OpenWrt”派
追求极致兼容与万能,只要内核存在,LuCI 界面就能带来熟悉体验。
硬路由:传统路由器设备,刷入OpenWrt。
软路由:小主机(J4125、N100)、电视盒子(N1)、树莓派(开发板)、NAS,甚至游戏机或服务器。
虚拟与容器环境:ESXi/PVE虚拟机,KVM/QEMU,LXC/Docker容器。
CPU架构:MIPS/MIPS64、x86、ARM、LoongArch64、RISC-V。
- 二、“去 OpenWrt 化”派
厌倦插件臃肿,追求性能或灵活部署。
硬路由:解锁Linux/BusyBox环境,部署 ShellCrash。或潘多拉,梅林。
Linux服务器:标准Linux/GNU发行版(如Debian),部署ShellCrash、Sing-box、Clash-meta。
安卓:Termux环境,部署上述工具。
Mac/Apple TV:Loon、Stash。
- 三、专注路由派
提供稳定路由、防火墙和流量管理。
家用路由:TPLink、AUSUS、LinkSYS、NETGEAR等
专业路由:UBNT
企业路由:Cisco,RouterOS 或 OpenBSD/FreeBSD + pf,iKuai。
注:这些系统本身不提供科学上网功能。
知道自己想要什么,就能根据场景选择合适的搭配。也许不存在最好的方案,但一定有最适合自己的方案,如何抉择全凭个人喜好,或者取决于自己所处的阶段。
本文只是记录个人遇到的一些疑难杂症和排除故障的过程,内容以命令输出和日志分析为主,如果与你预期不符,请及时止步。如果你恰好遇到了类似问题,也许能从中找到一些参考。
一、基础设施
个人使用过的设备有 N1、JDCloud AX1800 Pro、Radxa Rock5B。虽然我很清楚 x86 在使用便利性、性能和应用生态上都有明显优势。但为何还偏偏钟情于 ARM,其实自己也说不太清楚。
也许是因为 Oracle Cloud 服务器,也可能是因为 Mac Mini M4,这些设备都采用 ARM 架构,而且性能不弱。虽然未来 ARM 不会取代 x86,但它的应用场景也非常广泛——从智能家居、全屋智能,到物联网(IoT)。现在有机会多接触 ARM,并了解软件的兼容性,也并非坏事。
设备规划用途
宿主机 (Rock5B + Armbian) └─ PVE (Hypervisor) ├─ LXC 容器 │ └─ OpenWrt └─KVM / QEMU 虚拟机 (暂略)
宿主机
- Rock5B运行 Armbian 系统
- 部署以下服务(不依赖 OpenWrt):
- Samba
- qBittorrent
- Frp
- ZeroTier
- Komari
- Beszel
- ……
虚拟化管理
- 通过 PVE 平台,管理 LXC 容器 和 KVM/QEMU 虚拟机
- LXC OpenWrt,承担网络功能、路由和局域网管理
- 主要想体验 LXC 容器版 OpenWrt,暂时撤掉安装在物理设备的 OpenWrt,且不打算使用 Docker版 或 KVM/QEMU 虚拟机版 OpenWrt。
网络拓扑受限
Rock5B 网络接口说明
- 物理接口:Rock5B 自带一个 LAN 网口(enP4p65s0),原生单口不足以构成完整路由拓扑
- 单口方案:依赖 VLAN 交换机做单臂路由,可通过单线复用实现,但 WAN/LAN 共享物理口,可用带宽折半,作为备选
旁路由方案:非标准拓扑,需额外处理流量路径不对称、ICMP 重定向及 SNAT 问题,不建议采用- 实际方案:增加 USB 转 RJ45 网口(enxf8e4xxxxxxxx)作为 WAN 接口,与原生 LAN 口组成双臂拓扑,完整串联链路,无上述限制(USB 总线共享带宽,延迟及稳定性略逊于原生网口,但家用宽带场景下绰绰有余)
场景考虑
- 并不是每个人的网络环境都那么理想化
- 使用房东或物业宽带时,Rock5B 可能无法直接桥接上级光猫拨号服务
- 在没有固定宽带的场景(如 CPE 或随身 WiFi),桥接可行性有限
- 除非为 Rock5B 添加独立 4G/5G 模块
OpenWrt
- 负责局域网 DHCP 和 网关功能
- 作为透明网关处理加解密协议(需配合科学上网插件,如HomeProxy)
- 局域网终端访问互联网的数据流:
- 数据包先通过 AP 到达 OpenWrt LAN 接口
- 经过科学上网插件和防火墙规则处理
- 最后从 OpenWrt WAN 接口发出
OpenWrt 关闭科学上网插件时
- 退化为普通路由器(本案例中仅有1个WAN,1个LAN)
- LAN/WAN 提供基本路由和 NAT
- 不做任何加解密或科学上网处理
硬路由 AP(桥接模式)
- 关闭 DHCP 和 NAT
- 提供稳定的无线/有线网络
- 局域网内部数据交换(switch)直通,不绕 OpenWrt

Internet
│
┌─────────────────────────┐
│ ISP / CPE / Mobile WiFi │
└─────────────────────────┘
│
▼
┌──────────────────┐ ┌─────────────────┐
│ Rock5B WAN │ │ Rock5B LAN │
│ enxf8e4xxxxxxxx │ │ enP4p65s0 │
└──────────────────┘ └─────────────────┘
│ │
▼ ▼
vmbr1 vmbr0 ──── AP (bridge only)
│ │
▼ ▼
veth200i1@if3 veth200i0@if2
│ │
▼ ▼
eth1 WAN 192.168.0.2 eth0 LAN 192.168.1.1
│
▼
LAN Clients
二、那些奇怪的问题
1.SSRPlus插件自定义端口无效
# 运行环境
OpenWrt固件:https://t.me/openwrt_flippy/7002
OpenWrt版本:OpenWrt 24.10.3(LEDE R25.10.10) ——> Flippy R26.02.20
iptables版本:iptables v1.8.7 (legacy)
Lua版本:Lua 5.1.5
LuCI版本:LuCI Master (git-26.034.10143-64f3163)
SSRPlus版本:luci-app-ssr-plus - 190-3
Armbian版本:Armbian 25.11.2(Linux 6.12.58-current-rockchip64 )
PVE版本:pve-manager/9.0.10-2首先说明,需要自定义端口的场景
- speedtest.net测速时,连接测速服务器走的是8080端口
- 自己部署的一些服务,例如8443端口等
- 不想代理所有端口
问题:OpenWrt的SSRPlus插件自定义端口不生效,结果变成代理所有端口
分析:
1)需要代理的端口:所有端口、仅常用端口、自定义端口,共有3个选项。
# 查看 SSRPlus 在 iptables nat 表里创建的自定义链,确认是否带端口限制
iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers代理所有端口,第9条规则,REDIRECT重定向,tcp协议,destination目的地为0.0.0.0/0,所有端口都会被代理。
root@OpenWrt:~# iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers
Chain SS_SPEC_WAN_FW (4 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/8
2 0 0 RETURN all -- * * 0.0.0.0/0 10.0.0.0/8
3 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.0/8
4 0 0 RETURN all -- * * 0.0.0.0/0 169.254.0.0/16
5 0 0 RETURN all -- * * 0.0.0.0/0 172.16.0.0/12
6 0 0 RETURN all -- * * 0.0.0.0/0 192.168.0.0/16
7 0 0 RETURN all -- * * 0.0.0.0/0 224.0.0.0/4
8 0 0 RETURN all -- * * 0.0.0.0/0 240.0.0.0/4
9 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 1234代理所有端口
仅常用端口 ,即22,53,587,465,995,993,143,80,443,853,9418这些端口,指定的multiport dports。
root@OpenWrt:~# iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers
Chain SS_SPEC_WAN_FW (4 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/8
2 0 0 RETURN all -- * * 0.0.0.0/0 10.0.0.0/8
3 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.0/8
4 0 0 RETURN all -- * * 0.0.0.0/0 169.254.0.0/16
5 0 0 RETURN all -- * * 0.0.0.0/0 172.16.0.0/12
6 0 0 RETURN all -- * * 0.0.0.0/0 192.168.0.0/16
7 0 0 RETURN all -- * * 0.0.0.0/0 224.0.0.0/4
8 0 0 RETURN all -- * * 0.0.0.0/0 240.0.0.0/4
9 6 360 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 22,53,587,465,995,993,143,80,443,853,9418 redir ports 1234仅常用端口
自定义端口,我填写了22,53,587,465,995,993,143,80,443,853,9418,8080,8443,结果跟预期不符合,实际上变成了代理全部端口作为兜底。
root@OpenWrt:~# iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers
Chain SS_SPEC_WAN_FW (4 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/8
2 0 0 RETURN all -- * * 0.0.0.0/0 10.0.0.0/8
3 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.0/8
4 0 0 RETURN all -- * * 0.0.0.0/0 169.254.0.0/16
5 0 0 RETURN all -- * * 0.0.0.0/0 172.16.0.0/12
6 0 0 RETURN all -- * * 0.0.0.0/0 192.168.0.0/16
7 0 0 RETURN all -- * * 0.0.0.0/0 224.0.0.0/4
8 0 0 RETURN all -- * * 0.0.0.0/0 240.0.0.0/4
9 72 4560 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 1234自定义端口
查看 SSRPlus 日志,正常运行无异常。SSRPlus设置页面本身支持选择nftables和iptables防火墙,应用层面也有判断语句。
# 查看 SSRPlus 日志
cat /var/log/ssrplus.log
----------start------------
提示:优先使用 nftables...
警告:nftables (fw4) 应用环境不完整,切换至 iptables。(has_fw4:0/dnsmasq_nftset:0)
Main node:Xray 26.2.6 (Xray, Penetrates Everything.) OpenWrt (go1.26.0 linux/arm64) Started!
提示:优先使用 nftables...
警告:nftables (fw4) 应用环境不完整,切换至 iptables。(has_fw4:0/dnsmasq_nftset:0)
gfw2ipset: Using iptables
提示:优先使用 nftables...
警告:nftables (fw4) 应用环境不完整,切换至 iptables。(has_fw4:0/dnsmasq_nftset:0)
ssr-rules: Using iptables
提示:优先使用 nftables...
警告:nftables (fw4) 应用环境不完整,切换至 iptables。(has_fw4:0/dnsmasq_nftset:0)
Apple 域名中国大陆 CDN 的 优化规则正在加载。
Apple 域名中国大陆 CDN 的 优化规则加载完毕。
-----------end------------查看 SSRPlus 配置文件,确认8080和8443端口已成功写入。下面列出了大致的配置文件结构,由此得知custom_ports,是在global全局参数中定义的。
# 查看 SSRPlus 配置文件
cat /etc/config/shadowsocksr
——————————————————————
# 全局参数
config global
option global_server 'cfg014a8f'
option dports '3'
option custom_ports '22,53,587,465,995,993,143,80,443,853,9418,8080,8443'
_______________________
# 服务器节点列表
config servers
option local_port '1234'
option ip 'x.x.x.x'
config servers
option local_port '1234'
option ip 'x.x.x.x'
……把SSRPlus启动脚本/etc/init.d/shadowsocksr,以及在Github托管的源码,交给AI帮忙分析对比。首先定位custom_ports相关的代码。
# custom_ports 相关的代码
if [ "$(uci_get_by_type global dports)" == "3" ]; then
local custom_ports=$(uci_get_by_name $GLOBAL_SERVER custom_ports) # custom_ports 存储了用户自定义的端口
if [ -n "$custom_ports" ]; then
local proxyport="-m multiport --dports $custom_ports"
fi
else
if [ "$(uci_get_by_type global dports 1)" == "2" ]; then
local proxyport="-m multiport --dports 22,53,587,465,995,993,143,80,443,853,9418"
fi
fi
# uci_get_by_name 代码
uci_get_by_name() {
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
# uci_get_by_type 代码
uci_get_by_type() {
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
echo "${ret:=$3}"
}接着,使用uci命令再次确认SSRPlus配置。从以下结果得知,配置文件的custom_ports 存在 @global[0] 下,是全局配置。
然而,/etc/init.d/shadowsocksr启动脚本的代码,去服务器节点GLOBAL_SERVER(即当前节点cfg014a8f)读取custom_ports,所以自定义端口为空值,这就导致了代理所有端口的结果。
uci_get_by_name $GLOBAL_SERVER custom_ports,当前等价于uci get shadowsocksr.cfg014a8f.custom_ports。
# 返回3,表示第3个选项(自定义代理端口),配置正确
root@OpenWrt:~# uci show shadowsocksr | grep dports
shadowsocksr.@global[0].dports='3'
# custom_ports 变量值有效,自定义代理端口,配置正确。
root@OpenWrt:~# uci show shadowsocksr | grep custom_ports
shadowsocksr.@global[0].custom_ports='22,53,587,465,995,993,143,80,443,853,9418,8080,8443'
# GLOBAL_SERVER,是当前使用的节点ID
root@OpenWrt:~# uci get shadowsocksr.@global[0].global_server
cfg014a8f
# 查看 cfg014a8f,不存在 custom_ports 变量
root@OpenWrt:~# uci show shadowsocksr.cfg014a8f
shadowsocksr.cfg014a8f=servers
shadowsocksr.cfg014a8f.switch_enable='0'
shadowsocksr.cfg014a8f.xray_hy2_type='hysteria2'
shadowsocksr.cfg014a8f.type='v2ray'
shadowsocksr.cfg014a8f.alias='xx'
shadowsocksr.cfg014a8f.v2ray_protocol='vless'
shadowsocksr.cfg014a8f.server='xx'
shadowsocksr.cfg014a8f.server_port='443'
shadowsocksr.cfg014a8f.vmess_id='xx'
shadowsocksr.cfg014a8f.vless_encryption='none'
shadowsocksr.cfg014a8f.transport='raw'
shadowsocksr.cfg014a8f.tcp_guise='none'
shadowsocksr.cfg014a8f.reality='1'
shadowsocksr.cfg014a8f.reality_publickey='xx'
shadowsocksr.cfg014a8f.reality_shortid='xx'
shadowsocksr.cfg014a8f.tls_flow='xtls-rprx-vision'
shadowsocksr.cfg014a8f.fingerprint='chrome'
shadowsocksr.cfg014a8f.tls_host='xx'
shadowsocksr.cfg014a8f.insecure='0'
shadowsocksr.cfg014a8f.mux='0'
shadowsocksr.cfg014a8f.local_port='1234'
shadowsocksr.cfg014a8f.ip='xx'解决方法:
# 确认脚本中读取 custom_ports 的代码位置,以及完整的代码内容
# 完整匹配"uci_get_by_name $GLOBAL_SERVER custom_ports"仅出现1次,在1542行
root@OpenWrt:~# grep -n "uci_get_by_name \$GLOBAL_SERVER custom_ports" /etc/init.d/shadowsocksr
1542: local custom_ports=$(uci_get_by_name $GLOBAL_SERVER custom_ports) # custom_ports 存储了用户自定义的端口
# 手动编辑(二选一),+1542表示直接跳转到指定行(需要完整版的 vi 才能支持)
root@OpenWrt:~# vi +1542 /etc/init.d/shadowsocksr
或
root@OpenWrt:~# nano +1542 /etc/init.d/shadowsocksr
将 local custom_ports=$(uci_get_by_name $GLOBAL_SERVER custom_ports)
改为 local custom_ports=$(uci_get_by_type global custom_ports)
# 或者,直接一条命令替换
root@OpenWrt:~# sed -i 's/uci_get_by_name \$GLOBAL_SERVER custom_ports/uci_get_by_type global custom_ports/' /etc/init.d/shadowsocksr
# 重启SSRPlus插件
root@OpenWrt:~# /etc/init.d/shadowsocksr restart
# 验证自定义端口是否生效,会发现8080,8443已经加上了,大功告成
root@OpenWrt:~# iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers
Chain SS_SPEC_WAN_FW (4 references)
num pkts bytes target prot opt in out source destination
1 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/8
2 0 0 RETURN all -- * * 0.0.0.0/0 10.0.0.0/8
3 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.0/8
4 0 0 RETURN all -- * * 0.0.0.0/0 169.254.0.0/16
5 0 0 RETURN all -- * * 0.0.0.0/0 172.16.0.0/12
6 0 0 RETURN all -- * * 0.0.0.0/0 192.168.0.0/16
7 0 0 RETURN all -- * * 0.0.0.0/0 224.0.0.0/4
8 0 0 RETURN all -- * * 0.0.0.0/0 240.0.0.0/4
9 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 22,53,587,465,995,993,143,80,443,853,9418,8080,8443 redir ports 12342.Web后台的活动连接不准确
# 运行环境
OpenWrt固件:https://t.me/openwrt_flippy/7002
OpenWrt版本:OpenWrt 24.10.3(LEDE R25.10.10) ——> Flippy R26.02.20
BusyBox版本:BusyBox v1.36.1 (2026-02-15 10:01:10 UTC) built-in shell (ash)
iptables版本:iptables v1.8.7 (legacy)
Lua版本:Lua 5.1.5
LuCI版本:LuCI Master (git-26.034.10143-64f3163)
Armbian版本:Armbian 25.11.2(Linux 6.12.58-current-rockchip64 )
PVE版本:pve-manager/9.0.10-2问题:OpenWrt的Web后台(Luci界面)显示最大连接数只有4096
网络
IPv4 WAN 状态
类型: static
地址: 192.168.0.2
子网掩码: 255.255.255.0
网关: 192.168.0.1
已连接: 10h 55m 59s
活动连接 698 / 4096 (17%)
分析:
# 检查宿主机 最大连接数,正常
root@rock-5b:~# cat /proc/sys/net/netfilter/nf_conntrack_max
262144
root@OpenWrt:~# sysctl -n net.netfilter.nf_conntrack_max
262144
root@rock-5b:~# sysctl -n net.nf_conntrack_max
262144
——————————————————————————————————————————————————————————————
# 检查LXC OpenWrt 最大连接数,前两条正常,最后一条不正常
root@OpenWrt:~# cat /proc/sys/net/netfilter/nf_conntrack_max
262144
root@OpenWrt:~# sysctl -n net.netfilter.nf_conntrack_max
262144
root@OpenWrt:~# sysctl -n net.nf_conntrack_max
sysctl: error: 'net.nf_conntrack_max' is an unknown key# 查找 luci 状态页的数据来源
root@OpenWrt:~# grep -r "conntrack\|connections" /usr/lib/lua/luci/controller/ /usr/lib/lua/luci/model/ 2>/dev/null | grep -v ".pyc"
# 截取 luci 状态页 status 部分关键代码
# 发现连接数读取的是 sys.net.conntrack()
/usr/lib/lua/luci/controller/admin/status.lua: entry({"admin", "status", "realtime", "connections"}, template("admin_status/connections"), _("Connections"), 4).leaf = true
/usr/lib/lua/luci/controller/admin/status.lua: entry({"admin", "status", "realtime", "connections_status"}, call("action_connections")).leaf = true
/usr/lib/lua/luci/controller/admin/status.lua:function action_connections()
/usr/lib/lua/luci/controller/admin/status.lua: luci.http.write("{ connections: ")
/usr/lib/lua/luci/controller/admin/status.lua: luci.http.write_json(sys.net.conntrack())# 查看 conntrack 函数的实现,大范围搜索,找到相关文件和行
root@OpenWrt:~# grep -r "function conntrack\|nf_conntrack\|/proc/net" /usr/lib/lua/luci/ 2>/dev/null
# 从结果中截取 conntrack 相关的代码(当前连接数 和 最大连接数,conntrack函数)
/usr/lib/lua/luci/view/admin_status/index.htm:
fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
"sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
/usr/lib/lua/luci/sys.lua:
local ok, nfct = pcall(io.lines, "/proc/net/nf_conntrack")
# 查看 当前连接数 和 最大连接数,代码所在行
root@OpenWrt:~# grep -n "nf_conntrack_count\|nf_conntrack_max" /usr/lib/lua/luci/view/admin_status/index.htm
43: fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
46: "sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
# 显示第42-47行的代码,得知最大连接数读取失败时,默认值为4096
root@OpenWrt:~# sed -n '42,47p' /usr/lib/lua/luci/view/admin_status/index.htm
local conn_count = tonumber(
fs.readfile("/proc/sys/net/netfilter/nf_conntrack_count") or "") or 0
local conn_max = tonumber(luci.sys.exec(
"sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
):match("%d+")) or 4096
结论和解决方法:
首先,sysctl -n net.netfilter.nf_conntrack_max 和 cat /proc/sys/net/netfilter/nf_conntrack_max 是等价的,LXC OpenWrt输出结果正常。
其次,LXC OpenWrt 运行 sysctl -n net.nf_conntrack_max,报错unknown key。该命令,其实等价于cat /proc/sys/net/nf_conntrack_max。BusyBox的sysctl读取时,会去/proc/sys/下,按key路径查找,把net.nf_conntrack_max 转换成 /proc/sys/net/nf_conntrack_max。
OpenWrt Luci的index.htm里,用的是net.nf_conntrack_max(少了netfilter这一级目录),在BusyBox环境下,就是个错误的key,所以读不到值,回退显示默认4096。这是Luci针对BusyBox sysctl的一个适配bug。
# 确认 nf_conntrack_max 所在行
root@OpenWrt:~# grep -n "nf_conntrack_max" /usr/lib/lua/luci/view/admin_status/index.htm
46: "sysctl -n -e net.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"
# 直接替换(将 net.nf_conntrack_max 替换为 net.netfilter.nf_conntrack_max)
root@OpenWrt:~# sed -i 's/sysctl -n -e net.nf_conntrack_max/sysctl -n -e net.netfilter.nf_conntrack_max/' \
/usr/lib/lua/luci/view/admin_status/index.htm
# 确认替换成功
root@OpenWrt:~# grep -n "nf_conntrack_max" /usr/lib/lua/luci/view/admin_status/index.htm
46: "sysctl -n -e net.netfilter.nf_conntrack_max net.ipv4.netfilter.ip_conntrack_max"3.宿主机升级导致OpenWrt废了
# 运行环境
OpenWrt固件:https://t.me/openwrt_flippy/7002
OpenWrt版本:OpenWrt 24.10.3(LEDE R25.10.10) ——> Flippy R26.02.20
Armbian版本(前):Armbian 25.11.2(Linux 6.12.58-current-rockchip64 )
Armbian版本(后):Armbian 26.2.1 trixie (Linux 6.18.10-current-rockchip64)
PVE版本:pve-manager/9.0.10-2问题:宿主机升级导致OpenWrt出现异常
宿主机主要变化,Linux内核版本6.12.x—>6.18.x,升级后移除了 ip_tables.ko 模块,导致依赖 iptables 的 OpenWrt 插件和防火墙规则失效。
现象:
- OpenWrt 容器自身:DNS 解析、ping、curl 国内/国外网站均正常
- 局域网终端连接 OpenWrt 作为网关:DNS 解析正常,但无法 ping,无法访问国内/国外网站
原因:
- DNS 解析由 OpenWrt 本机的 dnsmasq 直接响应,不经过 iptables FORWARD 链,所以正常
- 终端访问外网需要经过 iptables FORWARD 链转发和 NAT 规则,ip_tables.ko 缺失后规则无法加载,数据包被丢弃
# 宿主机已经没有 ip_tables.ko 模块
root@rock-5b:~# find /lib/modules/$(uname -r) -name "ip_tables.ko"
# 虽然内核编译了 ip_tables.ko 模块,但打包内核的时候丢弃了
# 可能是 Armbian 官方有意推动用户迁移到 nftables 方案
root@rock-5b:~# grep "CONFIG_IP_NF_IPTABLES" /boot/config-6.18.10-current-rockchip64
CONFIG_IP_NF_IPTABLES=m# OpenWrt 运行 iptables 命令异常
root@OpenWrt:~# iptables
Error loading shared library libiptext.so: No such file or directory (needed by /usr/sbin/iptables)
Error loading shared library libiptext4.so: No such file or directory (needed by /usr/sbin/iptables)
Error relocating /usr/sbin/iptables: xtables_announce_chain: symbol not found
Error relocating /usr/sbin/iptables: xtables_strdup: symbol not found
Error relocating /usr/sbin/iptables: init_extensions: symbol not found
Error relocating /usr/sbin/iptables: xl_xlate_set_family: symbol not found
Error relocating /usr/sbin/iptables: init_extensions4: symbol not found
Error relocating /usr/sbin/iptables: xt_xlate_set_get: symbol not found
root@OpenWrt:~# iptables -t nat -L SS_SPEC_WAN_FW -v -n --line-numbers
Error loading shared library libiptext.so: No such file or directory (needed by /usr/sbin/iptables)
Error loading shared library libiptext4.so: No such file or directory (needed by /usr/sbin/iptables)
Error relocating /usr/sbin/iptables: xtables_announce_chain: symbol not found
Error relocating /usr/sbin/iptables: xtables_strdup: symbol not found
Error relocating /usr/sbin/iptables: init_extensions: symbol not found
Error relocating /usr/sbin/iptables: xl_xlate_set_family: symbol not found
Error relocating /usr/sbin/iptables: init_extensions4: symbol not found
Error relocating /usr/sbin/iptables: xt_xlate_set_get: symbol not found三种解决方案:
1. 自行编译,在当前宿主机上单独编译缺失的模块(ip_tables.ko)并手动部署,但每次内核更新都需要重新编译,狗看了都摇头,不推荐。
2. 降级内核,通过 armbian-config 将内核降级到 v6.12.58,该版本包含完整的 iptables 模块,操作简单,保命要紧,苟住,我们能赢。
3. 迁移到nftables,重建 OpenWrt 容器,改用 nftables 替代 iptables,从根本上解决问题,永绝后患,一劳永逸,推荐。
# armbian-config 非常轻松切换内核
Select kernel
linux-image-current-rockchip64=25.11.2 v6.12.58
linux-image-current-rockchip64=25.8.2 v6.12.57
linux-image-current-rockchip64=25.8.1 v6.12.44
linux-image-current-rockchip64=25.5.2 v6.12.38
linux-image-vendor-rk35xx=26.2.1 v6.1.115
linux-image-vendor-rk35xx=25.8.2 v6.1.115
linux-image-vendor-rk35xx=25.8.1 v6.1.115
linux-image-vendor-rk35xx=25.5.1 v6.1.115
< OK > <Cancel>其实,也早就听闻 OpenWrt 的版本变动:iptables(fw3)升级为 nftables(fw4)、.ipk升级为 .apk、Lua 升级为 ucode。只是一直懒得折腾,能用就不动。直到这次宿主机内核升级,ip_tables.ko模块缺失,被迫迁移到 nftables 方案,反而把一直拖着的历史债务一并还清了。
LXC OpenWrt固件的选择
# ImmortalWrt(推荐)
https://downloads.immortalwrt.org
https://downloads.immortalwrt.org/releases/24.10.5/targets/armsr/armv8/
拥有较高的知名度,社区代码贡献,初始安装包体积小,想要什么插件就自行安装,方便灵活,中文友好。主要针对硬路由而设计,固件精简度非常高。# OpenWrt 官方
https://downloads.openwrt.org
https://downloads.openwrt.org/releases/24.10.6/targets/armsr/armv8/
https://downloads.openwrt.org/releases/25.12.1/targets/armsr/armv8/
# LXC 官方
https://images.linuxcontainers.org
https://images.linuxcontainers.org/images/openwrt/24.10/arm64/default/
https://images.linuxcontainers.org/images/openwrt/25.12/arm64/default/# ophub 预编译 rootfs(LXC OpenWrt 场景不推荐直接使用)
https://github.com/ophub/amlogic-s9xxx-openwrt/releases
固件体积大,但预装有效插件少,冗余内容主要是containerd、/lib/modules/、perl、python3、git、无线网卡驱动、vim/screen 等工具,对LXC容器无意义。
原因是ophub针对各种ARM盒子物理机安装打包,提供rootfs只是顺手,并未针对LXC场景裁剪,驱动和工具包袱原封保留。
编译配置:https://github.com/ophub/amlogic-s9xxx-openwrt/blob/main/config/immortalwrt_master/config
基于ImmortalWrt master,即SNAPSHOT开发版,不适合长期稳定使用。
该仓库支持多个上游版本,每个上游有独立的编译配置目录,如有需要,fork仓库后修改对应目录下的配置文件,自行编译适合LXC场景的精简rootfs。
https://github.com/ophub/amlogic-s9xxx-openwrt/tree/main/config4.Dnsmasq启动失败
# 运行环境
OpenWrt固件:https://downloads.immortalwrt.org/releases/24.10.5/targets/armsr/armv8/immortalwrt-24.10.5-armsr-armv8-generic-squashfs-rootfs.img.gz
OpenWrt版本:ImmortalWrt 24.10.5
BusyBox版本:BusyBox v1.36.1 (2026-02-09 09:37:22 UTC) built-in shell (ash)
Dnsmasq版本:Dnsmasq version 2.90
Armbian版本:Armbian 26.2.1 trixie(Linux 6.18.10-current-rockchip64 )
PVE版本:pve-manager/9.0.10-2问题:OpenWrt的Dnsmasq启动失败
当我满怀期待地迁移到 nftables 方案,结果第一步就碰壁——dnsmasq 启动失败,DNS 解析失效,网络完全不通。还没开始折腾科学上网插件,基础功能就先趴下了。虽然只是本机127.0.0.1:53暂时没有DNS服务器,但指定DNS服务器可以解析(例如nslookup example.com 223.5.5.5)。
分析:查进程,查日志
# 无法解析 cn.bing.com
root@OpenWrt:~# nslookup cn.bing.com
nslookup: write to '127.0.0.1': Connection refused
nslookup: write to '::1': Connection refused
;; connection timed out; no servers could be reached
# 系统中没有任何 dns 相关的进程
root@OpenWrt:~# ps | grep dns
2657 root 1348 S grep dns
# 查看 dnsmasq 编译选项,确认支持 nftset,不支持 ipset
root@OpenWrt:~# dnsmasq --version | head -3
Dnsmasq version 2.90 Copyright (c) 2000-2024 Simon Kelley
Compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP conntrack no-ipset nftset auth cryptohash DNSSEC no-ID loop-detect inotify dumpfile# 熟悉的环节又来喽,哪怕是神仙来了,也得给我查 dnsmasq 日志
# 划重点:随机数生成失败,无此目录;procd守护进程无法初始化dsamasq,陷入重启崩溃死循环
root@OpenWrt:~# logread | grep dnsmasq
user.notice dnsmasq: DNS rebinding protection is active, will discard upstream RFC1918 responses!
user.notice dnsmasq: Allowing 127.0.0.0/8 responses
daemon.crit dnsmasq[1]: failed to seed the random number generator: No such file or directory
daemon.crit dnsmasq[1]: FAILED to start up
daemon.info procd: Instance dnsmasq::cfg01411c s in a crash loop 6 crashes, 0 seconds since last crash# 检查跟随机数相关的 unrandom 和 random 设备,在LXC OpenWrt中是否存在
root@OpenWrt:~# ls -la /dev/urandom /dev/random 2>/dev/null
crw-rw-rw- 1 nobody nogroup 1, 8 Mar 25 21:12 /dev/random
crw-rw-rw- 1 nobody nogroup 1, 9 Mar 25 21:12 /dev/urandom# unrandom 和 random 字符设备明明在这里,但 dnsmasq 却说找不到
# 守护进程 procd 有一个 ujail 沙箱机制,去看一眼情况如何
root@OpenWrt:~# grep -n "jail\|urandom\|random" /etc/init.d/dnsmasq
1262: procd_add_jail dnsmasq ubus log
1263: procd_add_jail_mount $CONFIGFILE $DHCPBOGUSHOSTNAMEFILE $DHCPSCRIPT $DHCPSCRIPT_DEPENDS
1264: procd_add_jail_mount $EXTRA_MOUNT $RFC6761FILE $TRUSTANCHORSFILE
1265: procd_add_jail_mount $dnsmasqconffile $dnsmasqconfdir $resolvdir $user_dhcpscript
1266: procd_add_jail_mount /etc/passwd /etc/group /etc/TZ /etc/hosts /etc/ethers
1267: procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile
1270: procd_add_jail_mount_rw "$logfacility"
1272: [ -e "$hostsfile" ] && procd_add_jail_mount $hostsfile从启动脚本可以知道,dnsmasq 在 ujail 沙箱里运行,只挂载了明确列出的文件,而/dev/urandom 不在列表里。所以 dnsmasq 找不到它,无法初始化随机数种子,启动失败。
解决方法:
方法一,在/etc/init.d/dnsmasq启动脚本中,挂载/dev/urandom 和 /dev/random
# 查看1260-1275行的完整代码,确定在哪个位置插入
root@OpenWrt:~# grep -n "" /etc/init.d/dnsmasq | sed -n '1260,1275p'
1260: [ -n "$instance_netdev" ] && procd_set_param netdev $instance_netdev
1261:
1262: procd_add_jail dnsmasq ubus log
1263: procd_add_jail_mount $CONFIGFILE $DHCPBOGUSHOSTNAMEFILE $DHCPSCRIPT $DHCPSCRIPT_DEPENDS
1264: procd_add_jail_mount $EXTRA_MOUNT $RFC6761FILE $TRUSTANCHORSFILE
1265: procd_add_jail_mount $dnsmasqconffile $dnsmasqconfdir $resolvdir $user_dhcpscript
1266: procd_add_jail_mount /etc/passwd /etc/group /etc/TZ /etc/hosts /etc/ethers
1267: procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile
1268: case "$logfacility" in */*)
1269: [ ! -e "$logfacility" ] && touch "$logfacility"
1270: procd_add_jail_mount_rw "$logfacility"
1271: esac
1272: [ -e "$hostsfile" ] && procd_add_jail_mount $hostsfile
1273:
1274: procd_close_instance
1275:# 在第1272行之后,追加一行代码,挂载 urandom 和 random
# 确保在 procd_close_instance 结束前即可
root@OpenWrt:~# sed -i '1272a\\tprocd_add_jail_mount /dev/urandom /dev/random' /etc/init.d/dnsmasq
# 重启 dnsmasq
root@OpenWrt:~# /etc/init.d/dnsmasq restart
# 查看dnsmasq 运行状态,输出 running 表示正常运行
root@OpenWrt:~# /etc/init.d/dnsmasq status
running方法二:直接禁用 ujail,不让 dnsmasq 进入沙箱
# 找到 procd_add_jail 所在行,可以手动编辑加注释
root@OpenWrt:~# grep -n "procd_add_jail dnsmasq" /etc/init.d/dnsmasq
1262: procd_add_jail dnsmasq ubus log
# 用 ':' 注释(shell 解析执行了 : 这个命令,只是什么结果都没产生)
sed -i 's/\tprocd_add_jail dnsmasq/\t: procd_add_jail dnsmasq/' /etc/init.d/dnsmasq
# 或者,用 '#' 注释(shell 解析时直接跳过这一行,根本不执行)
sed -i 's/\tprocd_add_jail dnsmasq/\t#procd_add_jail dnsmasq/' /etc/init.d/dnsmasq
# 重启 dnsmasq
root@OpenWrt:~# /etc/init.d/dnsmasq restart
# 查看dnsmasq 运行状态,输出 running 表示正常运行
root@OpenWrt:~# /etc/init.d/dnsmasq status
running方法三:将 非特权容器 改为 特权容器
# 在宿主机上修改容器配置,以容器ID 200 为例,请根据自己的具体情况修改
# 将 unprivileged: 1 改为 unprivileged: 0
root@rock-5b:~# nano /etc/pve/lxc/200.conf总结,宿主机 ——> 非特权容器OpenWrt ——> 进程dnsmasq,形成了双重隔离。
对于dnsmasq的启动脚本/etc/init.d/dnsmasq:
- ImmortalWrt提供的rootfs固件,默认未注释jail;
- OpenWrt官方和LXC官方提供的rootfs固件,默认注释了jail,在非特权容器环境下避免了双重隔离。
5.HomeProxy无法启动
# 运行环境
OpenWrt固件:https://downloads.immortalwrt.org/releases/24.10.5/targets/armsr/armv8/immortalwrt-24.10.5-armsr-armv8-generic-squashfs-rootfs.img.gz
OpenWrt版本:ImmortalWrt 24.10.5
BusyBox版本:BusyBox v1.36.1 (2026-02-09 09:37:22 UTC) built-in shell (ash)
HomeProxy版本:luci-app-homeproxy - 25.318.35044~0706fa8
Sing-box版本:sing-box - 1.12.17-r1
Armbian版本:Armbian 26.2.1 trixie(Linux 6.18.10-current-rockchip64 )
PVE版本:pve-manager/9.0.10-2在OpenWrt中安装完HomeProxy后,也添加了节点,最后显示HomeProxy (sing-box v1.12.17) 未运行。
错误的排查方向:
因为以前早就遇到过 ZeroTier 因 /dev/net/tun 缺失映射,导致启动失败的经历。虽然HomeProxy代理模式,选的是 Redirect TCP + TProxy UDP,并未开启 tun 模式。而且homeproxy Web界面下方也有提示,但我还是往错误的路上走了。
要启用 Tun 支持,您需要安装透传/映射 tun 目录ip-full和kmod-tun
# homeproxy 开启 tun 模式,需要 /dev/net/tun
root@OpenWrt:~# ls -lh /dev/net/tun
ls: /dev/net/tun: No such file or directory
# 宿主机 映射 /dev/net/tun 给 OpenWrt,以容器ID 200 为例,添加两行代码
root@rock-5b:~# nano /etc/pve/lxc/200.conf
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
# 在宿主机运行命令,重启容器,以容器ID 200 为例
root@rock-5b:~# pct reboot 200
# OpenWrt 已经映射了 /dev/net/tun,结果还是一样的报错
root@OpenWrt:~# ls -lh /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Mar 25 21:12 /dev/net/tun正确的排查方向:查看日志
# 查看 homeproxy 日志
root@OpenWrt:~# logread | grep homeproxy
daemon.info procd: Instance homeproxy::sing-box-c s in a crash loop 6 crashes, 0 seconds since last crash
# 查看 sing-box 日志,ujail 在 LXC 非特权容器里无法挂载 /proc
root@OpenWrt:~# logread | grep sing-box
daemon.err sing-box[6788]: jail: failed to mount proc /tmp/ujail-eCcOCp/proc: Operation not permitted
daemon.err sing-box[6788]: jail: mount_all() failed
daemon.err sing-box[6788]: jail: failed to build jail fs
# 查看 homeproxy 脚本中的 procd_add_jail 相关的代码
root@OpenWrt:~# grep -n "procd_add_jail" /etc/init.d/homeproxy
156: procd_add_jail "sing-box-c" log procfs
157: procd_add_jail_mount "$RUN_DIR/sing-box-c.json"
158: procd_add_jail_mount_rw "$RUN_DIR/sing-box-c.log"
159: [ "$routing_mode" != "bypass_mainland_china" ] || procd_add_jail_mount_rw "$RUN_DIR/cache.db"
160: procd_add_jail_mount "$HP_DIR/certs/"
161: procd_add_jail_mount "/etc/ssl/"
162: procd_add_jail_mount "/etc/localtime"
163: procd_add_jail_mount "/etc/TZ"
200: procd_add_jail "sing-box-s" log procfs
201: procd_add_jail_mount "$RUN_DIR/sing-box-s.json"
202: procd_add_jail_mount_rw "$RUN_DIR/sing-box-s.log"
203: procd_add_jail_mount_rw "$HP_DIR/certs/"
204: procd_add_jail_mount "/etc/acme/"
205: procd_add_jail_mount "/etc/ssl/"
206: procd_add_jail_mount "/etc/localtime"
207: procd_add_jail_mount "/etc/TZ"# 查看完整的代码行(匹配 procd_add_jail 行的上下各5行)
root@OpenWrt:~# grep -nC 5 "procd_add_jail" /etc/init.d/homeproxy
151-
152- # QUIC-GO GSO is broken on kernel 6.6 currently
153- uname -r | grep -Eq "^6\.6" && procd_set_param env "QUIC_GO_DISABLE_GSO"="true"
154-
155- if [ -x "/sbin/ujail" ] && [ "$routing_mode" != "custom" ] && ! grep -Eq '"type": "(wireguard|tun)"' "$RUN_DIR/sing-box-c.json"; then
156: procd_add_jail "sing-box-c" log procfs
157: procd_add_jail_mount "$RUN_DIR/sing-box-c.json"
158: procd_add_jail_mount_rw "$RUN_DIR/sing-box-c.log"
159: [ "$routing_mode" != "bypass_mainland_china" ] || procd_add_jail_mount_rw "$RUN_DIR/cache.db"
160: procd_add_jail_mount "$HP_DIR/certs/"
161: procd_add_jail_mount "/etc/ssl/"
162: procd_add_jail_mount "/etc/localtime"
163: procd_add_jail_mount "/etc/TZ"
164- procd_set_param capabilities "/etc/capabilities/homeproxy.json"
165- procd_set_param no_new_privs 1
166- procd_set_param user sing-box
167- procd_set_param group sing-box
168- fi
--
195-
196- # QUIC-GO GSO is broken on kernel 6.6 currently
197- uname -r | grep -Eq "^6\.6" && procd_set_param env "QUIC_GO_DISABLE_GSO"="true"
198-
199- if [ -x "/sbin/ujail" ]; then
200: procd_add_jail "sing-box-s" log procfs
201: procd_add_jail_mount "$RUN_DIR/sing-box-s.json"
202: procd_add_jail_mount_rw "$RUN_DIR/sing-box-s.log"
203: procd_add_jail_mount_rw "$HP_DIR/certs/"
204: procd_add_jail_mount "/etc/acme/"
205: procd_add_jail_mount "/etc/ssl/"
206: procd_add_jail_mount "/etc/localtime"
207: procd_add_jail_mount "/etc/TZ"
208- procd_set_param capabilities "/etc/capabilities/homeproxy.json"
209- procd_set_param no_new_privs 1
210- procd_set_param user sing-box
211- procd_set_param group sing-box
212- fi# sing-box 客户端,当这3个条件都满足时,sing-box 会进入沙箱运行
155- if [ -x "/sbin/ujail" ] && [ "$routing_mode" != "custom" ] && ! grep -Eq '"type": "(wireguard|tun)"' "$RUN_DIR/sing-box-c.json"; then
156: procd_add_jail "sing-box-c" log procfs
# sing-box 服务端,当满足1个条件时,sing-box 会进入沙箱运行
199- if [ -x "/sbin/ujail" ]; then
200: procd_add_jail "sing-box-s" log procfs
# 条件1:ujail 是否存在且可执行。满足条件
root@OpenWrt:~# ls -lah /sbin/ujail
-rwxr-xr-x 1 root root 129.1K Feb 9 17:37 /sbin/ujail
# 条件2:当前路由模式是否为 custom。满足条件
root@OpenWrt:~# uci get homeproxy.config.routing_mode
bypass_mainland_china
# 条件3:配置文件里是否有 wireguard 或 tun 类型。满足条件
root@OpenWrt:~# cat /var/run/homeproxy/sing-box-c.json | grep -E '"type": "(wireguard|tun)"'
# 注意:homeproxy 启动失败,配置文件可能还没生成,验证是否存在
root@OpenWrt:~# ls -lh /var/run/homeproxy/sing-box-c.json
-rw-r--r-- 1 sing-box sing-box 3.4K Mar 26 20:10 /var/run/homeproxy/sing-box-c.json三个条件同时满足,sing-box-c 进入 ujail 沙箱,结合日志无法挂载proc。终于确认ujail 在 LXC 非特权容器里尝试挂载 /proc 被拒绝,jail 文件系统构建失败,sing-box-c 无法启动。(sing-box-s 服务端的条件更简单,只要 /sbin/ujail 存在就会进入沙箱)
方法一:代码更改为 if false; then,让条件永远不成立,then 和 fi 之间的代码块,永远不会执行。从而避免 sing-box 进入沙箱。
# 先确认实际行号(虽然在前面的步骤,也已经得知行号)
root@OpenWrt:~# grep -n 'if \[ -x "/sbin/ujail" \]' /etc/init.d/homeproxy
155: if [ -x "/sbin/ujail" ] && [ "$routing_mode" != "custom" ] && ! grep -Eq '"type": "(wireguard|tun)"' "$RUN_DIR/sing-box-c.json"; then
199: if [ -x "/sbin/ujail" ]; then
# 手动编辑,+155 表示直接跳转到指定行(需要完整版的 vi 才能支持)
# 用 '#' 注释原始条件,新增 if false; then
vi +155 /etc/init.d/homeproxy
或
nano +155 /etc/init.d/homeproxy
# 修改效果
# sing-box 客户端
#if [ -x "/sbin/ujail" ] && [ "$routing_mode" != "custom" ] && ! grep -Eq '"type": "(wireguard|tun)"' "$RUN_DIR/sing-box-c.json"; then
if false; then
# sing-box 服务端,虽未使用,但预防性修复
#if [ -x "/sbin/ujail" ]; then
if false; then
# 重启 sing-box
root@OpenWrt:~# /etc/init.d/homeproxy restart
# 查看 sing-box 运行状态
root@OpenWrt:~# /etc/init.d/homeproxy status
running方法二:跟前面的dnsmasq一样,直接注释 procd_add_jail,实际上不可行。因为,只注释 procd_add_jail,if 条件仍然成立,代码块里的 procd_set_param 依然执行。(除非把 procd_set_param 的4行代码,也一起注释掉)
# sing-box 客户端 和 服务端
#if xx, then,代码块
procd_set_param capabilities "/etc/capabilities/homeproxy.json"
procd_set_param no_new_privs 1
procd_set_param user sing-box
procd_set_param group sing-box
# 分别表示
按 capabilities 配置精细授权
以低权限用户运行
低权限用户组
禁止提权(子进程不能获得比父进程更高的权限)方法三:将 非特权容器 改为 特权容器。
# 在宿主机上修改容器配置,以容器ID 200 为例,请根据自己的具体情况修改
# 将 unprivileged: 1 改为 unprivileged: 0
root@rock-5b:~# nano /etc/pve/lxc/200.confHomeProxy的Tun模式
路由模式:GFWList,大陆白名单,仅代理中国大陆,自定义路由,全局。
大陆白名单(绕过中国大陆)
国内流量:数据包在内核态被 nftables 直接放行。
海外流量:数据包在内核态被 nftables 规则拦截,重定向到 sing-box 监听的本地端口
nftables 防火墙规则动作:
accept — 直接放行
redirect — 重定向到本机端口
tproxy — 透明代理到本机进程
drop — 丢弃
reject — 拒绝并回应
———————————————————————————————————————————————————————————————————————
代理模式:Redirect TCP,Redirect TCP + TProxy UDP,Redirect TCP + Tun UDP,Tun TCP/UDP。
Redirect:重定向
Redirect 只能处理 TCP(而 UDP 需要 TProxy)
优点,性能最优;缺点,只支持 TCP。
—— 小轿车,专门载客,速度快
TProxy:
支持 TCP 和 UDP,比 Redirect 支持更多协议
不需要经过虚拟网卡,比 Tun 开销小
—— 面包车,既能载客,也能载人,速度差不多
Tun:隧道/管道,虚拟网卡
Tun 能处理所有协议,包括 TCP、UDP、ICMP、GRE 等。
优点,支持全协议;缺点,性能开销大。
数据包 ——> 物理网卡(内核) ——> nftables 路由到 Tun 虚拟网卡(内核)
——> sing-box 读取(用户态) ——> 处理后写回 Tun(内核)→ 出站。
—— 轮船,渡轮啥都能装,但上下船慢代理模式:Redirect TCP,Redirect TCP + TProxy UDP,默认仅有这2个选项,因为还没安装所需的软件包(ip-full 和 kmod-tun),所以不能使用 Tun。
# HomeProxy 的 Web 后台页面显示
# 要启用 Tun 支持,您需要安装 ip-full 和 kmod-tun
# 安装所需的软件包
root@OpenWrt:~# opkg install ip-full kmod-tun
Installing ip-full (6.11.0-r1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/24.10.5/packages/aarch64_generic/base/ip-full_6.11.0-r1_aarch64_generic.ipk
Installing zlib (1.3.1-r1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/24.10.5/packages/aarch64_generic/base/zlib_1.3.1-r1_aarch64_generic.ipk
Installing libelf1 (0.192-r1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/24.10.5/packages/aarch64_generic/base/libelf1_0.192-r1_aarch64_generic.ipk
Installing libbpf1 (1.5.0-r1) to root...
Downloading https://mirrors.vsean.net/openwrt/releases/24.10.5/packages/aarch64_generic/base/libbpf1_1.5.0-r1_aarch64_generic.ipk
Package kmod-tun (6.6.122-r1) installed in root is up to date.
Configuring zlib.
Configuring libelf1.
Configuring libbpf1.
Configuring ip-full.此时,在 OpenWrt Web 后台,HomeProxy 设置中,代理模式出现了多个选项,当选择 Redirect TCP + Tun UDP 或 Tun TCP/UDP,并保存应用。结果再次提示 HomeProxy (sing-box v1.12.17) 未运行。
# sing-box 日志显示 tun 接口错误
root@OpenWrt:~# logread | grep sing-box
daemon.err sing-box[12151]: FATAL[0000] start service: start inbound/tun[tun-in]: configure tun interface: no such file or directory
daemon.info procd: Instance homeproxy::sing-box-c s in a crash loop 6 crashes, 0 seconds since last crash
# OpenWrt 内检查是否存在 /dev/net/tun
root@OpenWrt:~# ls -lh /dev/net/tun
ls: /dev/net/tun: No such file or directory如果之前没有将宿主机的/dev/net/tun,映射到LXC OpenWrt的话,此时就会出现这个错误。步骤参照前面的 映射 Tun 目录。(这个在非特权容器内,经常会遇到,例如ZeroTier)
还可以参考:https://pve.proxmox.com/wiki/OpenVPN_in_LXC
# 宿主机上,其实默认权限为 666,所有用户都可以读写,已经有权限访问
root@rock-5b:~# ls -lh /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Mar 25 13:12 /dev/net/tun
# 而proxmox文档中,将宿主机的权限改为 100000:100000,只是更为保险而已
root@rock-5b:~# chown 100000:100000 /dev/net/tun
root@rock-5b:~# ls -l /dev/net/tun
crw-rw-rw- 1 100000 100000 10, 200 Mar 25 13:12 /dev/net/tun
# 宿主机,如果提示 只读权限无法修改
root@rock-5b:~# chown 100000:100000 /dev/net/tun
chown: changing ownership of '/dev/net/tun': Read-only file system
# 宿主机,重新挂载 mount -o remount,rw /dev 即可,再去改权限
root@rock-5b:~# mount -o remount,rw /dev
root@rock-5b:~# chown 100000:100000 /dev/net/tun
————————————————————————————————————————————————————————
# 非特权容器(宿主机改权限前)
root@OpenWrt:~# ls -lh /dev/net/tun
crw-rw-rw- 1 nobody nogroup 10, 200 Mar 25 21:12 /dev/net/tun
# 非特权容器(宿主机改权限后)
root@OpenWrt:~# ls -lh /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Mar 25 21:12 /dev/net/tun
# 特权容器(宿主机改权限前)
root@OpenWrt:~# ls -lh /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Mar 25 21:12 /dev/net/tun
# 特权容器(宿主机改权限后)
root@OpenWrt:~# ls -lh /dev/net/tun
crw-rw-rw- 1 100000 100000 10, 200 Mar 25 21:12 /dev/net/tunTun虚拟网卡,虽然理论上支持所有协议,但HomeProxy默认只代理TCP和UDP,不代理ICMP协议,主要是因为没必要吧。通过以下测试,发现ICMP数据包都是发往eth0网卡,而非singtun0网卡,从而得到验证。
# OpenWrt 更新软件源,并安装 tcpdump
root@OpenWrt:~# opkg update
root@OpenWrt:~# opkg install tcpdump
# 在 OpenWrt 上,分别监听不同网卡的流量
# 局域网设备,把网关设为 OpenWrt,然后发出 ping 包
root@OpenWrt:~# tcpdump -i singtun0 icmp
root@OpenWrt:~# tcpdump -i eth0 icmp
IP 192.168.1.20 > Host-By.DMIT.com: ICMP echo request, id 33929, seq 9, length 64
IP Host-By.DMIT.com > 192.168.1.20: ICMP echo reply, id 33929, seq 9, length 64
6.ZeroTier接口信息为空
原因也都一样,ZeroTier组网需要隧道/虚拟网卡来实现。只需要将宿主机的 /dev/net/tun,映射到非特权容器内即可。或者将 非特权容器,改为特权容器,在此不做过多赘述。
7.LXC特权容器切换非特权容器报错
# 运行环境
OpenWrt固件:https://t.me/openwrt_flippy/7002
OpenWrt版本:OpenWrt 24.10.3(LEDE R25.10.10) ——> Flippy R26.02.20
Armbian版本:Armbian 25.11.2(Linux 6.12.58-current-rockchip64 )
PVE版本:pve-manager/9.0.10-2当时为了排查 ZeroTier 异常的问题,怀疑是非特权容器权限不足导致,所以切换为特权容器验证。最后,从特权容器切换为非特权容器,出现了错误。
问题:OpenWrt Web管理后台,这几个地方报错,“由于以下错误,配置文件无法被加载: uci: I/O error”
- 网络/接口
- 网络/DHCP/DNS
- 网络/主机名
- 只能上国内网站,而国外网站无法访问(科学上网失效)。
原因:
非特权容器——>宿主机中,映射的用户为 100000:100000
特权容器——>宿主机中,映射的用户为 root:root
从以下输出结果得知,特权容器的部分配置文件是 root:root 权限,切换为 非特权容器后,无权访问导致的。
root@rock-5b:# ls -lh /var/lib/lxc/200/rootfs/etc/config/
total 404K
-rw------- 1 100000 100000 991 Feb 19 10:20 acme
-rwxrwxr-x 1 root root 414 Mar 23 15:07 AdGuardHome
-rw-rw-r-- 1 100000 100000 658 Mar 23 13:07 amlogic
-rw------- 1 100000 100000 851 Feb 19 10:20 aria2
-rw-r--r-- 1 100000 100000 0 Mar 23 13:07 arpbind
-rw-rw-r-- 1 100000 100000 1.4K Feb 19 10:20 atcmds.user
-rw-rw-r-- 1 100000 100000 86 Feb 19 10:20 autoreboot
-rw-r--r-- 1 100000 100000 178 Feb 19 10:20 autossh
-rw------- 1 100000 100000 933 Feb 19 10:20 ddns
-rw------- 1 100000 100000 240 Feb 19 10:20 ddns-go
-rw------- 1 root root 1.1K Mar 23 15:07 dhcp
-rw------- 1 100000 100000 861 Feb 19 10:20 dnsproxy
-rw------- 1 100000 100000 377 Mar 23 13:07 dockerd
-rw-r--r-- 1 100000 100000 861 Feb 19 10:20 etherwake
-rw-rw-r-- 1 100000 100000 110 Feb 19 10:20 filebrowser
-rw------- 1 root root 6.0K Mar 23 15:04 firewall
-rw-rw-r-- 1 100000 100000 400 Feb 19 10:20 frp
-rw------- 1 100000 100000 331 Mar 23 13:07 frpc
-rw------- 1 100000 100000 490 Feb 19 10:20 frps
-rw-rw-r-- 1 100000 100000 208 Feb 19 10:20 frps-opkg
-rw-r--r-- 1 100000 100000 151 Mar 23 13:07 fstab
-rw------- 1 100000 100000 86 Feb 19 10:20 gost
-rw-rw-r-- 1 100000 100000 557 Feb 19 10:20 haproxy
-rw-r--r-- 1 100000 100000 129 Feb 19 10:20 hd-idle
-rw-rw-r-- 1 100000 100000 84 Feb 19 10:20 hypermodem
-rw------- 1 100000 100000 288 Feb 19 10:20 igmpproxy
-rw-rw-r-- 1 100000 100000 187 Feb 19 10:20 ipsec
-rw------- 1 100000 100000 910 Feb 19 10:20 kcptun
-rw-rw-r-- 1 100000 100000 221 Feb 19 10:20 kodexplorer
-rw-rw-r-- 1 100000 100000 1.5K Mar 23 13:08 luci
-rw-rw-r-- 1 100000 100000 112 Feb 19 10:20 lucky
-rw-rw-r-- 1 100000 100000 33 Feb 19 10:20 mia
-rw------- 1 100000 100000 336 Feb 19 10:20 microsocks
-rw------- 1 100000 100000 629 Feb 19 10:20 minidlna
-rw-rw-r-- 1 100000 100000 354 Feb 19 10:20 mjpg-streamer
-rw-rw-r-- 1 100000 100000 755 Feb 19 10:20 mosdns
-rw-rw-r-- 1 100000 100000 584 Feb 19 10:20 mwan3
-rw-rw-r-- 1 100000 100000 83 Feb 19 10:20 mwan3helper
-rw------- 1 100000 100000 541 Feb 19 10:20 n2n
-rw------- 1 100000 100000 119 Feb 19 10:20 naiveproxy
-rw------- 1 100000 100000 1.1K Mar 23 13:14 network
-rw------- 1 100000 100000 664 Feb 19 10:20 nginx
-rw------- 1 100000 100000 2.4K Feb 19 10:20 nlbwmon
-rw------- 1 100000 100000 270 Feb 19 10:20 ocserv
-rw-rw-r-- 1 100000 100000 633 Feb 19 10:20 oled
-rw-rw-r-- 1 100000 100000 6.9K Mar 23 13:07 openclash
-rw------- 1 100000 100000 755 Feb 19 10:20 openlist
-rw-r--r-- 1 100000 100000 89 Feb 19 10:20 openssl
-rw-rw-r-- 1 100000 100000 775 Feb 19 10:20 openvpn
-rw-rw-r-- 1 100000 100000 2.7K Feb 19 10:20 openvpn_recipes
-rw-r--r-- 1 100000 100000 908 Feb 19 10:20 p910nd
-rw-r--r-- 1 100000 100000 6.9K Mar 23 13:07 passwall
-rw-r--r-- 1 100000 100000 3.4K Mar 23 13:07 passwall2
-rw-rw-r-- 1 100000 100000 44 Feb 19 10:20 passwall2_server
-rw-rw-r-- 1 100000 100000 44 Feb 19 10:20 passwall_server
-rw-rw-r-- 1 100000 100000 25 Feb 19 10:20 phonebook.user
-rw-r--r-- 1 100000 100000 58 Feb 19 10:20 php8-fastcgi
-rw-r--r-- 1 100000 100000 34 Feb 19 10:20 php8-fpm
-rw-rw-r-- 1 100000 100000 86 Feb 19 10:20 pppwn
-rw-rw-r-- 1 100000 100000 236 Feb 19 10:20 pptpd
-rw-rw-r-- 1 100000 100000 104 Feb 19 10:20 qbittorrent
-rw-rw-r-- 1 100000 100000 1.5K Feb 19 10:20 qos
-rw-r--r-- 1 100000 100000 264 Feb 19 10:20 radius
-rw------- 1 100000 100000 350 Feb 19 10:20 rclone
-rw------- 1 100000 100000 167 Feb 19 10:20 rpcd
-rw------- 1 100000 100000 206 Mar 23 13:07 samba4
-rw-rw-r-- 1 100000 100000 246 Feb 19 10:20 serverchan
-rw-r--r-- 1 100000 100000 3.6K Mar 23 13:19 shadowsocksr
-rw-r--r-- 1 100000 100000 16 Mar 23 13:16 shadowsocksr_redirect
-rw------- 1 100000 100000 218 Feb 19 10:20 shairplay
-rw-rw-r-- 1 100000 100000 328 Feb 19 10:20 shairport-sync
-rw------- 1 root root 173 Mar 23 15:07 smartdns
-rw-rw-r-- 1 100000 100000 340 Feb 19 10:20 sms_tool
-rw-r--r-- 1 100000 100000 2.6K Feb 19 10:20 snmpd
-rw-rw-r-- 1 100000 100000 37 Feb 19 10:20 softethervpn
-rw-r--r-- 1 100000 100000 452 Feb 19 10:20 sqm
-rw------- 1 100000 100000 2.2K Feb 19 10:20 sshtunnel
-rw-rw-r-- 1 100000 100000 66 Feb 19 10:20 ssr_mudb_server
-rw-rw-r-- 1 100000 100000 374 Feb 19 10:20 ssr_mudb_server.json
-rw------- 1 100000 100000 433 Mar 23 13:08 system
-rw-r--r-- 1 100000 100000 256 Feb 19 10:20 tailscale
-rw------- 1 100000 100000 2.5K Feb 19 10:20 transmission
-rw------- 1 100000 100000 68 Feb 19 10:20 ttyd
-rw-rw-r-- 1 100000 100000 339 Feb 19 10:20 turboacc
-rw-rw-r-- 1 100000 100000 3.0K Mar 23 13:07 ucitrack
-rw------- 1 100000 100000 659 Feb 19 10:20 udpspeeder
-rw------- 1 100000 100000 369 Feb 19 10:20 udpxy
-rw------- 1 100000 100000 818 Mar 23 13:07 uhttpd
-rw-rw-r-- 1 100000 100000 154 Feb 19 10:20 unblockmusic
-rw------- 1 100000 100000 685 Feb 19 10:20 upnpd
-rw-rw-r-- 1 100000 100000 0 Feb 19 10:20 usb_printer
-rw-rw-r-- 1 100000 100000 176 Feb 19 10:20 ussd.user
-rw------- 1 100000 100000 52 Feb 19 10:20 uugamebooster
-rw-rw-r-- 1 100000 100000 49 Feb 19 10:20 uuplugin
-rw-rw-r-- 1 100000 100000 26 Feb 19 10:20 verysync
-rw-rw-r-- 1 100000 100000 70 Feb 19 10:20 vlmcsd
-rwxr-xr-x 1 100000 100000 959 Feb 19 10:20 vsftpd
-rw-r--r-- 1 100000 100000 627 Feb 19 10:20 wifi_schedule
drwxr-xr-x 4 100000 100000 4.0K Mar 23 15:09 zero
-rw-rw-r-- 1 100000 100000 100 Mar 23 13:26 zerotierroot@rock-5b:# ls -lh /var/lib/lxc/200/rootfs/etc/
total 696K
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 acme
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 acpi
-rw-rw-r-- 1 100000 100000 94 Feb 19 10:20 asound.conf
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 avahi
-rw-rw-r-- 1 100000 100000 372 Feb 19 10:20 banner
-rw-rw-r-- 1 100000 100000 461 Feb 19 10:20 banner.failsafe
-rw-rw-r-- 1 100000 100000 132 Feb 19 10:20 bash.bashrc
-rw-r--r-- 1 100000 100000 0 Mar 23 13:07 bench.log
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 bluetooth
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 board.d
-rw-r--r-- 1 100000 100000 207 Mar 23 13:07 board.json
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 capabilities
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 chatscripts
drwxr-xr-x 3 100000 100000 4.0K Mar 23 15:07 config
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 conntrackd
-rwxr-xr-x 1 100000 100000 317 Feb 19 10:20 coremark.sh
drwxr-xr-x 2 100000 100000 4.0K Mar 23 15:10 crontabs
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 dbus-1
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 ddns
-rw-rw-r-- 1 100000 100000 123 Feb 19 10:20 device_info
-rw-rw-r-- 1 100000 100000 948 Feb 19 10:20 diag.sh
-rw------- 1 100000 100000 1.4K Mar 23 13:07 dnsmasq.conf
-rw-r--r-- 1 100000 100000 38 Feb 19 10:20 e2fsck.conf
drwxrwxr-x 5 100000 100000 4.0K Feb 19 10:20 easy-rsa
-rw-r--r-- 1 100000 100000 97 Feb 19 10:20 environment
-rw-rw-r-- 1 100000 100000 130 Feb 19 10:20 ethers
-rw-r--r-- 1 100000 100000 1.4K Feb 19 10:20 ethertypes
-rw-r--r-- 1 100000 100000 38 Feb 19 10:20 exports
-rw------- 1 100000 100000 352 Mar 23 13:07 firewall.user
-rw-r--r-- 1 100000 100000 1.3K Feb 19 10:20 fping.conf
drwxr-xr-x 4 100000 100000 4.0K Feb 19 10:20 frp
-rw-rw-r-- 1 100000 100000 61 Feb 19 10:20 fstab
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 gcom
-rwxrwxr-x 1 100000 100000 653 Feb 19 10:20 genovpn.sh
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 gnutls
-rw-rw-r-- 1 100000 100000 503 Feb 19 10:20 group
-rw------- 1 100000 100000 2.7K Feb 19 10:20 haproxy.cfg
-rwxrwxr-x 1 100000 100000 5.2K Feb 19 10:20 haproxy_init.sh
-rwxrwxr-x 1 100000 100000 2.4K Feb 19 10:20 haproxy_start
-rw-r--r-- 1 100000 100000 46K Feb 19 10:20 health_alarm_notify.conf
-rw-rw-r-- 1 100000 100000 110 Mar 23 15:07 hosts
drwxr-xr-x 18 100000 100000 4.0K Feb 19 10:20 hotplug.d
-rw------- 1 100000 100000 1.9K Feb 19 10:20 hotplug.json
-rw------- 1 100000 100000 305 Feb 19 10:20 hotplug-preinit.json
lrwxrwxrwx 1 100000 100000 23 Mar 23 13:08 igmpproxy.conf -> /var/etc/igmpproxy.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 init.d
-rw-rw-r-- 1 100000 100000 382 Feb 19 10:20 inittab
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 iproute2
-rw------- 1 100000 100000 639 Feb 19 10:20 ipsec.conf
drwxr-xr-x 10 100000 100000 4.0K Feb 19 10:20 ipsec.d
-rwxrwxr-x 1 100000 100000 686 Feb 19 10:20 ipsec.include
-rw------- 1 100000 100000 87 Feb 19 10:20 ipsec.secrets
-rw------- 1 100000 100000 196 Feb 19 10:20 ipsec.user
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 kodexplorer
lrwxrwxrwx 1 100000 100000 14 Feb 19 10:20 localtime -> /tmp/localtime
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 luci-uploads
-rwxrwxr-x 1 100000 100000 24 Feb 19 10:20 mia.include
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 modules-boot.d
-rw-r--r-- 1 100000 100000 55 Feb 19 10:20 modules.conf
drwxr-xr-x 2 100000 100000 12K Feb 19 10:20 modules.d
drwxrwxr-x 3 100000 100000 4.0K Feb 19 10:20 mosdns
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 msd_lite
lrwxrwxrwx 1 100000 100000 12 Feb 19 10:20 mtab -> /proc/mounts
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 mwan3helper
-rw-rw-r-- 1 100000 100000 727 Feb 19 10:20 mwan3.user
-rw-r--r-- 1 100000 100000 767 Feb 19 10:20 netconfig
drwxr-xr-x 11 100000 100000 4.0K Feb 19 10:20 netdata
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 nginx
drwxr-xr-x 3 100000 100000 4.0K Mar 23 13:07 ocserv
-rw------- 1 100000 100000 75 Feb 19 10:20 odhcp6c.user
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 odhcp6c.user.d
drwxrwxr-x 11 100000 100000 4.0K Mar 23 13:07 openclash
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 openconnect
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 openvpn
-rwxrwxr-x 1 100000 100000 702 Feb 19 10:20 openvpncert.sh
-rw-r--r-- 1 100000 100000 372 Feb 19 10:20 openvpn.user
-rw-rw-r-- 1 100000 100000 197 Mar 23 13:07 openwrt_release
-rw-rw-r-- 1 100000 100000 16 Feb 19 10:20 openwrt_version
drwxr-xr-x 3 100000 100000 4.0K Mar 23 13:07 opkg
-rw-r--r-- 1 100000 100000 85 Mar 23 13:07 opkg.conf
lrwxrwxrwx 1 100000 100000 21 Feb 19 10:20 os-release -> ../usr/lib/os-release
-rw-rw-r-- 1 100000 100000 9 Feb 19 10:20 ovpnadd.conf
-rw-rw-r-- 1 100000 100000 552 Feb 19 10:20 pam.conf
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 pam.d
-rw-rw-r-- 1 100000 100000 1.1K Mar 23 13:07 passwd
-rw-rw-r-- 1 100000 100000 1.1K Feb 19 10:20 passwd-
-rw------- 1 100000 100000 777 Feb 19 10:20 pcat-manager.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 php8
-rw-r--r-- 1 100000 100000 5.1K Feb 19 10:20 php8-fpm.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 php8-fpm.d
-rw-r--r-- 1 100000 100000 2.8K Feb 19 10:20 php.ini
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 pkcs11
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 ppp
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 pppwn
-rw-r--r-- 1 100000 100000 98 Feb 19 10:20 pptpd.conf
-rwxrwxr-x 1 100000 100000 585 Feb 19 10:20 pptpd.include
-rwxrwxr-x 1 100000 100000 609 Feb 19 10:20 preinit
-rw-rw-r-- 1 100000 100000 1.1K Feb 19 10:20 profile
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 profile.d
-rw-rw-r-- 1 100000 100000 2.5K Feb 19 10:20 protocols
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 qbittorrent
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 radius
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 rc.button
-rwxrwxr-x 1 100000 100000 3.5K Feb 19 10:20 rc.common
drwxr-xr-x 2 100000 100000 4.0K Mar 23 13:08 rc.d
-rw-rw-r-- 1 100000 100000 132 Feb 19 10:20 rc.local
lrwxrwxrwx 1 100000 100000 16 Feb 19 10:20 resolv.conf -> /tmp/resolv.conf
drwxr-xr-x 2 100000 100000 4.0K Mar 23 13:07 samba
drwxr-xr-x 4 100000 100000 4.0K Feb 19 10:20 security
-rw-rw-r-- 1 100000 100000 3.1K Feb 19 10:20 services
-rw------- 1 100000 100000 669 Mar 23 13:07 shadow
-rw------- 1 100000 100000 669 Mar 23 13:07 shadow-
-rw-r--r-- 1 100000 100000 23K Feb 19 10:20 shairport-sync.conf
-rw-rw-r-- 1 100000 100000 30 Feb 19 10:20 shells
-rw-rw-r-- 1 100000 100000 475 Feb 19 10:20 shinit
drwxr-xr-x 4 100000 100000 4.0K Mar 23 15:10 smartdns
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 snmp
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 sqm
drwxr-xr-x 3 100000 100000 4.0K Mar 23 13:07 ssh
drwxr-xr-x 5 100000 100000 4.0K Feb 19 10:20 ssl
drwxrwxr-x 2 100000 100000 4.0K Mar 23 15:08 ssrplus
-rw------- 1 100000 100000 317 Feb 19 10:20 strongswan.conf
drwxr-xr-x 3 100000 100000 4.0K Feb 19 10:20 strongswan.d
-rw-rw-r-- 1 100000 100000 200 Feb 19 10:20 sysctl.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 sysctl.d
-rw-r--r-- 1 100000 100000 723 Feb 19 10:20 sysfs.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 sysfs.d
-rw-r--r-- 1 100000 100000 0 Feb 19 10:20 syslog.conf
-rw-rw-r-- 1 100000 100000 128 Feb 19 10:20 sysupgrade.conf
drwx------ 2 100000 100000 4.0K Mar 23 13:22 tailscale
-rwxr-xr-x 1 100000 100000 7.2K Feb 19 10:20 tc-qos-helper.sh
lrwxrwxrwx 1 100000 100000 7 Feb 19 10:20 TZ -> /tmp/TZ
drwxr-xr-x 2 100000 100000 12K Mar 23 13:07 uci-defaults
-rw-rw-r-- 1 100000 100000 70 Feb 19 10:20 udhcpc.user
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 udhcpc.user.d
-rw-r--r-- 1 100000 100000 535 Mar 23 13:07 uhttpd.crt
-rw------- 1 100000 100000 241 Mar 23 13:07 uhttpd.key
-rw------- 1 100000 100000 512 Mar 23 13:08 urandom.seed
-rw-r--r-- 1 100000 100000 55K Feb 19 10:20 usb-mode.json
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 vlmcsd
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 vpnc
-rw-r--r-- 1 100000 100000 681 Feb 19 10:20 xattr.conf
drwxr-xr-x 2 100000 100000 4.0K Feb 19 10:20 xl2tpd
drwxrwxr-x 2 100000 100000 4.0K Feb 19 10:20 zerotier
-rwxrwxr-x 1 100000 100000 705 Feb 19 10:20 zerotier.start
-rwxrwxr-x 1 100000 100000 494 Feb 19 10:20 zerotier.stop解决方法:
# 先停止容器(本例中容器ID是 200),在宿主机中运行命令;或在 PVE Web 关机/停止
root@rock-5b:# pct stop 200
# 查看容器挂载的目录
root@rock-5b:# echo $(pct mount 200)
mounted CT 200 in '/var/lib/lxc/200/rootfs'
# 将 /var/lib/lxc/200/rootfs/etc/ 目录权限改为 100000:100000
root@rock-5b:# chown -R 100000:100000 /var/lib/lxc/200/rootfs/etc/
# 或者,将 rootfs 整个目录改权限;-R 是递归,包括子目录及文件
# 但要注意,直接改整个 rootfs 可能有问题,某些文件和目录需要特定权限
root@rock-5b:# chown -R 100000:100000 /var/lib/lxc/200/rootfs/
root@rock-5b:# chown -R 100000:100000 /var/lib/lxc/200/rootfs/
# 卸载容器
root@rock-5b:# pct unmount 200
# 启动容器
root@rock-5b:# pct start 200写在最后
最后,感谢在 GitHub 上开源的项目,以及所有为 OpenWrt 贡献代码、适配与打包固件、制作教程的开发者和爱好者们。作为技术水平尚浅的我,虽然无法直接参与代码贡献,但深表敬意与感激,点个 Star 是我力所能及的支持。
值得一提的是,这次折腾我也请了一位“外援”——AI。在分析晦涩代码和排查故障时,它确实帮了不少忙,虽然也会一本正经地把我带偏,但不得不说,它画起图来可比我厉害多了。
我对 AI 的态度是:不排斥,也不完全信任。 把它当作辅助,确实帮我克服了不少“懒”的成分,让那些细碎的笔记能被重新梳理成逻辑。
其实很多时候,遇到问题随手记个笔记解决了也就罢了,总觉得自己技术浅显,不值得大费周章地复现、核对、排版,甚至觉得没人会在意。但后来发现,从头梳理回顾,加深了对某些概念的理解,本身就是一种逼自己思考与表达的总结。
至于有没有必要写文章分享,那是另一回事。
说实话,我技术水平一般,写文章的水平更加一般,各位看官且凑合着看吧。正好我捂脸,你捂眼睛,绝配。