Страница 1 из 1

FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-05 16:28:58
metallic
Надобно настроить PBR, имеется:
Шлюз FreeBSD 8.1 с двумя каналыми и белыми адресами, поднимается два линка pppoe: ng0 и ng1, дефолтный роут через ng1 (GATEWAY)
Хост Windows XP, который находится за шлюзом, на него надо прокинуть RDP (RDPHOST)
Просто хост Debian снаружи для теста (HOST)

Конфиг сетевых интерфейсов.

RDPHOST

Код: Выделить всё

vlan 1 - Ethernet адаптер:

        DNS-суффикс этого подключения . . :
        Описание  . . . . . . . . . . . . : AMD PCNET Family Ethernet Adapter (PCI)
        Физический адрес. . . . . . . . . : 08-00-27-47-6E-B3
        Dhcp включен. . . . . . . . . . . : нет
        IP-адрес  . . . . . . . . . . . . : 10.0.20.10
        Маска подсети . . . . . . . . . . : 255.255.255.0
        Основной шлюз . . . . . . . . . . : 10.0.20.2
        DNS-серверы . . . . . . . . . . . : 10.0.15.8
HOST

Код: Выделить всё

# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1d:92:39:32:38
          inet addr:78.46.44.XX  Bcast:78.46.44.95  Mask:255.255.255.224
          inet6 addr: fe80::21d:92ff:fe39:3238/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:91754840 errors:0 dropped:0 overruns:0 frame:0
          TX packets:113554161 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:27946971237 (26.0 GiB)  TX bytes:133541107507 (124.3 GiB)
          Interrupt:25 Base address:0xe000
GATEWAY

Код: Выделить всё

# ifconfig
default: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 08:00:27:00:bf:45
        inet 10.0.20.2 netmask 0xffff0000 broadcast 10.0.255.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
domolink: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 08:00:27:e1:99:d9
        inet 192.168.20.44 netmask 0xffffff00 broadcast 192.168.20.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
goldentk: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=9b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM>
        ether 08:00:27:1e:20:54
        inet 192.168.30.44 netmask 0xffffff00 broadcast 192.168.30.255
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
        inet6 ::1 prefixlen 128
        inet 127.0.0.1 netmask 0xff000000
        nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
ng0: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1460
        inet 80.82.46.XX --> 80.82.57.56 netmask 0xffffffff
ng1: flags=88d1<UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1460
        inet 195.218.247.XX --> 195.218.208.10 netmask 0xffffffff

# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
default            195.218.208.10     UGS         0       20    ng1
10.0.0.0/16        link#1             U           1    56619 defaul
10.0.20.2          link#1             UHS         0        0    lo0
80.82.46.XX        link#5             UHS         0        0    lo0
80.82.57.56        link#5             UH          0        0    ng0
127.0.0.1          link#4             UH          0       48    lo0
192.168.20.0/24    link#2             U           0        4 domoli
192.168.20.44      link#2             UHS         0        0    lo0
192.168.30.0/24    link#3             U           0        1 golden
192.168.30.44      link#3             UHS         0        0    lo0
195.218.208.10     link#6             UH          0        0    ng1
195.218.247.XX    link#6             UHS         0        0    lo0
Ну и параметры каналов.

Первый пров:
Интерфейс ng0
Адрес 80.82.46.XX
Шлюз 80.82.57.56

Второй пров:
Интерфейс ng1
Адрес 195.218.247.XX
Шлюз 195.218.208.10

Пробую пробросить порт 3389 со шлюза внутрь на винду.
Правила PF на шлюзе:

Код: Выделить всё

isp1_if="ng0"
isp2_if="ng1"
isp1_ip="80.82.46.XX"
isp2_ip="195.218.247.XX"
isp1_gw="80.82.57.56"
isp2_gw="195.218.208.10"

scrub in all fragment reassemble
scrub out all random-id max-mss 1440

nat on $isp1_if inet proto tcp tagged RDP -> ($isp1_if)

rdr on $isp1_if inet proto tcp to $isp1_if port 3389 tag RDP -> 10.0.20.10
rdr on $isp2_if inet proto tcp to $isp2_if port 3389 -> 10.0.20.10

pass in
pass out keep state
Ну т.е. второго прова тупо пробрасываю, т.к. он дефолтный маршрут, а первого помечаю (tag RDP) и делаю nat.

Что получается. На первый взгляд все работает, на оба адреса (80.82.46.XX и 195.218.247.XX) можно снаружи (с HOST) телнетом простучать порт 3389. Но если поглядеть снифером откуда что приходит и куда уходит - возникают вопросы.

Ну для начала для теста постучим на основной адрес(195.218.247.XX) с тестовго хоста (HOST) и посмотрим tcpdump на интефейсе ng1 (GATEWAY):

Код: Выделить всё

# tcpdump -ni ng1 port 3389
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng1, link-type NULL (BSD loopback), capture size 96 bytes
16:36:45.195734 IP 78.46.44.XX.50115 > 195.218.247.XX.3389: Flags [S], seq 1283344839, win 5840, options [mss 1460,sackOK,TS val 1466624485 ecr 0,nop,wscale 7], length 0
16:36:45.196656 IP 195.218.247.XX.3389 > 78.46.44.XX.50115: Flags [S.], seq 1160975158, ack 1283344840, win 64240, options [mss 1440,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
16:36:45.274853 IP 78.46.44.XX.50115 > 195.218.247.XX.3389: Flags [.], ack 1, win 46, options [nop,nop,TS val 1466624505 ecr 0], length 0
Все нормально, обмен идет по одному интерфейсу.

Теперь тоже самое пробуем проделать со вторым каналом, постучим с хоста(HOST) на GATEWAY(80.82.46.XX) по порту 3389.

HOST

Код: Выделить всё

# tcpdump -ni eth0 port 3389
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:40:00.832809 IP 78.46.44.XX.50923 > 80.82.46.XX.3389: Flags [S], seq 3493759667, win 5840, options [mss 1460,sackOK,TS val 1466672714 ecr 0,nop,wscale 7], length 0
15:40:00.926030 IP 80.82.46.XX.3389 > 78.46.44.XX.50923: Flags [S.], seq 25488965, ack 3493759668, win 64240, options [mss 1440,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
15:40:00.926071 IP 78.46.44.XX.50923 > 80.82.46.XX.3389: Flags [.], ack 1, win 46, options [nop,nop,TS val 1466672737 ecr 0], length 0
GATEWAY

Код: Выделить всё

# tcpdump -ni ng0 port 3389
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng0, link-type NULL (BSD loopback), capture size 96 bytes
16:39:58.094826 IP 78.46.44.XX.50923 > 80.82.46.XX.3389: Flags [S], seq 3493759667, win 5840, options [mss 1460,sackOK,TS val 1466672714 ecr 0,nop,wscale 7], length 0
16:39:58.189221 IP 78.46.44.XX.50923 > 80.82.46.XX.3389: Flags [.], ack 25488966, win 46, options [nop,nop,TS val 1466672737 ecr 0], length 0

# tcpdump -ni ng1 port 3389
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ng1, link-type NULL (BSD loopback), capture size 96 bytes
16:39:58.101228 IP 80.82.46.XX.3389 > 78.46.44.XX.50923: Flags [S.], seq 25488965, ack 3493759668, win 64240, options [mss 1440,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
Со стороны хоста(HOST) все выглядит нормально, запрос ушел на 80.82.46.XX и оттуда же вернулся.

Но со стороны шлюаз(GATEWAY) получается запрос приходит на 80.82.46.XX интерфейс ng0 (все верно), а уходит с адреса 80.82.46.XX, но уже интерфейса ng1 (хотя это основной канал и там другой адрес). Собственно в этом и вопрос, разве так должно быть или где-то ошибка в конфиге?

Плюс к этому, если я выключу основной канал (ng1 195.218.247.XX), то проброс порта перестает работать и на резервном канале по адресу 80.82.46.XX, ведь так быть же не должно?

Если основной канал(ng1) отключить, то таблица маршрутизации на шлюзе(GATEWAY) выглядит так:

Код: Выделить всё

# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif Expire
10.0.0.0/16        link#1             U           1    56973 defaul
10.0.20.2          link#1             UHS         0        0    lo0
80.82.46.XX        link#5             UHS         0        0    lo0
80.82.57.56        link#5             UH          0        0    ng0
127.0.0.1          link#4             UH          0       48    lo0
192.168.20.0/24    link#2             U           0        4 domoli
192.168.20.44      link#2             UHS         0        0    lo0
192.168.30.0/24    link#3             U           0        1 golden
192.168.30.44      link#3             UHS         0        0    lo0

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-05 17:44:54
metallic
Одну проблему победил, теперь пакеты ходят по нужным интерфейсам, сейчас конфиг выглядит так:

Код: Выделить всё

isp1_if="ng0"
isp2_if="ng1"
isp1_ip="80.82.46.XX"
isp2_ip="195.218.247.XX"
isp1_gw="80.82.57.56"
isp2_gw="195.218.208.10"

scrub in all fragment reassemble
scrub out all random-id max-mss 1440
set skip on default
set skip on lo

nat on $isp1_if inet proto tcp tagged RDP -> $isp1_if

rdr on $isp1_if inet proto tcp to $isp1_if port 3389 tag RDP1 -> 10.0.20.10
rdr on $isp2_if inet proto tcp to $isp2_if port 3389 tag RDP2 -> 10.0.20.10

block in
pass out keep state

pass in on $isp1_if reply-to ($isp1_if $isp1_gw) inet proto tcp tagged RDP1 keep state
pass in on $isp2_if reply-to ($isp2_if $isp2_gw) inet proto tcp tagged RDP2 keep state
Но вторая проблема осталась. Если отключить основной канал, то по второму каналу(80.82.46.XX) до порта 3389 не достучатся, хотя на шлюзе tcpdump показывается, что входящие пакеты есть

Код: Выделить всё

18:35:41.638895 IP 78.46.44.ХХ.37330 > 80.82.46.ХХ.3389: Flags [S], seq 2751270333, win 5840, options [mss 1460,sackOK,TS val 1468408913 ecr 0,nop,wscale 7], length 0
Но шлюз на них не отвечает.

Я так подозреваю, что что-то с роутингом не донастроил, шлюз тупо незнает куда слать, ведь при отключении основного канала исчезает маршрут по умолчанию.

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-10 1:13:46
si__lis
setfib для этого существует

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-10 12:31:39
RL
Скриптик юзай, который будет мониторить каналы. Основной пропадает, скрипт меняет маршрут на резерв. Восстанавливается - обратно.

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-10 14:22:34
metallic
RL писал(а):Скриптик юзай, который будет мониторить каналы. Основной пропадает, скрипт меняет маршрут на резерв. Восстанавливается - обратно.
Это как запасной костыль, хотелось бы как в linux, без лишних телодвижений, чтобы были активны все каналы, но на другом форуме мне объяснили, что так не получится из-за того, что в линуксе conntrack есть, а во фре нет.

Но si__lis написал про setfib, к сожалению он под ipfw, вот щас курю ман.

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-10 15:10:28
si__lis
RL писал(а):Скриптик юзай, который будет мониторить каналы. Основной пропадает, скрипт меняет маршрут на резерв. Восстанавливается - обратно.
О.. это классика того, как делать не надо. ;-)
Проблема таких скриптов - затрудненная отладка и недостаточная гибкость.
Люди целый протокол динамической маршрутизации ихзобрели, а вы хотите одном шелвским скриптом на 2 строки решить! :cz2:
Назовите критерии мониторинга каналов и практическую реализация этого.

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-10 15:17:32
si__lis
metallic писал(а): Но si__lis написал про setfib, к сожалению он под ipfw, вот щас курю ман.
классика жанра

2 внешних ифейса fxp0 fxp1 1 внутренний - em0
есть сетка А 192,168,0/24 есть сетка Б 192,168,1/24, надо вторую пустить через fxp1
пишем

Код: Выделить всё

setfib 1 route add 0 -iface fxp1
ipfw add x setfib 1 all from 192.168.1.0/24 to any in recv em0

Воля! Вам не нужно знать IP шлюзов и ваши IP (они могут быть динамическими)...

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-13 10:16:36
metallic
Вроде, пока все получается с ipfw, единственный момент, не могу найти аналог следующего:

Код: Выделить всё

scrub out all random-id max-mss 1400
Эта директива PF заставляет фрагментировать весь исходящий трафик, уменьшая размер пакета до 1400 байт.
Это необходимо для нормальной работы nat, например за натом есть хост Windows XP, у которого на интерфейсе mtu 1500 и из-за этого некоторые сайты не открываются, нужно уменьшать mtu на клиенте, а это геморойно, особенно в Win XP, где надо копаться в реестре. В PF эта проблема решается просто добавлением вышеуказанной строчки, как можно решить эту проблему в IPFW ?

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-13 12:48:27
Alvares

Код: Выделить всё

ifconfig em0 ... mtu 1400
Может так?

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-13 13:08:49
metallic
Alvares писал(а):

Код: Выделить всё

ifconfig em0 ... mtu 1400
Может так?
Не, не поможет

[offtop]Ты реально из Воронежа? Земляки получается :)[/offtop]

Re: FreeBSD + PF + PBR (ага, опять)

Добавлено: 2012-01-16 8:20:04
Alvares

Код: Выделить всё

net.inet.ip.dummynet.red_max_pkt_size 
не то? "ожидаемый размер пакета очереди"

З.Ы. Да, земляки