Здравствуйте.
Есть маршрутизатор с FreeBSD 7.0 на борту, используется ipfw.
Возникла задача пробросить некоторую часть трафика до определённого узла через альтернативный маршрут.ifconfig -a :
vlan900: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3<RXCSUM,TXCSUM>
ether 00:13:20:c4:b0:85
inet 192.168.0.22 netmask 0xfffffe00 broadcast 192.168.1.255
media: Ethernet autoselect (1000baseTX <full-duplex>)
status: active
vlan: 900 parent interface: em0
Дефолтный шлюз: 192.168.0.24sk0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=b<RXCSUM,TXCSUM,VLAN_MTU>
ether 00:17:9a:06:1b:dc
inet 192.168.22.1 netmask 0xffffff00 broadcast 192.168.22.255
media: Ethernet autoselect (100baseTX <full-duplex>)
status: activeЗдесь есть адсл-модем, настроеный рутером, ip 192.168.22.2, его интернет адрес 89.###.###.3
/etc/rc.firewall :
/sbin/ipfw -q flush${ipfw} add pass tcp from any to any established
${ipfw} add check-state${ipfw} add divert natd log tcp from me to 77.###.###.158 80 out
${ipfw} add fwd 192.168.22.2 log tcp from me to 77.###.###.158 80${ipfw} add divert natd log ip from any to 192.168.22.1 in
Natd запущен просто natd -a 192.168.22.1
Какая получается картина:
Пакеты форвардятся через модем и доходят до хоста 77.###.###.158 нормально, о чем свидетельствует netstat, на том хосте.
netstat -na --inet
tcp 0 0 77.###.###.158:80 89.###.###.3:53542 SYN_RECVnatd с параметром -v показывает, что исходящие пакеты дивертятся нормально.
Out {default}[TCP] [TCP] 192.168.0.22:53542 -> 77.###.###.158:80 aliased to
[TCP] 192.168.22.1:53542 -> 77.###.###.158:80но tcpdump на интерфейсе sk0(с адсл модемом) показывает только входящие пакеты, из чего я делаю вывод, что они не попадают в natd по какой-то причине.
08:54:55.468904 IP 77.###.###.158.80 > 192.168.22.1.53542: S 916117243:916117243(0) ack 4200163278 win 5792 <mss 1452,sackOK,timestamp 40956577 309862263,nop,wscale 0>
>${ipfw} add divert natd log tcp from me to 77.###.###.158 80
>out
>
>${ipfw} add fwd 192.168.22.2 log tcp from me to 77.###.###.158 80
>
>
>${ipfw} add divert natd log ip from any to 192.168.22.1 in
>странная конструкция какая-то. Но сначала покажите вывод
#sysctl net.inet.ip.fw.one_pass
и
#sysctl net.inet.ip.forwarding
>#sysctl net.inet.ip.fw.one_pass
>и
>#sysctl net.inet.ip.forwardingnet.inet.ip.fw.one_pass: 0
net.inet.ip.forwarding: 1В чем странность?
>
>>#sysctl net.inet.ip.fw.one_pass
>>и
>>#sysctl net.inet.ip.forwarding
>
>net.inet.ip.fw.one_pass: 0
>net.inet.ip.forwarding: 1
>
>В чем странность?если нужно указать путь ДО хоста, зачем вообще юзать форвард? что мешает прописать статический маршрут через нужный шлюз?
>[оверквотинг удален]
>>>и
>>>#sysctl net.inet.ip.forwarding
>>
>>net.inet.ip.fw.one_pass: 0
>>net.inet.ip.forwarding: 1
>>
>>В чем странность?
>
>если нужно указать путь ДО хоста, зачем вообще юзать форвард? что мешает
>прописать статический маршрут через нужный шлюз?Ну, вот возникла такая необходимость: на порт 80 нужно гнать через адсл, всё остальное -- через обычный маршрут.
>[оверквотинг удален]
>>>net.inet.ip.fw.one_pass: 0
>>>net.inet.ip.forwarding: 1
>>>
>>>В чем странность?
>>
>>если нужно указать путь ДО хоста, зачем вообще юзать форвард? что мешает
>>прописать статический маршрут через нужный шлюз?
>
>Ну, вот возникла такая необходимость: на порт 80 нужно гнать через адсл,
>всё остальное -- через обычный маршрут.догда правило с дивертом не нужно вообще. НАТ включен на самом адсл, достаточно просто отфорвардить трафик туда
>>>если нужно указать путь ДО хоста, зачем вообще юзать форвард? что мешает
>>>прописать статический маршрут через нужный шлюз?
>>
>>Ну, вот возникла такая необходимость: на порт 80 нужно гнать через адсл,
>>всё остальное -- через обычный маршрут.
>
>догда правило с дивертом не нужно вообще. НАТ включен на самом адсл,
>достаточно просто отфорвардить трафик тудаУбрал в правилах диверты, оставил просто форвард. Всеравно не работает. На удалённом хосте в нестате всё так же SYN_RECV. В tcpdump'e на интерфейсе с модемом:
15:36:56.110278 IP 77.###.###.158.80 > 192.168.0.22.62523: S 654993913:654993913(0) ack 3533674242 win 5792 <mss 1452,sackOK,timestamp 43368808 334018382,nop,wscale 0>
>Убрал в правилах диверты, оставил просто форвард. Всеравно не работает. На удалённом
>хосте в нестате всё так же SYN_RECV. В tcpdump'e на интерфейсе
>с модемом:
>
>15:36:56.110278 IP 77.###.###.158.80 > 192.168.0.22.62523: S 654993913:654993913(0) ack 3533674242 win 5792 <mss 1452,sackOK,timestamp 43368808 334018382,nop,wscale 0>Так почему не работает нормально форвард?
>Ну, вот возникла такая необходимость: на порт 80 нужно гнать через адсл,
>всё остальное -- через обычный маршрут.Только определитесь, траффик должен уйти до divert или после divert ?
Порядок правил, если через natd, то сначала divert затем fwd но уже с адресом natd,
> Только определитесь, траффик должен уйти до divert или после divert ?
>
>
> Порядок правил, если через natd, то сначала divert затем fwd но
>уже с адресом natd,Извините, но я вас не понял.
(несколько раз прочитал про себя и пару раз вслух, но так и не уловил сути)
Проблема решена! Заключалась в самом верхнем правиле,
${ipfw} add pass tcp from any to any establishedПередвинул ниже дивертов -- все отлично заработало.