麒麟OS中限制进程仅通过指定物理网卡出网,须在内核网络栈层面绑定流量:可用iptables+ip rule按PID打标并策略路由,或用cgroup v2+tc egress按服务长期分流,需确保模块加载、路由表唯一、tc顺序正确,并通过ss、ip rule、tcpdump验证。

麒麟OS中限制特定进程仅通过某张物理网卡出网,必须绕过应用层路由选择,直接在内核网络栈层面绑定进程流量到指定接口的出口路径,否则进程仍可能因系统默认路由、策略路由或连接跟踪而走错网卡。
用iptables + ip rule 实现进程级网卡绑定
该方法利用Linux内核的owner匹配模块与策略路由协同工作,将指定PID或进程名的出站流量强制标记并导向专用路由表,再由该表指向目标网卡。需确保系统已加载xt_owner模块且NetworkManager未覆盖自定义路由。
第一步:确认目标网卡名称及IP,执行ip -br a | grep UP,记下待绑定网卡(如ens33)及其主IP(如192.168.1.100)。
第二步:创建专用路由表,在/etc/iproute2/rt_tables末尾添加一行:200 ens33-out(数字200为自定义表ID,不可与已有表冲突)。
第三步:为该表配置默认路由,执行:sudo ip route add default via $(ip route | awk '/default.*dev ens33/ {print $3}') dev ens33 table ens33-out——【若输出为空,请先手动查出ens33所在子网的网关IP,例如192.168.1.1,再替换命令中的$()部分】。
第四步:启用策略路由规则,使标记流量查此表:sudo ip rule add fwmark 0x100 table ens33-out。
第五步:用iptables对目标进程出站包打标。先获取其PID:pidof firefox;再执行:sudo iptables -t mangle -A OUTPUT -m owner --pid-owner PID号 -j MARK --set-mark 0x100。
用cgroup v2 + tc egress filter 按进程分流(推荐用于长期服务)
当目标程序以systemd服务形式运行时,此法更稳定可靠,避免PID变动导致iptables规则失效。它将进程归入特定cgroup,再用tc在网卡出口处按cgroup classid重定向流量。
方法一:启用cgroup v2并挂载(若未启用):sudo mkdir -p /sys/fs/cgroup && sudo mount -t cgroup2 none /sys/fs/cgroup。
方法二:为程序创建专用cgroup并设置classid:sudo mkdir /sys/fs/cgroup/firefox-net && echo 0x00010001 | sudo tee /sys/fs/cgroup/firefox-net/cgroup.procs——此处0x00010001中后16位0001即classid,前16位0001表示主类号,必须与后续tc命令一致。
方法三:在目标网卡上挂载htb队列并添加classid匹配规则:sudo tc qdisc add dev ens33 root handle 1: htb default 10 → sudo tc class add dev ens33 parent 1: classid 1:1 htb rate 1000mbit → sudo tc filter add dev ens33 parent 1: protocol ip u32 match ip src 0.0.0.0/0 flowid 1:1 → sudo tc filter add dev ens33 parent 1: protocol ip u32 match ip src 0.0.0.0/0 flowid 1:1 classid 1:1 → sudo tc filter add dev ens33 parent 1: protocol ip u32 match ip src 0.0.0.0/0 flowid 1:1 classid 0x00010001。
方法三最后一行才是关键:它把classid为0x00010001的流量全部导向1:1 class,而该class已绑定至ens33出口。注意:tc命令顺序不能颠倒,class必须在filter前创建。
验证是否生效
启动目标程序后,在另一终端执行:ss -tnp | grep $(pidof firefox) | grep :443,观察本地地址是否为ens33所配IP;再执行:ip rule show | grep 0x100,确认策略规则存在;最后用curl -s https://httpbin.org/ip配合tcpdump -i ens33 port 443 -c 2抓包,若能捕获且源IP为ens33地址,则绑定成功。

















