Как стать автором
Обновить

Round-robin default gateway ломает маршрутизацию от источника для OpenVPN сервера

Время на прочтение3 мин
Количество просмотров8.7K


На Linux (Debian 8) роутере настроена маршрутизация от источника при помощи iproute2. Корректно маршрутизируются как FORWARD, так и INPUT\OUTPUT пакеты. После включения round-robin default gateway стали возникать проблемы при подключении OpenVPN клиентов. Кейс довольно редкий, поэтому решил поделиться найденным решением с сообществом в виде данной заметки.

Round-robin default gateway включен следующей командой:
ip route add default scope global nexthop via $GW1 dev $IF1 weight 1 nexthop via $GW2 dev $IF2 weight 1 nexthop via $GW3 dev $IF3 weight 1

В реальности с маршрутизацией все немного сложнее, но эти частности не сильно влияют на конечный вывод, поэтому их можно опустить. Как видно, попеременно используется три шлюза с одинаковым весом. OpenVPN сервер слушает все интерфейсы и работает по UDP протоколу. По идее, он должен работать при таких настройках, но клиенты перестали подключаться к данному серверу. Хотя тот же SSH продолжал работать при подключении по любому из интерфейсов. Можно предположить, что причина в UDP протоколе, но проверка на DNS сервере показала, что ответы на UDP запросы возвращаются с нужных интерфейсов. Таким образом, при включении Round-robin gateway, маршрутизация от источника сломалась только для OpenVPN и причину надо искать в нем.

При коннекте, перед началом рукопожатия, запрашивается логин с паролем, и авторизация проходит успешно, дальнейшее подключение не происходит, лог неудачного подключения клиента не говорит ровным счетом ничего полезного:
TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
TLS Error: TLS handshake failed
SIGUSR1[soft,tls-error] received, process restarting
MANAGEMENT: >STATE:1451454269,RECONNECTING,tls-error
Restart pause, 2 second(s)

Интересно то, что у некоторых клиентов (по факту встретился только у одного) в логах прилетало кое-что интересное. При подключении на первый интерфейс $IP1 лог выдавал следующее:
Incoming packet rejected from [AF_INET]$IP1:1194[2], expected peer address: [AF_INET]$IP2:1194 (allow this incoming source address/port by removing --remote or adding --float)
Incoming packet rejected from [AF_INET]$IP1:1194[2], expected peer address: [AF_INET]$IP3:1194 (allow this incoming source address/port by removing --remote or adding --float)

И так по кругу. При чем, если на клиенте заменить IP адрес сервера на $IP2, то ответные пакеты будут приходить с $IP1 и $IP3, но не с $IP2. Т.е. к какому бы IP не подключался клиент, ответ никогда не приходит с того же адреса. Достаточно странное поведение. Повторю, в этот же момент маршрутизация от источника по другим подключениям работает исправно.

В процессе траблшутинга выяснилось, что при смене протокола на TCP, соединение происходит успешно и причину в надо искать в реализации работы по UDP. После этого нашлось и решение — параметр Multihome на стороне сервера OpenVPN. Man openvpn параметра multihome:

--multihome
Configure a multi-homed UDP server. This option needs to be used when a server has more than one IP address (e.g. multiple interfaces, or secondary IP addresses), and is not using --local to force binding to one
specific address only. This option will add some extra lookups to the packet path to ensure that the UDP reply packets are always sent from the address that the client is talking to. This is not supported on all
platforms, and it adds more processing, so it's not enabled by default.
Note: this option is only relevant for UDP servers.
Note 2: if you do an IPv6+IPv4 dual-stack bind on a Linux machine with multiple IPv4 address, connections to IPv4 addresses will not work right on kernels before 3.15, due to missing kernel support for the
IPv4-mapped case (some distributions have ported this to earlier kernel versions, though).

Теперь понятно, причина в принципе работы OpenVPN сервера по UDP протоколу. Опция multihome добавляет дополнительные обработки к udp пакетам, которые гарантируют отсылку ответных пакетов с адреса, на который пришел запрос. Конкретно же, что происходит, можно сказать после изучения исходников OpenVPN. Таким образом, при настройке round-robin default gateway для корректной работы OpenVPN надо или использовать TCP протокол, или добавлять параметр multihome при использовании UDP.
Теги:
Хабы:
Всего голосов 11: ↑9 и ↓2+7
Комментарии6

Публикации

Истории

Работа

Ближайшие события