Добрый день.
Как водится, появилась пара провайдеров, соответственно, следует раскидать трафик по интерфейсам.
Настроен iproute2:
# ip rule
0: from all lookup local
32756: from 1.1.1.1 lookup s
32757: from all fwmark 0x1e lookup s
32758: from 2.2.2.2 lookup b
32759: from all fwmark 0x14 lookup b
32766: from all lookup main
32767: from all lookup default
# ip route list table s
ip.addr.dns.serv1 via 1.1.1.2 dev eth0
127.0.0.0/8 via 127.0.0.1 dev lo
default via 1.1.1.2 dev eth0
# ip route list table b
ip.addr.dns.serv2 via 2.2.2.3 dev eth2
127.0.0.0/8 via 127.0.0.1 dev lo
default via 2.2.2.3 dev eth2
Маршрут по умолчанию для всей системы при этом установлен через 1.1.1.2, т.е. через интерфейс eth0.
Настраиваем icmp:
$IPT -t mangle -A OUTPUT -s $EXTIP2 -p icmp -j MARK --set-mark 0x14
$IPT -t mangle -A OUTPUT -s $EXTIP -p icmp -j MARK --set-mark 0x1e
Пробуем:
# ping -I eth0 -c 3 ya.ru
PING ya.ru (77.88.21.8) from 1.1.1.1 eth0: 56(84) bytes of data.
64 bytes from ya.ru (77.88.21.8): icmp_seq=1 ttl=52 time=16.5 ms
64 bytes from ya.ru (77.88.21.8): icmp_seq=2 ttl=52 time=16.1 ms
64 bytes from ya.ru (77.88.21.8): icmp_seq=3 ttl=52 time=16.4 ms
--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 16.181/16.381/16.557/0.186 ms
gate ~ # ping -I eth2 -c 3 ya.ru
PING ya.ru (77.88.21.8) from 2.2.2.2 eth2: 56(84) bytes of data.
64 bytes from ya.ru (77.88.21.8): icmp_seq=1 ttl=59 time=2.46 ms
64 bytes from ya.ru (77.88.21.8): icmp_seq=2 ttl=59 time=2.49 ms
64 bytes from ya.ru (77.88.21.8): icmp_seq=3 ttl=59 time=2.42 ms
--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 2.425/2.460/2.495/0.028 ms
Как видно, всё работает. Для чистоты эксперимента в таблицах временно убирались правила
from ip
Теперь, пробуем пустить исходящий трафик, скажем, от squid через интерфейс eth2. По умолчанию, как выше сказано, он бегает через eth0. Добавляем правило фаервола:
$IPT -t mangle -A OUTPUT -p tcp --dport http -j MARK --set-mark 0x14
и смотрим, куда же побежит сей трафик по логам:
Feb 18 14:28:03 gate kernel: [46051.290116] ACCEPT IN= OUT=eth0 SRC=1.1.1.1 DST=213.180.204.11 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=23141 DF PROTO=TCP SPT=45386 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 MARK=0x14
Feb 18 14:28:05 gate kernel: [46053.183161] ACCEPT IN= OUT=eth0 SRC=1.1.1.1 DST=87.250.251.60 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=15276 DF PROTO=TCP SPT=58717 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0 MARK=0x14
Если последить через tcpdump, то выясняется, что исходящий трафик бежит через eth2, но с адресом eth0:
# tcpdump -i eth2 -n 'tcp port 80'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth2, link-type EN10MB (Ethernet), capture size 68 bytes
15:04:37.727833 IP 1.1.1.1.58404 > 78.140.142.125.80: . ack 3246838659 win 501 <nop,nop,timestamp[|tcp]>
15:04:37.734168 IP 1.1.1.1.58404 > 78.140.142.125.80: . ack 2897 win 501 <nop,nop,timestamp[|tcp]>
Вопрос: как же заставить правильно работать эту связку? Ловить пакеты и менять адрес источника, и тогда, как понимаю, метить ничего не надо будет, iproute2 уже сказано, что делать с пакетами от соответствующих источников? Иных путей для решения проблемы нет?
Отмечу, что решение использовать встроенные в приложение средства для направления трафика через определённый интерфейс не совсем подходят: приложение может работать на всех интерфейсах, может не иметь подобного функционала и тд и тп. К тому же, хочется подобные вещи разруливать в одном месте.