LINUX.ORG.RU
ФорумAdmin

Source based routing

 , ,


0

1

Привет. Есть хост на Freebsd со следующими интерфейсами:

re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
        ether 30:0e:d5:cf:54:ca
        inet6 fe80::320e:d5ff:fecf:54ca%re0 prefixlen 64 scopeid 0x1 
        inet 172.16.0.1 netmask 0xffffff00 broadcast 172.16.0.255 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet 1000baseT <full-duplex>
        status: active
re0.12: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=3<RXCSUM,TXCSUM>
        ether 30:0e:d5:cf:54:ca
        inet 172.16.12.1 netmask 0xffffff00 broadcast 172.16.12.255 
        inet6 fe80::320e:d5ff:fecf:54ca%re0.12 prefixlen 64 scopeid 0x4 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        media: Ethernet 1000baseT <full-duplex>
        status: active
        vlan: 12 parent interface: re0
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet6 fe80::320e:d5ff:fecf:54ca%tun0 prefixlen 64 scopeid 0x5 
        inet [SKIPPED] --> [SKIPPED] netmask 0xffffffe0 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        Opened by PID 36484

Я хочу, чтобы весь трафик, который приходит на re0.12, заворачивался в tun0. В pf.conf прописано следующее:

lan_if = "re0"
vlan_if = "re0.12"
vpn_if = "tun0"

set skip on lo0

nat on $vpn_if inet from $vlan_if:network to any -> $vpn_if
pass in on $vlan_if route-to ($vpn_if $vpn_if:peer) inet from ($vlan_if:network) keep state

pass from { lo0, $lan_if:network, $vlan_if:network } to any keep state

При этом правило с route-to почему-то не работает, и трафик всё равно уходит в default gw. Что делать?

очевидно форварднуть пакет проматчив его, а там и NAT отработает. вот уже запамятовал есть-ли в pf fwd

VKraft ★★
()
Ответ на: комментарий от VKraft

очевидно форварднуть пакет проматчив его, а там и NAT отработает. вот уже запамятовал есть-ли в pf fwd

Правило с route-to это и должно делать, разве нет?

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

х.з. вроде должно. Извини не разглядел route-to, попробуй nat on $vpn_if inet from any to any -> $vpn_if если основной маршрут не бросает пакеты на этот интерфейс, хотя откуда тут ноги растут непонятно, с первого взгляда вроде всё правильно

VKraft ★★
()
Ответ на: комментарий от VKraft

попробуй nat on $vpn_if inet from any to any -> $vpn_if

Нет, всё равно пакеты уходят в re0 на default_gw.

P.S. Сам nat не причём. Проблема именно с роутингом. Если я пропишу маршрут к какому-нибудь хосту через tun0 руками, то пакеты к нему из vlan_if идут как надо.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)

Вот это немного смущает

nat on $vpn_if inet from $vlan_if:network to any -> $vpn_if

Там же должен быть адрес с которого натить, а не интерфейс. Может $vpn_if нужно в скобках?

nat on $vpn_if inet from $vlan_if:network to any -> ($vpn_if)
Deleted
()
Ответ на: комментарий от Deleted

Это никак не влияет. Ещё раз, проблема с route-to. Nat нормально отрабатывает, если руками прописать маршрут.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Может как-то криво разворачивает макросы? Пробовал руками дать адрес вместо $vpn_if:peer например? На OpenBSD практически такие же правила (только не на туннельных интерфейсах и с адресами вручную) отрабатывают как надо. Вот прямо скопипастил из живого конфига

nat on $ext_if from (vlan25:network) -> a.b.c.d
...
pass in on vlan25 route-to ($ext_if e.f.g.h) from (vlan25:network) to {!192.168.0.0/16} keep state
Deleted
()
Ответ на: комментарий от Deleted

Нет, руками развернуть макросы не помогло.

nat on $vpn_if inet from $vlan_if:network to any -> A.A.B.C
pass in on $vlan_if route-to ($vpn_if A.A.B.B) inet from ($vlan_if:network) keep state

Даже в этом случае результат тот же.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Непонятно. Может быть общее пропускающее правило нужно поставить перед правилом с route-to? У pf такая фича - last rule wins

Deleted
()

пример из рабочего конфига:

ext_if_a = "xl0"
ext_gw_a = "a.a.a.a"

ext_if_b = "fxp1"
ext_gw_b = "b.b.b.b"

ext_if_c = "fxp2"

int_if   = "fxp0"

match out on $ext_if_a inet proto tcp from <src1> to !<src1> nat-to $ext_if_a
match out on $ext_if_b inet from { <src1>, <src2> } to !<src1> nat-to $ext_if_b

pass in on $int_if inet proto tcp from <mail> to any port { www, smtp, https, smtps } route-to ($ext_if_a $ext_gw_a)
pass in on $int_if inet proto { tcp, udp } from <kl-bank> to any port !=25 route-to ($ext_if_b $ext_gw_b)

pass out inet from $ext_if_a route-to ($ext_if_a $ext_gw_a)
pass out inet from $ext_if_b route-to ($ext_if_b $ext_gw_b)
pass out on { $ext_if_a, $ext_if_b }

nerve ★★
()
Ответ на: комментарий от nerve

Это OpenBSD? В FreeBSD немножко старый PF, и другой синтаксис правил. В частности, nat-to не поддерживается, вроде как.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

вместо match out используйте свое текущее правило:

nat on $vpn_if inet from $vlan_if:network to any -> $vpn_if

nerve ★★
()

pass in quick on либо правила местами поменять, подсказали же уже

rubic
()
Ответ на: комментарий от Deleted

Поменял местами и добавил to !self в правило с route-to. Теперь пакеты вообще никуда не уходят. Кроме того, система перестала отвечать на пинги на $vlan_if и вообще дропает все приходящие пакеты. pass in quick даёт тот же эффект.

Правила выглядят теперь вот так:

nat on $vpn_if inet from $vlan_if:network to any -> ($vpn_if)
pass from { lo0, $lan_if:network, $vlan_if:network } to any keep state
pass in on $vlan_if route-to ($vpn_if $vpn_if:peer) inet from ($vlan_if:network) to !self keep state

Честно говоря, я нифига не понимаю почему так происходит. Мб я какой-то флаг где-то должен включить? Помимо ip.forwarding.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Если же убрать разрешающее правило (pass from { lo0, $lan_if:network, $vlan_if:network } to any keep state), то пакеты вообще никуда не роутятся.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Может во FreeBSD есть какие-то особенности? В OpenBSD в sysctl.conf вижу только «net.inet.ip.forwarding=1»

Натыкай ему протоколирования (pass log), он в выводе tcpdump -n -e -i pflog0 должен показать правило по которому пропускает (или блокирует) пакеты

Deleted
()
Ответ на: комментарий от Deleted

Хотя, возможно, дело не в pf а в OpenVPN? Он добавляет маршрут после подключения?

Deleted
()
Ответ на: комментарий от Deleted

Лог:

20:33:54.738183 rule 8..16777216/0(match): pass in on re0.12: 172.16.12.7 > 8.8.8.8: ICMP echo request, id 16099, seq 1, length 64

Правило 8 из pfstat -s rules:

pass in log on re0.12 route-to ( [SKIPPED]) inet from (re0.12:network) to ! 172.16.12.1 flags S/SA keep state

Всё вроде как верно.

У меня в конфиге OpenVPN стоит routes-nopull, чтобы он не менял default gateway для всей системы. В netstat -r маршрут к пиру присутствует.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

И дальше никуда не идет? На tun-интерфейсе ничего не появляется?

Вот вроде бы похожий случай: http://daemonforums.org/showthread.php?t=6713

Пишут разное, «Using route-to with a tun device in „dev-type tap“ mode does not work. Probably a bug i think.» например.

В итоге у него получилось, что-то там подкрутил с маршрутами

Deleted
()
Ответ на: комментарий от Deleted

И дальше никуда не идет? На tun-интерфейсе ничего не появляется?

Именно.

Вот вроде бы похожий случай: http://daemonforums.org/showthread.php?t=6713

Да, у него такая же конфигурация, но на OpenBSD. И у него проблема решилась добавлением шлюза, что у меня было изначально.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Вот что бывает, когда не хватает базовых знаний, не читают мануал, ищут решение методом гугляжа.

iZEN ★★★★★
()
Ответ на: комментарий от hateyoufeel

Это очень странно вообще-то, так как pf по умолчанию пропускает все, что не попало под действие правил. Вывод: косяк в правиле route-to. Когда оно реально начинает действовать, весь трафик перестает ходить. Разверните все макросы, не прячьте серые адреса. Какая топология OpenVPN (p2p, net30, subnet)? Тот ли IP peer? Вот сгенерированный pfSense рабочий набор правил под вашу задачу (см. последнее):

nat on em0 inet from <nPRIVATE> to any -> A.B.C.158 port 1024:65535
nat on ovpnc4 inet from <nPRIVATE> to any -> 10.211.1.37 port 1024:65535

block drop in log inet all label "Default deny rule IPv4"
block drop out log inet all label "Default deny rule IPv4"

block drop in log on ! em0 inet from A.B.C.0/24 to any
block drop in log inet from A.B.C.158 to any
block drop in log on ! ovpnc4 inet from 10.211.1.37 to any
block drop in log inet from 10.211.1.37 to any

pass in on lo0 inet all flags S/SA keep state label "pass IPv4 loopback"
pass out on lo0 inet all flags S/SA keep state label "pass IPv4 loopback"

pass out inet all flags S/SA keep state allow-opts label "let out anything IPv4 from firewall host itself"
pass out inet6 all flags S/SA keep state allow-opts label "let out anything IPv6 from firewall host itself"
pass out route-to (em0 A.B.C.1) inet from A.B.C.158 to ! A.B.C.0/24 flags S/SA keep state allow-opts label "let out anything from firewall host itself"
pass out route-to (ovpnc4 10.211.1.38) inet from 10.211.1.37 to ! 10.211.1.37 flags S/SA keep state allow-opts label "let out anything from firewall host itself"

pass in quick on em1 route-to (ovpnc4 10.211.1.38) inet from 192.168.11.0/24 to any flags S/SA keep state label "USER_RULE"

Здесь сетевой экран реализует политику 'default deny', потому необходимо не только впустить трафик, но выпустить его специальным правилом «let out anything from firewall host itself».

rubic
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.