Есть роутер, облуживающий локальную сеть, к которому подведено два канала в Интернет от разных провайдеров:
ip-mark=1
10.10.0.1
eth1 -------- gw 10.10.0.10
LAN ====== eth0 ROUTER
10.0.0.0/24 eth2 -------- gw 10.20.0.20
10.20.0.1
ip-mark=2
default gw роутера - eth2 (10.20.0.20)
Большинство пользователей пускается через канал eth1.
На машине так же стоит squid, который тоже работает через eth1.
Это реализовано через IP-Mark-и в iptables
iptables -t mangle -A OUTPUT -d !10.0.0.0/24 -m owner --uid-owner squid -j MARK --set-mark 1
iptables -A FORWARD -s 10.0.0.0/24 -d !10.0.0.1 -j MARK --set-mark 2
Далее в iproute2 все эти марки разруливаются:
ip rule ls
0: from all lookup local
10010: from 10.10.0.1 lookup channel_1
10020: from all fwmark 0x1 lookup channel_1
10030: from all fwmark 0x2 lookup channel_2
10040: from 10.10.0.1 lookup channel_1
10050: from 10.20.0.1 lookup channel_2
32766: from all lookup main
32767: from all lookup default
ip route ls table channel_1
10.10.0.10 dev eth1 scope link src 10.10.0.1
10.20.0.20 dev eth2 scope link src 10.20.0.1
10.0.0.0/24 dev eth0 scope link src 10.0.0.1
default via 10.10.0.10 dev eth1
ip route ls table channel_2
10.10.0.10 dev eth1 scope link src 10.10.0.1
10.20.0.20 dev eth2 scope link src 10.20.0.1
10.0.0.0/24 dev eth0 scope link src 10.0.0.1
default via 10.20.0.20 dev eth2
Т.е. если пакет пометили MARK=1, идем через первый канал, если MARK=2
- через второй.
Если пакет уходит с IP адреса eth1, то через первый, с IP адреса eth2
- через второй.
Все отлично работает, почти.
По какой то загадочной причине, если с ICQ серверов приходят пакеты
(к нам) c порта 20480 (мы их не заказывали, по крайней мере явно,
так как на эти (icq) подсети разрешен коннект лишь на порт 5190):
tcpdump -i eth1 -tnn port 20480
listening on eth1, link-type EN10MB (Ethernet), capture size 68 bytes
IP 64.12.163.198.20480 > 10.10.0.1.46575: F 989230390:989230390(0) ack 3759679222 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46532: F 3850546332:3850546332(0) ack 3695983447 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46350: R 2325480714:2325480714(0) ack 3423810008 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46534: F 803308875:803308875(0) ack 3697429387 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46459: F 1838867399:1838867399(0) ack 3558304478 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46582: F 2365749742:2365749742(0) ack 3762615305 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46580: F 1896503484:1896503484(0) ack 3751645506 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46584: F 919800549:919800549(0) ack 3763930573 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46586: F 818128566:818128566(0) ack 3759034461 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46587: F 878087222:878087222(0) ack 3760221868 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46644: F 625144099:625144099(0) ack 3834986459 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46621: F 1294591151:1294591151(0) ack 3788650210 win 16384
IP 64.12.163.198.20480 > 10.10.0.1.46542: F 39607421:39607421(0) ack 3708106639 win 16384
то роутер отвечает почему то не с eth1 (хотя вроде как, если не левый пакет приходит на этот интерфейс и адрес 10.10.0.1, то отвечать мы должны же с этого адреса и интерфейса?), а отвечает роутер с eth2:
tcpdump -i eth2 -tnn
listening on eth2, link-type EN10MB (Ethernet), capture size 68 bytes
IP 10.10.0.1.46620 > 64.12.163.198.20480: R 3796472795:3796472795(0) win 0
IP 10.10.0.1.46640 > 64.12.163.198.20480: R 3824027914:3824027914(0) win 0
IP 10.10.0.1.46533 > 64.12.163.198.20480: R 3687496548:3687496548(0) win 0
IP 10.10.0.1.46595 > 64.12.163.198.20480: R 3770445592:3770445592(0) win 0
IP 10.10.0.1.46578 > 64.12.163.198.20480: R 3764669375:3764669375(0) win 0
IP 10.10.0.1.46576 > 64.12.163.198.20480: R 3747630349:3747630349(0) win 0
IP 10.10.0.1.46610 > 64.12.163.198.20480: R 3784433598:3784433598(0) win 0
IP 10.10.0.1.46588 > 64.12.163.198.20480: R 3761104850:3761104850(0) win 0
IP 10.10.0.1.46659 > 64.12.163.198.20480: R 3858790926:3858790926(0) win 0
IP 10.10.0.1.46669 > 64.12.163.198.20480: R 3847494617:3847494617(0) win 0
IP 10.10.0.1.46641 > 64.12.163.198.20480: R 3825184905:3825184905(0) win 0
(в примере приведены возможно не те самые пакеты ответов,
которые ушли в ответ на запросы из первого лога tcpdump-а,
но факт именно в этом, запрос на eth1, ответ - на eth2).
Собственно, я никак не могу понять, какого %^&*($%^& ответы с 10.10.0.1(адрес принадлежит eth1), уходят с eth2?
Хотя в ip rule явно прописано другое? :(
Ядро 2.6.7, iptables 1.2.9, iproute2-2.6.7.20040608, Gentoo Linux
На ядре 2.6.8.1 и iptables 1.2.11 ситуация не меняется.
Это реализовано через IP-Mark-и в
<...>
iptables -A FORWARD -s 10.0.0.0/24 -d !10.0.0.1 -j MARK --set-mark 1
(локальная сеть маркируется как ip-mark=1)
И я правильно понял, что приведены пакты ICMP unreachable, которые генерятся ядром из-за того, что порт 20480 никто не слушает?
И какие NAT правила есть?
Re: Re: Re: source routing with iproute2 не работает.
>>А где правило с ip-mark=2 ?
Сорри, все правила для ip-mark=1 и ip-mark=2 есть, порезал при вставке лишнее:
iptables -t mangle -A OUTPUT -d !10.0.0.0/24 -m owner --uid-owner squid -j MARK --set-mark 1
iptables -A FORWARD -s 10.0.0.0/24 -d !10.0.0.1 -j MARK --set-mark 1
iptables -A FORWARD -s user_ip1 -d !10.0.0.1 -j MARK --set-mark 2
iptables -A FORWARD -s user_ip2 -d !10.0.0.1 -j MARK --set-mark 2
<...>
т.е. некоторех хосты (c ip-mark=2) пускаем через eth2
Правила NAT простые:
iptables -t nat -A POSTROUTING -m mark --mark 1 -j SNAT --to-source 10.10.0.1
iptables -t nat -A POSTROUTING -m mark --mark 2 -j SNAT --to-source 10.20.0.1
т.е. NAT-ятся лишь пакеты с соответствующими марками.
>>И я правильно понял, что приведены пакты ICMP unreachable, которые >>генерятся ядром из-за того, что порт 20480 никто не слушает?
А вот содержимое пакетов я посмотреть не удосужился :(
Но врядли это icmp port unreachable, так как на обоих (eth1,2) интерфейсах пакеты,
попадающие на закрытые порты молча дропаются (не считая пакетов с established, releated)
Прием icmp type 3,11 на обоих интерфейсах разрешен, но, если я не путаю,
на отсылку ICMP unreacable (в случае дропа пакета), это не влияет.
Re: Re: Re: Re: source routing with iproute2 не работает.
Я не знаю, может попробовать понять причину путем создания счетчиков типа:
iptables -t nat -I POSTROUTING -m mark --mark 2 -o eth1 -j LOG
iptables -t nat -I POSTROUTING -m mark --mark 1 -o eth2 -j LOG
iptables -t nat -I POSTROUTING -s 10.0.10.1 -o eth2 -j LOG
iptables -t nat -I POSTROUTING -s 10.0.20.1 -o eth1 -j LOG
Если они будут расти, надо смотреть, может где ошибка в ядре.
P.S. Если адрес 10.0.0.1 принадлежит eth0, то пакеты -d 10.0.0.1 не попадут в цепочку FORWARD и -d !10.0.0.1 в данном правиле:
iptables -A FORWARD -s 10.0.0.0/24 -d !10.0.0.1 -j MARK --set-mark 2
не нужен.
P.P.S А что, сейчас -j MARK работает в FORWARD в смысле (-t filter), раньше можно было только
iptables -t mangle -A FORWARD -j MARK