freebsd pf rdr локального порта на удалённый для локального приложени

Phoenix

дано
em0(11.11.11.11 tun0(10.0.1.1 tun1(10.0.2.1).
tun0 и tun1 в одну и ту же сеть (через разных провайдеров). 10.10.10.0/24
что сделано.
сделано
11.11.11.11:10001 -> 10.10.10.1:8081 через tun0
11.11.11.11:10002 -> 10.10.10.1:8081 через tun0
Но работает это только, когда пакет приходит через em0.
 
# pf config

ext_if="em0"
ext_addr="11.11.11.11"

int_if="lo0"

tun_if1="tun0"
tun_addr1="10.0.1.1"
tun_if2="tun1"
tun_addr2="10.0.2.1"

nat on $tun_if1 from any to any -> $tun_addr1
nat on $tun_if2 from any to any -> $tun_addr2

rdr on $ext_if inet proto tcp to $ext_addr port 10001 tag G1 -> 10.10.10.1 8081
rdr on $ext_if inet proto tcp to $ext_addr port 10002 tag G2 -> 10.10.10.1 8081

rdr on $int_if inet proto tcp to $ext_addr port 10001 tag G1 -> 10.10.10.1 8081
rdr on $int_if inet proto tcp to $ext_addr port 10002 tag G2 -> 10.10.10.1 8081

pass in all
pass out all

pass in quick on $ext_if route-to ($tun_if1 $tun_addr1) tagged G1 keep state
pass in quick on $ext_if route-to ($tun_if2 $tun_addr2) tagged G2 keep state

pass out quick route-to ($tun_if1 $tun_addr1) from $tun_addr1
pass out quick route-to ($tun_if2 $tun_addr2) from $tun_addr2

в случае доступа с локального компа
 
 # pfctl -ss | grep 8081

No ALTQ support in kernel
ALTQ related functions disabled
all tcp 10.10.10.1:8081 <- 11.11.11.11:10001 <- 11.11.11.11:30267 CLOSED:SYN_SENT
all tcp 11.11.11.11:30267 -> 10.0.1.1:52876 -> 10.10.10.1:8081 TIME_WAIT:TIME_WAIT

в случае доступа с компа 12.12.12.12 на 11.11.11.11:10001

# pfctl -ss | grep 8081
No ALTQ support in kernel
ALTQ related functions disabled
all tcp 10.10.10.1:8081 <- 11.11.11.11:10001 <- 12.12.12.12:63080 ESTABLISHED:ESTABLISHED
all tcp 12.12.12.12:63080 -> 10.0.1.1:55210 -> 10.10.10.1:8081 ESTABLISHED:ESTABLISHED

проблема в отсутствии преобразования

это на tun0
 
20:14:17.385633 IP 10.0.1.1.52876 > 10.10.10.1:8081: Flags [S], seq 4061748027, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1138808799 ecr 0], length 0
20:14:17.390086 IP 10.10.10.1:8081 > 10.0.1.1.52876: Flags [S.], seq 3088984230, ack 4061748028, win 16384, options [mss 1380,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
20:14:17.390100 IP 10.0.1.1.52876 > 10.10.10.1:8081: Flags [R], seq 4061748028, win 0, length 0
20:14:20.385016 IP 10.0.1.1.51130 > 10.10.10.1:8081: Flags [S], seq 4061748027, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1138811799 ecr 0], length 0
20:14:20.387668 IP 10.10.10.1:8081 > 10.0.1.1.51130: Flags [S.], seq 544987895, ack 4061748028, win 16384, options [mss 1380,nop,wscale 0,nop,nop,TS val 0 ecr 0,nop,nop,sackOK], length 0
20:14:20.387682 IP 10.0.1.1.51130 > 10.10.10.1:8081: Flags [R], seq 4061748028, win 0, length 0
  

это на lo0
 
20:14:17.385612 IP 11.11.11.11.30267 > 11.11.11.11.10001: Flags [S], seq 4061748027, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1138808799 ecr 0], length 0
20:14:20.384998 IP 11.11.11.11.30267 > 11.11.11.11.10001: Flags [S], seq 4061748027, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1138811799 ecr 0], length 0
    
  

на em0 соответственно ничего.
Насколько я понимаю, нет последнего преобразования из 10.0.1.1:52876 в 11.11.11.11:30267. Хотя может что-то ещё.
Это баг или так и должно быть?

AlexV769

для локальных тебе не rdr надо делать, а nat. Ну т.е. добавлять ещё правил.
что-то поторопился. ЕМНП, локальные соединения маршрутизируются через lo0, так что правила надо вешать на него. Может что и получится :)

Phoenix

Как nat, если нужно dst поправить? nat вроде только для src работает.
читал http://www.openbsd.org/faq/pf/nat.html и ман. Может что-то не вижу.

tokuchu

По крайней мере на FreeBSD в man pf.conf сказано следующее:
...
tions originating from the outside. Connections to the address of the
external interface from local hosts will not be redirected, since such
packets do not actually pass through the external interface.
Redirec-
...

tokuchu

Вот чего нагуглил ещё:
http://lists.freebsd.org/pipermail/freebsd-net/2006-January/...
Всё не читал, но возможно там есть ответы.

Phoenix

это я читал. изначально я пробовал на локальный адрес. Было тоже самое.
Поэтому я решил, что пакетик редиректится(поскольку отсылается пакет с изменённым dst. а фразу нужно понимать, что пиши "rdr on lo0", а не "rdr on em0"

tokuchu

а фразу нужно понимать, что пиши "rdr on lo0", а не "rdr on em0"
Да нет, как я понял, в рассылке написано, что если насильно его не завернёшь в loop, то оно не проявится. Т.к. rdr на in работает, а в случае, когда у тебя пакет outgouing с твоего компа, то in просто не будет.

Phoenix

На форумах там обратная проблема. хотят исходящий трафик завернуть на локальный хост. А я заворачиваю трафик на с локального хоста на удалённый.
отсылают на удалённый хост. Поэтому пакет появляется как out на em0 (внешний интерфейс)
У меня же пакет идёт к локальному хосту. Поэтому (если без rdr) будет так
ipfw log (здесь пакеты после прохождения rdr и nat от pf)
Nov 16 17:34:39 london kernel: ipfw: 2 Count TCP 11.11.11.11:11935 11.11.11.11:10001 out via em0
Nov 16 17:34:39 london kernel: ipfw: 2 Count TCP 11.11.11.11:11935 11.11.11.11:10001 in via em0
Nov 16 17:34:39 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:11935 out via em0
Nov 16 17:34:39 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:11935 in via em0

PF:
 pass in all
pass out all


#tcpdump -i lo0 tcp and port 10001 or port 8081
17:34:39.170627 IP 11.11.11.11.11935 > 11.11.11.11.10001: Flags [S], seq 2424694690, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1215630574 ecr 0], length 0
17:34:39.170657 IP 11.11.11.11.10001 > 11.11.11.11.11935: Flags [R.], seq 0, ack 2424694691, win 0, length 0

на em0 тишина.
теперь добавим rdrстроку.

rdr on em0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.10.10.1 port 8081
pass in all
pass out all

получаем
Nov 16 17:38:07 london kernel: ipfw: 2 Count TCP 11.11.11.11:18006 11.11.11.11:10001 out via em0
Nov 16 17:38:07 london kernel: ipfw: 2 Count TCP 11.11.11.11:18006 10.10.10.1:8081 in via em0
Nov 16 17:38:07 london kernel: ipfw: 2 Count TCP 11.11.11.11:18006 10.10.10.1:8081 out via tun4

tcpdump на lo0
17:41:36.381825 IP 11.11.11.11.35184 > 11.11.11.11.10001: Flags [S], seq 3294470754, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1216047786 ecr 0], length 0

tcpdump на em0 ничего не показывает
tcpdump на tun0
17:41:36.381854 IP 11.11.11.11.35184 > 10.10.10.1.8081: Flags [S], seq 3294470754, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1216047786 ecr 0], length 0

#pfctl -ss | grep 10001
all tcp 11.11.11.11:35184 -> 11.11.11.11:10001 SYN_SENT:CLOSED
all tcp 10.10.10.1:8081 <- 11.11.11.11:10001 <- 11.11.11.11:35184 CLOSED:SYN_SENT

Т.е. пакет просто не натится, но отсылается.
Добавляем нат.

nat on tun0 inet all -> 10.0.1.1
rdr on em0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.10.10.1 port 8081
pass in all
pass out all

получаем такую картинку
Nov 16 17:59:12 london kernel: ipfw: 2 Count TCP 11.11.11.11:60395 11.11.11.11:10001 out via em0
Nov 16 17:59:12 london kernel: ipfw: 2 Count TCP 11.11.11.11:60395 10.10.10.1:8081 in via em0
Nov 16 17:59:12 london kernel: ipfw: 2 Count TCP 11.11.11.11:60395 10.10.10.1:8081 out via tun0
Nov 16 17:59:12 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 11.11.11.11:60395 in via tun0
Nov 16 17:59:12 london kernel: ipfw: 2 Count TCP 11.11.11.11:60395 10.10.10.1:8081 out via tun0

на lo0
17:59:12.140946 IP 11.11.11.11.60395 > 11.11.11.11.10001: Flags [S], seq 2615008344, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1217103545 ecr 0], length 0

на tun0

17:59:12.140977 IP 10.0.1.1.59098 > 10.10.10.1.8081: Flags [S], seq 2615008344, win 65535, options [mss 1460,nop,wscale 3,sackOK,TS val 1217103545 ecr 0], length 0
17:59:12.141816 IP 10.10.10.1.8081 > 10.0.1.1.59098: Flags [S.], seq 3256716261, ack 2615008345, win 65535, options [mss 1410,nop,wscale 1,nop,nop,TS val 358013178 ecr 1217103545,sackOK,eol], length 0
17:59:12.141837 IP 10.0.1.1.59098 > 10.10.10.1.8081: Flags [R], seq 2615008345, win 0, length 0

#pfctl -ss | grep 10001
all tcp 11.11.11.11:60395 -> 11.11.11.11:10001 SYN_SENT:CLOSED
all tcp 10.10.10.1:8081 <- 11.11.11.11:10001 <- 11.11.11.11:60395 CLOSED:SYN_SENT

вот выделнный STATE не применяется. вроде как именно он должен заменить 10.10.10.1:8081 на 11.11.11.11:10001
Т.е. ответ приходит, но так как src= 10.10.10.1:8081, а не 11.11.11.11:10001 в ответ генерируется RST пакет.
Есть ощущение, что это происходит потому, что rdr был на одном интерфейсе (em0 а ответ на него не попал. Но заставить пакет пройти через em0 ещё раз у меня не получается.

Phoenix

попробовал так.
 

nat on em0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.255.255.1 #NAT-2
nat on tun0 inet all -> 10.0.1.1 #NAT-1
rdr on em0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.10.10.1 port 8081 #RDR-1
pass in all
pass out all

Т.е. как бы эмуляция внешнего адреса (10.255.255.1).Теперь пакет отправляется на em0 :grin:
 
Nov 16 18:30:21 london kernel: ipfw: 2 Count TCP 11.11.11.11:29092 11.11.11.11:10001 out via em0 #применяется NAT-2
Nov 16 18:30:21 london kernel: ipfw: 2 Count TCP 10.255.255.1:64152 10.10.10.1:8081 in via em0 #применяется RDR-1
Nov 16 18:30:21 london kernel: ipfw: 2 Count TCP 10.255.255.1:64152 10.10.10.1:8081 out via tun4 #применяется NAT-1
Nov 16 18:30:21 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:64152 in via tun4 #применяется deNAT-1
Nov 16 18:30:21 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:64152 out via em0 # ничего не применяется :(
  

Но, отправившись, не возвращается. Что тоже понятно. Обратное правило nat применяется только на входящие сообщения.

Phoenix

чувствую, придётся применять тёмную магию в виде
ng_ether <-> ng_bridge <-> ng_ether.
Интересно, пакет будет считаться другим в этом случае или тем же самым. Вроде ж там прямые вызовы и всё такое.

tokuchu

На форумах там обратная проблема. хотят исходящий трафик завернуть на локальный хост. А я заворачиваю трафик на с локального хоста на удалённый.
А чем "исходящий" отличается от "с локального хоста"?
Есть ощущение, что это происходит потому, что rdr был на одном интерфейсе (em0 а ответ на него не попал. Но заставить пакет пройти через em0 ещё раз у меня не получается.
Ну вообще навряд ли он 2 раза проходит. Наверное в этом и проблема. Я не совсем понял ты хочешь делать rdr, а потом нат ещё поверху? Наверное так просто с pf это не получится.
В остальное потом повникаю. :)

Phoenix

ура. получилось без магии.
сначала делаем левый адрес 10.255.255.1 (тут важно, чтобы этот адрес не использовался как локальный ни на одном интерфейсе, тогда он отправится в соответствии с netstat -rn, а не будет считаться доставленным.)
потом добавляем маршрут
 
route add 10.255.255.0/24 -iface lo0

и алиас (адрес лучше локальный. Но я не стал переделывать)
 
ifconfig lo0 inet 11.11.11.11/32 alias

PF
 
nat on lo0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.255.255.1    #NAT-2
nat on tun0 inet all -> 10.0.1.1 #NAT-1
rdr on lo0 inet proto tcp from any to 11.11.11.11 port = 10001 -> 10.10.10.1 port 8081 #RDR-1
pass in all
pass out all

и получаем
 
 
#туда 1
Nov 16 20:01:37 london kernel: ipfw: 2 Count TCP 11.11.11.11:20303 11.11.11.11:10001 out via lo0
 
#обратно 1
Nov 16 20:01:37 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 in via tun0
Nov 16 20:01:37 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 out via lo0
Nov 16 20:01:37 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:20303 in via lo0

 
Nov 16 20:01:37 london kernel: ipfw: 2 Count TCP 11.11.11.11:20303 11.11.11.11:10001 out via lo0
 
 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:20303 11.11.11.11:10001 out via lo0
 
 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 in via tun0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 out via lo0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:20303 in via lo0
 
 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 in via tun0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 out via lo0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:20303 in via lo0
  
 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:20303 11.11.11.11:10001 out via lo0

 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:20303 11.11.11.11:10001 out via lo0

 
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 in via tun0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 10.10.10.1:8081 10.255.255.1:56781 out via lo0
Nov 16 20:01:41 london kernel: ipfw: 2 Count TCP 11.11.11.11:10001 11.11.11.11:20303 in via lo0

  

(хотя я всё равно не понимаю, почему ipfw log не показывает in via lo0 второй строкой и out via tun0 третьей.)
tcpdump на lo0
 
20:01:37.633160 IP 10.255.255.1.56781 > 11.11.11.11.10001: Flags [S], seq 3366213893, win 65535, options [mss 16344,nop,wscale 3,sackOK,TS val 1224449036 ecr 0], length 0
20:01:37.634015 IP 11.11.11.11.10001 > 10.255.255.1.56781: Flags [S.], seq 463545509, ack 3366213894, win 65535, options [mss 1410,nop,wscale 1,nop,nop,TS val 372704553 ecr 1224449036,sackOK,eol], length 0
20:01:37.634040 IP 10.255.255.1.56781 > 11.11.11.11.10001: Flags [.], ack 1, win 8213, options [nop,nop,TS val 1224449037 ecr 372704553], length 0
20:01:41.169772 IP 10.255.255.1.56781 > 11.11.11.11.10001: Flags [P.], ack 1, win 8213, options [nop,nop,TS val 1224452572 ecr 372704553], length 6
20:01:41.174907 IP 11.11.11.11.10001 > 10.255.255.1.56781: Flags [P.], ack 7, win 32853, options [nop,nop,TS val 372711635 ecr 1224452572], length 173
20:01:41.174936 IP 11.11.11.11.10001 > 10.255.255.1.56781: Flags [F.], seq 174, ack 7, win 32853, options [nop,nop,TS val 372711635 ecr 1224452572], length 0
20:01:41.174958 IP 10.255.255.1.56781 > 11.11.11.11.10001: Flags [.], ack 175, win 8213, options [nop,nop,TS val 1224452578 ecr 372711635], length 0
20:01:41.175031 IP 10.255.255.1.56781 > 11.11.11.11.10001: Flags [F.], seq 7, ack 175, win 8213, options [nop,nop,TS val 1224452578 ecr 372711635], length 0
20:01:41.178536 IP 11.11.11.11.10001 > 10.255.255.1.56781: Flags [.], ack 8, win 32852, options [nop,nop,TS val 372711642 ecr 1224452578], length 0
  

tcpdump на tun0
 
20:01:37.633177 IP 10.0.1.1.60760 > 10.10.10.1.8081: Flags [S], seq 3366213893, win 65535, options [mss 16344,nop,wscale 3,sackOK,TS val 1224449036 ecr 0], length 0
20:01:37.633995 IP 10.10.10.1.8081 > 10.0.1.1.60760: Flags [S.], seq 463545509, ack 3366213894, win 65535, options [mss 1410,nop,wscale 1,nop,nop,TS val 372704553 ecr 1224449036,sackOK,eol], length 0
20:01:37.634044 IP 10.0.1.1.60760 > 10.10.10.1.8081: Flags [.], ack 1, win 8213, options [nop,nop,TS val 1224449037 ecr 372704553], length 0
20:01:41.169785 IP 10.0.1.1.60760 > 10.10.10.1.8081: Flags [P.], ack 1, win 8213, options [nop,nop,TS val 1224452572 ecr 372704553], length 6
20:01:41.174885 IP 10.10.10.1.8081 > 10.0.1.1.60760: Flags [P.], ack 7, win 32853, options [nop,nop,TS val 372711635 ecr 1224452572], length 173
20:01:41.174916 IP 10.10.10.1.8081 > 10.0.1.1.60760: Flags [F.], seq 174, ack 7, win 32853, options [nop,nop,TS val 372711635 ecr 1224452572], length 0
20:01:41.174962 IP 10.0.1.1.60760 > 10.10.10.1.8081: Flags [.], ack 175, win 8213, options [nop,nop,TS val 1224452578 ecr 372711635], length 0
20:01:41.175038 IP 10.0.1.1.60760 > 10.10.10.1.8081: Flags [F.], seq 7, ack 175, win 8213, options [nop,nop,TS val 1224452578 ecr 372711635], length 0
20:01:41.178514 IP 10.10.10.1.8081 > 10.0.1.1.60760: Flags [.], ack 8, win 32852, options [nop,nop,TS val 372711642 ecr 1224452578], length 0
  

Phoenix

А чем "исходящий" отличается от "с локального хоста"?

транзит является и входящим, и исходящим, например.
и всё, что через на localhost тоже.
Т.е. исходящий != не входящий.
В данном случае, важно, чтобы пакет был входящим ("in" на каком-либо интерфейсе).

tokuchu

А чем "исходящий" отличается от "с локального хоста"?
транзит является и входящим, и исходящим, например.
...
Т.е. исходящий != не входящий.
Так блин "с локального хоста" разве синоним "транзит" или "не входящий"? :)
Я же про это говорил.
и всё, что через на localhost тоже.
Та как-то странно предлоги связываешь. Тебя сложно понять.
"на с локального хоста"
"через на localhost"
WTF?
В данном случае, важно, чтобы пакет был входящим ("in" на каком-либо интерфейсе).
Ну так да. Написано же, что rdr только на in работает.
Я не вникал, но ты, похоже, как раз что-то вроде описываемой в рассылке петли и реализовал.

Phoenix

и всё, что через на localhost тоже.

"на" лишнее . :grin:

Phoenix

Я не вникал, но ты, похоже, как раз что-то вроде описываемой в рассылке петли и реализовал.

Ну да. Идея оттуда. Правда я сначала её не с того конца начал реализовывать. я при отправке начал в петлю делать - разницы не увидел. А нужно было ответ завернуть.
Спасибо :D
Оставить комментарий
Имя или ник:
Комментарий: