Linux 機器上有多個網卡,想要讓其中的一個程序使用 eth1 而不是默認的 網卡,不影響其他程序。
大概思路是這樣的:
1. 設置一個路由規則,將帶了 0x100 mark 的流量通過 table 123 查找路由:
ip rule add fwmark 0x100 table 123;
2. table 123 中下發一條 默認路由 路由規則,就是通過 eth1 出去:
ip route add default dev eth1 table 123 scope global pref 123
3. 然后給特定程序打標簽。
但是怎么給特定程序打標簽或者說打mark呢,這里有多中辦法。如果能夠確定程序的端口,直接通過iptables對特定端口打mark也是可以的,這里介紹一下更加通用的方法。
方法1:在應用程序中 通過SO_MARK給程序所有往外發的報文打上mark
mark = 0x100;
setsockopt(client_socket,SOL_SOCKET,SO_MARK,&ma rk,sizeof(mark) );
但是這種方法是改動代碼
方法2:通過 iptables owner 模塊 只要給進程分配一個單獨的 user 來運行就好了。
owner match options:
[!] --uid-owner userid[-userid] Match local UID
[!] --gid-owner groupid[-groupid] Match local GID
[!] --socket-exists Match if socket exists
[root@0000dede-vmxg3eslgl bin]# iptables -m owner --help
iptables -t mangle -A OUTPUT -m owner --uid-owner user-xxx -j MARK --set-mark 0x100
方法3:通過 iptables cgroup 模塊
cd /sys/fs/cgroup/net_cls
mkdir progxxx 創建一個文件夾
[root@localhost progxxx]# ll 默認就有這么多文件
total 0
-rw-r--r-- 1 root root 0 Jul 7 11:03 cgroup.clone_children
--w--w--w- 1 root root 0 Jul 7 11:03 cgroup.event_control
-rw-r--r-- 1 root root 0 Jul 7 11:04 cgroup.procs
-rw-r--r-- 1 root root 0 Jul 7 11:04 net_cls.classid
-rw-r--r-- 1 root root 0 Jul 7 11:03 net_prio.ifpriomap
-r--r--r-- 1 root root 0 Jul 7 11:03 net_prio.prioidx
-rw-r--r-- 1 root root 0 Jul 7 11:03 notify_on_release
-rw-r--r-- 1 root root 0 Jul 7 11:03 tasks
查找進程的pid,這里假設pid為15445
echo 15445 > cgroup.procs
設置一個classid 這里假設0x12345
echo 0x12345 > net_cls.classid
iptables -t mangle -I OUTPUT -m cgroup --cgroup 0x12345 -j MARK --set-mark 0x100