GRE и NAT – внезапно проблема [preSOLVED?]

Есть некий сервер с accel-ppp, предоставляет pptp и l2tp. И вдруг от него потребовалось, чтобы он предоставлял это не на одном IP, а на нескольких. Сам он так не умеет, так что iptables -t nat -A PREROUTING -m set --match-set $SET_VPN dst -j DNAT --to-destination $VPN_IP. Но увы, подключиться на $SET_VPN через pptp не удается:
(server.6 это $VPN_IP, на котором accel-ppp принимает pptp и l2tp, server.15 – это один из $SET_VPN)

02:51:01.181534 IP client.4147 > server.15.1723: Flags [S], seq 2758515470, win 65535, options [mss 1412,nop,nop,sackOK], length 0
02:51:01.181566 IP server.15.1723 > client.4147: Flags [S.], seq 1583048317, ack 2758515471, win 29200, options [mss 1460,nop,nop,sackOK], length 0
02:51:01.211865 IP client.4147 > server.15.1723: Flags [P.], seq 1:157, ack 1, win 65535, length 156: pptp CTRL_MSGTYPE=SCCRQ PROTO_VER(1.0) FRAME_CAP(A) BEARER_CAP(A) MAX_CHAN(0) FIRM_REV(2600) HOSTNAME() VENDOR(Microsoft Windows NT)
02:51:01.211922 IP server.15.1723 > client.4147: Flags [.], ack 157, win 30016, length 0
02:51:01.212052 IP server.15.1723 > client.4147: Flags [P.], seq 1:157, ack 157, win 30016, length 156: pptp CTRL_MSGTYPE=SCCRP PROTO_VER(1.0) RESULT_CODE(1) ERR_CODE(0) FRAME_CAP(AS) BEARER_CAP(DA) MAX_CHAN(1) FIRM_REV(1) HOSTNAME(local) VENDOR(cananian)
02:51:01.242265 IP client.4147 > server.15.1723: Flags [P.], seq 157:325, ack 157, win 65379, length 168: pptp CTRL_MSGTYPE=OCRQ CALL_ID(4147) CALL_SER_NUM(56979) MIN_BPS(300) MAX_BPS(100000000) BEARER_TYPE(Any) FRAME_TYPE(E) RECV_WIN(64) PROC_DELAY(0) PHONE_NO_LEN(0) PHONE_NO() SUB_ADDR()
02:51:01.242480 IP server.15.1723 > client.4147: Flags [P.], seq 157:189, ack 325, win 31088, length 32: pptp CTRL_MSGTYPE=OCRP CALL_ID(38185) PEER_CALL_ID(4147) RESULT_CODE(1) ERR_CODE(0) CAUSE_CODE(0) CONN_SPEED(100000000) RECV_WIN(64) PROC_DELAY(0) PHY_CHAN_ID(0)
02:51:01.242950 IP server.6 > client: GREv1, call 4147, seq 1, length 35: LCP, Conf-Request (0x01), id 1, length 21
02:51:01.277129 IP client.4147 > server.15.1723: Flags [P.], seq 325:349, ack 189, win 65347, length 24: pptp CTRL_MSGTYPE=SLI PEER_CALL_ID(38185) SEND_ACCM(0xffffffff) RECV_ACCM(0xffffffff)
02:51:01.279646 IP client > server.15: GREv1, call 38185, seq 0, length 34: LCP, Conf-Request (0x01), id 0, length 20
02:51:01.279723 IP server.6 > client: GREv1, call 4147, seq 2, ack 0, length 28: LCP, Conf-Reject (0x04), id 0, length 10
02:51:01.321846 IP server.15.1723 > client.4147: Flags [.], ack 349, win 31088, length 0
02:51:03.278989 IP client > server.15: GREv1, call 38185, seq 1, length 34: LCP, Conf-Request (0x01), id 1, length 20
02:51:03.279171 IP server.6 > client: GREv1, call 4147, seq 3, ack 1, length 28: LCP, Conf-Reject (0x04), id 1, length 10
02:51:04.243003 IP server.6 > client: GREv1, call 4147, seq 4, length 35: LCP, Conf-Request (0x01), id 1, length 21
02:51:06.283295 IP client > server.15: GREv1, call 38185, seq 2, length 34: LCP, Conf-Request (0x01), id 2, length 20
02:51:06.283416 IP server.6 > client: GREv1, call 4147, seq 5, ack 2, length 28: LCP, Conf-Reject (0x04), id 2, length 10
02:51:07.242993 IP server.6 > client: GREv1, call 4147, seq 6, length 35: LCP, Conf-Request (0x01), id 1, length 21
02:51:10.243174 IP server.6 > client: GREv1, call 4147, seq 7, length 35: LCP, Conf-Request (0x01), id 1, length 21
02:51:10.288690 IP client > server.15: GREv1, call 38185, seq 3, length 34: LCP, Conf-Request (0x01), id 3, length 20
02:51:10.288771 IP server.6 > client: GREv1, call 4147, seq 8, ack 3, length 28: LCP, Conf-Reject (0x04), id 3, length 10

вгетпаста, то же самое

сразу бросается в глаза, что DNAT для контрольного соединения работает верно (client <> server.15.1723), однако с GRE не совсем мне понятно. Глядя другим глазом (мне как-то совсем лень изучать RFC) в удачное pptp соединение на «основной» IP server.6, я вижу, что оба конца посылают Conf-Request пока видимо не договорятся о length.
Для данного же случая я вижу интереснейшую вещь:

client > server.15: GREv1, call 38185, seq 0, length 34: LCP, Conf-Request (0x01), id 0, length 20
server.6 > client: GREv1, call 4147, seq 2, ack 0, length 28: LCP, Conf-Reject (0x04), id 0, length 10
…
client > server.15: GREv1, call 38185, seq 2, length 34: LCP, Conf-Request (0x01), id 2, length 20
server.6 > client: GREv1, call 4147, seq 5, ack 2, length 28: LCP, Conf-Reject (0x04), id 2, length 10

Conf-Reject от сервера не «натится», а уходит с «оригинальным» IP. Разумеется, эти ответы не проходит через nat, за которым находится client – так же как и Conf-Request в ту же сторону. Собственно, это и есть вопрос.

----

дальнейшие расследования: (PPTP успешно подключен к server.6):

# conntrack -L -s client -d server.6
gre      47 25 src=client dst=server.6 srckey=0x0 dstkey=0x954d [UNREPLIED] src=server.6 dst=client srckey=0x954d dstkey=0x0 mark=0 use=1
tcp      6 51 ESTABLISHED src=client dst=server.6 sport=4192 dport=1723 src=server.6 dst=client sport=1723 dport=4192 [ASSURED] mark=0 use=1

----

вроде бы починено? работает, но вопросы остались, комментарии в теме.

+ -t raw -A PREROUTING -i $OINTERFACE -d $VPN_IP -p tcp --dport 1723 -j CT --helper pptp
+ -t raw -A PREROUTING -i $OINTERFACE -m set --match-set $SET_VPN dst -p tcp --dport 1723 -j CT --helper pptp
- -A allow-vpn-traffic-in-in -p gre -j ACCEPT
+ -A allowed-connection -m conntrack --ctstate RELATED -m helper --helper pptp -p gre -i $OINTERFACE -d $VPN_IP -j ACCEPT

.

Ядро? Вангую 3.14.
Не похоже на #518724?

:wq
--
Live free or die

3.12.13 Ну если ты по тем

3.12.13
Ну если ты по тем диффам что-то понял, то я искренне завидую. Скажи тогда сам – похоже или нет :)

lsmod|grep nf_nat_pptp

lsmod|grep nf_nat_pptp
Угу, такие дела :)

П.С полный список правил и модулей ф студию

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

я тоже в эту сторону сразу

я тоже в эту сторону сразу подумал, однако …

# lsmod | egrep 'xt|ip|nat|pptp|gre|conntrack' | cut -d' ' -f1
ip_set_hash_ipport
ip_set_list_set
ip_set_bitmap_ip
xt_NETMAP
ip_set_hash_ip
xt_mark
ip_set_hash_netport
iptable_mangle
pptp
gre
pppox
ppp_generic
xt_nat
iptable_nat
nf_nat_ipv4
xt_limit
ipt_REJECT
xt_set
xt_multiport
xt_LOG
xt_conntrack
xt_comment
nf_conntrack_ipv4
nf_defrag_ipv4
xt_tcpudp
iptable_raw
xt_CT
ip_set_hash_net
ip_set
iptable_filter
nfnetlink
ip_tables
xt_recent
x_tables
nf_nat_pptp
nf_nat_proto_gre
nf_nat
nf_conntrack_pptp
nf_conntrack_proto_gre
nf_conntrack_ftp
nf_conntrack

по правилам все тоже просто:

-A allow-vpn-traffic-in -i $OINTERFACE -d $VPN_IP -j allow-vpn-traffic-in-in
-A allow-vpn-traffic-in-in -p gre -j ACCEPT
-A allow-vpn-traffic-in-in -j allow-vpn-traffic-in-check
# 1701,1723
-A allow-vpn-traffic-in-in -m multiport -p udp --destination-ports $VPN_UDP_PORTS -j ACCEPT
-A allow-vpn-traffic-in-in -m multiport -p tcp --destination-ports $VPN_TCP_PORTS -j ACCEPT
-A allow-vpn-traffic-in-in -j allowed-connection
-A allow-vpn-traffic-in-check -m conntrack --ctstate NEW -m recent --set --name rcnt_vpn
-A allow-vpn-traffic-in-check -m conntrack --ctstate NEW -m recent --name rcnt_vpn --update $VPN_RECENT -j recent-limit
…
-A allowed-connection -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A allowed-connection -j DROP
…
-A INPUT -j allow-vpn-traffic-in
…
-A INPUT -j allowed-connection
…
-t nat -A PREROUTING -m set --match-set $SET_VPN dst -j DNAT --to-destination $VPN_IP
…
# Chain OUTPUT (policy ACCEPT), Chain INPUT (policy DROP)

в шапку добавлены «дальнейшие

в шапку добавлены «дальнейшие расследования»

остались вопросы – хотелось

что, собственно, было сделано (подробности в шапке):

1. было убрано правило прямого ACCEPT для gre
2. был добавлен -j CT --helper pptp в raw/PREROUTING, после чего conntrack стал помечать gre соединения как ASSURED

остались вопросы – хотелось бы, чтоб их прокомментировали:

1. Почему оказывается необходимым -t raw -A PREROUTING -i $OINTERFACE -d $VPN_IP -p tcp --dport 1723 -j CT --helper pptp? Насколько я раньше думал, хелперам помогать не надо, если все на умолчательных портах…

2. -A allowed-connection -m conntrack --ctstate RELATED -m helper --helper pptp -p gre -i $OINTERFACE -d $VPN_IP -j ACCEPT. Почему на нем счетчик 0? Для сравнения, аналогичный счетчик для пассивных соединений FTP таки инкрементируется при новом сеансе передачи данных. И где, собственно, в данном случае ACCEPTится gre? В ESTABLISHED?

3. Почему conntrack показывает для pptp и gre разные направления?

tcp      6 64 ESTABLISHED src=client dst=server.15 sport=4561 dport=1723 src=server.6 dst=client sport=1723 dport=4561 [ASSURED] mark=0 helper=pptp use=

но

gre      47 17994 src=server.6 dst=client srckey=0x95e4 dstkey=0x11d1 src=client dst=server.15 srckey=0x11d1 dstkey=0x95e4 [ASSURED] mark=0 use=1

1. Почему оказывается

1. Почему оказывается необходимым -t raw -A PREROUTING -i $OINTERFACE -d $VPN_IP -p tcp --dport 1723 -j CT --helper pptp? Насколько я раньше думал, хелперам помогать не надо, если все на умолчательных портах…

Вот здесь мужики описывают как такого поведения добиться специально.
Наверняка у Вас cat /proc/sys/net/netfilter/nf_conntrack_helper покажет 0.

Ёж птица гордая - пока не пнешь, не полетит!

не сразу даже понял что ТС

не сразу даже понял что ТС это я :-D

да, все верно, secure user of helpers уже было когда-то прочитано, nf_conntrack_helper=0 и вопрос с -j CT – снят. однако остальные вопросы вроде бы повисли.

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".