LINUX.ORG.RU
решено ФорумAdmin

Не получается поднять NAT

 , ,


0

1

Пилю себе тихо-мирно NAT для выхода в интернет через сторонний узел в сети Tinc VPN.

Для клиента написал несколько правил для iptables, которые маркируют пакеты для VPN,
после отсылаю их на сервер правилом для iproute. Судя по wireshark, тут проблем нет.

Однако, связи нет: не приходят ответы.

Конфигурация на сервере выглядит примерно так:

iptables -I FORWARD -i $INTERFACE -o eth0 -j ACCEPT
iptables -I FORWARD -i eth0 -o $INTERFACE -j ACCEPT
iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

$INTERFACE — будет заменено на имя vpn-интерфейса.

Судя по дампу с eth0 сервера (1.2.3.4) обмен c лором выглядит так:
151	15.613006	1.2.3.4	178.248.233.6	TCP	74	43504→80 [SYN] Seq=0 Win=19200 Len=0 MSS=960 SACK_PERM=1 TSval=24783014 TSecr=0 WS=128
154	15.753552	178.248.233.6	1.2.3.4	TCP	74	80→43504 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=960 SACK_PERM=1 TSval=1903969879 TSecr=24783014 WS=512
161	16.611843	1.2.3.4	178.248.233.6	TCP	74	[TCP Spurious Retransmission] 43504→80 [SYN] Seq=0 Win=19200 Len=0 MSS=960 SACK_PERM=1 TSval=24783264 TSecr=0 WS=128
162	16.752465	178.248.233.6	1.2.3.4	TCP	74	[TCP Retransmission] 80→43504 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=960 SACK_PERM=1 TSval=1903970903 TSecr=24783264 WS=512
185	18.616522	1.2.3.4	178.248.233.6	TCP	74	[TCP Spurious Retransmission] 43504→80 [SYN] Seq=0 Win=19200 Len=0 MSS=960 SACK_PERM=1 TSval=24783765 TSecr=0 WS=128
186	18.757059	178.248.233.6	1.2.3.4	TCP	74	[TCP Retransmission] 80→43504 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=960 SACK_PERM=1 TSval=1903972887 TSecr=24783765 WS=512
...
И дальше они так и продолжают играть в пинг-понг

Адрес источника перезаписан, следовательно маскарад работает.
Связь непосредственно клиента с сервером через VPN-канал не прерывается, но ответов по установленным соединениям через сервер нет.

Гугл подсказывает, что проблема может быть в MTU. MTU VPN равен 1360. Остальные интерфейсы участников по 1500.
Пробовал на сервере iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1300:9000 -j TCPMSS -o eth0 --set-mss 1000
Без положительного результата.

Куда копать? В чём может быть причина?

★★★★★

До клиента пакеты от 178.248.233.6 доходят? Судя по дампу, похоже что нет. Может быть на самом клиенте firewall так настроен. Смотрите сначала дамп на eth0, потом на самом клиенет.

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

До клиента пакеты от 178.248.233.6 доходят?

Нет в этом и суть топика. И на клиенте и на сервере все входящие и исходящие с vpn-интерфейса разрешены.
Какие ещё настройки на клиенте могут понадобиться?

Входящие на eth0 сервера, очевидно, запрещены, но в числе прочих там есть правило «iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT».
Если я правильно понимаю, то сервер инициировал отфорварженный коннект к 178.248.233.6, значит должен получить и ответ.

aidaho ★★★★★ ()
Ответ на: комментарий от stels
root@vault13:~# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1


Был бы выключен, я так понимаю, что не увидел бы отфорварженного запроса к 178.248.233.6 в дампе с eth0 сервера.

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

Сервер ответ не получает в INPUT, там не нужны правила. Решение о маршрутизации пакета принимается раньше, чем пакет пойдёт по таблице filter.

При попытка клиента выйти в инет счётчики у правила ″iptables -I FORWARD -i eth0 -o $INTERFACE -j ACCEPT″ растут?

Если на сервере сделать дамп пакетов на VPN-интерфейсе, будут пакеты от 178.248.233.6? Может на сервере нет маршрута к клиенту через VPN-интерфейс или ваша маркировка пакетов срабатывает на идущие к клиенту пакеты и отправляет их в неправильный интерфейс.

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

счётчики

Даже не знал, что они есть.

Да, на сервере iptables -I FORWARD -i eth0 -o $INTERFACE -j ACCEPT имеет нулевое значение, в то время как iptables -I FORWARD -i $INTERFACE -o eth0 -j ACCEPT — ненулевое.

Если на сервере сделать дамп пакетов на VPN-интерфейсе, будут пакеты от 178.248.233.6

Сделал, таких нет. Только пришедшие от клиента на 178.248.233.6.

Может на сервере нет маршрута к клиенту через VPN-интерфейс

Есть. Маршрут поднимает сам Tinc. Когда на клиенте активированы правила iproute для форвардинга, сервер по-прежнему остаётся доступен именно через VPN-интерфейс.

ваша маркировка пакетов срабатывает на идущие к клиенту пакеты и отправляет их в неправильный интерфейс

Маркировка точно должна срабатывать и на сервере, поскольку соответствующие правила входят в стартовый скрипт tinc'а.
Цепочка правил маркировки применяется так:

iptables -t mangle -A OUTPUT -j vpn-router  # outgoing packets
iptables -t mangle -A PREROUTING -j vpn-router  # incoming packets

Не знаю правда, зачем маркирую в PREROUTING, по-моему это лишнее.
Суть в том, что маркировка сама по себе ничего не делает, пока на сервере нет соответствующих правил iproute, никаких дополнительных эффектов от этого быть не должно.

Кстати, fwmark помечает пакеты просто в сетевом стеке машины или модифицирует сами пакеты?


В общем, из снятых дампов и счётчиков мне вполне понятно что происходит:


[1] После включения правил iproute траффик с клиента успешно заворачивается в VPN-интерфейс и идёт на адрес сервера
[1] Сервер успешно пересылает пакеты с подменой адреса источника в пункт назначения
[2] Сервер успешно получает ответ от пункта назначения и на этом хорошие новости заканчиваются
[3] Клиент не получает ответа от пункта назначания через сервер в установленный срок и перепосылает пакет, который мы видим как «TCP Spurious Retransmission»
[4] Пункт назначания получает перепосланный пакет и отвечает опять идентичным, мы видим «TCP Retransmission»

Не попадают пакеты принятые на eth0 сервера на vpn интерфейс. Почему — не понятно, и куда смотреть не понятно тоже.

Возможно есть инструменты для отсылки и отслеживания прохождения через сетевой стек пакетов с заданными свойствами?

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

fwmark метит пакеты, содержимое пакета не меняется.

Можно проследить прохождение пакета по iptables, либо с помощью ″-t raw ... -j TRACE″, либо ″-j LOG″ в различные цепочки. Только обязательно условие, чтобы все пакеты подряд под правило не попадали, допустим ″-p tcp -s 178.248.233.6″.

Не попадают пакеты принятые на eth0 сервера на vpn интерфейс.

Пока вижу три возможных варианта:
1. Пакеты рубятся rp_filter.
2. Нет нужного маршрута в vpn-интерфейс, допустим клиент идёт не с адреса на vpn-интерфейсе, а с какого-то другого.
3. Обратные пакеты рубятся где-нибудь до FORWARD-filter, допустим FORWARD-mangle.

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

1. Пакеты рубятся rp_filter.

Погуглил на эту тему, нашёл такое: http://serverfault.com/questions/297030/advanced-routing-problem
Человек пытался решить ровно ту же задачу (роутинг с помощью маркировки пакетов) и имел ровно ту же проблему, что и я.
Но мне выключение rp_filter на всех интерфейсах сервера (да и клиента тоже) не помогло. Уж было думал, что дело в шляпе.

2. Нет нужного маршрута в vpn-интерфейс, допустим клиент идёт не с адреса на vpn-интерфейсе, а с какого-то другого.

Не совсем понял, где именно его нет?
С сервера:

aidaho@vault13:~$ ip route show
default via 1.2.3.1 dev eth0
default dev vaultnet  scope link  metric 1060
169.254.0.0/16 dev vaultnet  proto kernel  scope link  src 169.254.200.1
169.254.0.0/16 dev eth0  scope link  metric 1000
1.2.3.0/24 dev eth0  proto kernel  scope link  src 1.2.3.4

aidaho@vault13:~$ ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

vaultnet - тот самый vpn интерфейс, подсеть 169.254.0.0/16. Сервер в ней имеет адрес 169.254.200.1.

С клиента при отключённой маршрутизации через сервер:
aidaho@thinkpad:~$ ip route show
default via 192.168.1.1 dev wlan0  proto static  metric 1024
default dev vaultnet  scope link  metric 1078
169.254.0.0/16 dev vaultnet  proto kernel  scope link  src 169.254.200.2
169.254.0.0/16 dev wlan0  scope link  metric 1000
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.2
aidaho@thinkpad:~$ ip rule show
0:      from all lookup local
99:     from all fwmark 0x3 lookup main
100:    from all fwmark 0x4 lookup vpn
32766:  from all lookup main
32767:  from all lookup default
aidaho@thinkpad:~$ ip route show table vpn
aidaho@thinkpad:~$


Клиент, включена маршрутизация через сервер:
aidaho@thinkpad:~$ ip route show
default via 192.168.1.1 dev wlan0  proto static  metric 1024
default dev vaultnet  scope link  metric 1078
169.254.0.0/16 dev vaultnet  proto kernel  scope link  src 169.254.200.2
169.254.0.0/16 dev wlan0  scope link  metric 1000
192.168.1.0/24 dev wlan0  proto kernel  scope link  src 192.168.1.2
aidaho@thinkpad:~$ ip rule show
0:      from all lookup local
99:     from all fwmark 0x3 lookup main
100:    from all fwmark 0x4 lookup vpn
32766:  from all lookup main
32767:  from all lookup default
aidaho@thinkpad:~$ ip route show table vpn
default via 169.254.200.1 dev vaultnet


3. Обратные пакеты рубятся где-нибудь до FORWARD-filter, допустим FORWARD-mangle.

В таблице mangle цепочка FORWARD пуста, политика ACCEPT.
В таблице filter цепочка FORWARD содержит два правила

iptables -I FORWARD -i $INTERFACE -o eth0 -j ACCEPT
iptables -I FORWARD -i eth0 -o $INTERFACE -j ACCEPT

Политика цепочки DROP.

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

Покажите дамп пакетов на сервере на интерфесе vaultnet. Мне почему-то кажется, что клиент идёт через vaultnet, но с адреса 192.168.1.2.

В таблице filter цепочка FORWARD содержит два правила. Политика

цепочки DROP.

Попробуйте на время добавить в конец FORWARD правило ″-j LOG″ и попробовать выйти в инет с клинета, чтобы было понятно, какие пакеты попадают в DROP (политику).

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

Мне почему-то кажется, что клиент идёт через vaultnet, но с адреса 192.168.1.2.

Вы совершенно правы! Я пропустил этот момент по невнимательности, когда снимал дамп в первый раз.
То есть, source-адрес проставляется раньше, чем дело доходит до маршрутизации через iproute.
Совсем неочевидная логика.

Если я правильно понимаю, то мне нужен ещё один маскарад на клиенте для интерфейса vaultnet?

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

ещё один маскарад на клиенте для интерфейса vaultnet?

Не похоже, что так можно. Цель MASQUERADE доступна только в таблице nat, а на клиенте ната нет, идёт просто рассовывание пакетов в нужные гейты.

Пытался вписать что-то вроде

iptables -t mangle -A POSTROUTING ! -d 169.254.0.0/16 -m mark --mark 4 -o vaultnet -j MASQUERADE

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

Понял ещё одну вещь.
Маршрут-то есть в vpn-сеть, но правило iprule для форвардинга выбирает таблицу vpn, где его уже нет.
Пакет самой vpn-сети проходит по правильному маршруту таблицы main, а завёрнутый в него отфорварженный по.. ну в общем не по

169.254.0.0/16 dev vaultnet  proto kernel  scope link  src 169.254.200.2

точно. И где он получает свой source адрес тоже неведомо.

Подправил vpn-таблицу маршрутов так:
default via 169.254.200.1 dev vaultnet  src 169.254.200.2

Но судя по дампу source-адрес почему-то по-прежнему не перезаписывается.

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

При выборе ip-адреса, от которого будет установлено соединение, если приложение не указывает его явно, рассматриваются маршруты только в main таблице. То есть:

default via 192.168.1.1 dev wlan0 proto static metric 1024

и берётся адрес интерфейса данного маршрута. Если используется сложная маршрутизация (ip rule), то SNAT/MASQURADE обычно дело, что-то типа:

iptables -t nat -A POSTROUTING -o vaultnet -j MASQUERADE

а на клиенте ната нет, идёт просто рассовывание пакетов в нужные гейты.

нет правил в таблице nat или его невозможно там сделать (вылюченна поддержка в ядре)?

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

нет правил в таблице nat или его невозможно там сделать (вылюченна поддержка в ядре)?

Сделать то можно, но таблица эта к поведению клиента отношения не имеет ведь?
Для пробы сделал сейчас на клиенте

root@thinkpad:/home/aidaho# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
root@thinkpad:/home/aidaho# iptables -t nat -A POSTROUTING -o vaultnet -j MASQUERADE
root@thinkpad:/home/aidaho# /home/aidaho/.scripts/vpn-activate vault13.local

На интерфейс vaultnet сервера пришли пакеты с неперезаписанным адресом источника.

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

При выборе ip-адреса, от которого будет установлено соединение, если приложение не указывает его явно, рассматриваются маршруты только в main таблице

Ок. Но когда пакет правилом был определён в таблицу маршрутизации «vpn», а там его встречает «default via 169.254.200.1 dev vaultnet src 169.254.200.2», источник по идее должен же быть перезаписан?
Может просто я как-то неверно свормулировал src правило.

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

Сделать то можно, но таблица эта к поведению клиента отношения не имеет ведь?

Оказывается, имеет. После перечитывания документации по iproute пришёл к выводу, что всё правильно сделал, вернулся к этому шагу.
Выполнил

iptables -t nat -A POSTROUTING ! -d 169.254.0.0/16 -o vaultnet -j SNAT --to 169.254.200.2

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

Проверил дампы, счётчики, внешний адрес: форвардинг точно заработал.
Пакетдроп страшный, но это, по-видимому, отдельная проблема (MTU?).
Поработаю над этим, и если не получится, создам отдельный тред.

aidaho@thinkpad:~$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=144 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=58 time=144 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=58 time=143 ms
...
64 bytes from 8.8.8.8: icmp_seq=118 ttl=58 time=40091 ms
64 bytes from 8.8.8.8: icmp_seq=119 ttl=58 time=39230 ms
64 bytes from 8.8.8.8: icmp_seq=120 ttl=58 time=38222 ms
64 bytes from 8.8.8.8: icmp_seq=121 ttl=58 time=37215 ms
64 bytes from 8.8.8.8: icmp_seq=122 ttl=58 time=36208 ms
64 bytes from 8.8.8.8: icmp_seq=123 ttl=58 time=35200 ms
64 bytes from 8.8.8.8: icmp_seq=124 ttl=58 time=34194 ms
64 bytes from 8.8.8.8: icmp_seq=125 ttl=58 time=33186 ms
...
64 bytes from 8.8.8.8: icmp_seq=163 ttl=58 time=144 ms
64 bytes from 8.8.8.8: icmp_seq=164 ttl=58 time=144 ms
64 bytes from 8.8.8.8: icmp_seq=165 ttl=58 time=144 ms
64 bytes from 8.8.8.8: icmp_seq=166 ttl=58 time=144 ms
^C
--- 8.8.8.8 ping statistics ---
167 packets transmitted, 97 received, +18 errors, 41% packet loss, time 166645ms
rtt min/avg/max/mdev = 142.706/15160.976/40117.416/15410.193 ms, pipe 40


mky, огромное спасибо за помощь. Сам бы в этом болоте вовек бы не разобрался.

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