Удалённые пользователи не попадают на второй сайт через VPN-концентратор
Транзит через концентратор требует трёх поисков: маршрута клиента, маршрута выхода концентратора и обратного пути на дальней стороне, плюс одно ограниченное правило пересылки.
Удалённый пользователь подключается к концентратору, добирается до файлового сервера в его собственной локальной сети, и всё выглядит здоровым. Затем он открывает общий ресурс на 10.20.0.50 в головном офисе, куда концентратор попадает через отдельный туннель «сайт — сайт», и запрос заканчивается тайм-аутом. Оба туннеля подняты, и оба счётчика растут, поэтому ни один из туннелей не сломан. Проход через концентратор — это три решения маршрутизации на трёх устройствах, и туннель несёт только те префиксы, для которых он построен. Вот порядок, в котором я проверяю, и команда, которая показывает, выполняется ли каждый шаг.
Транзиту нужны три поиска, а не один туннель
Каждое устройство выполняет собственное сопоставление по самому длинному префиксу и забывает его. Ноутбук должен отправлять 10.20.0.50 в туннель, а не своему локальному маршрутизатору. Концентратор должен взять пакет, пришедший на интерфейс удалённого доступа, и передать его интерфейсу «сайт — сайт». Головной офис должен отправить ответ на адрес пользователя обратно через туннель. Любой из трёх сбоев выглядит в браузере одинаково: тишина.
Поэтому проверка каждого туннеля по отдельности доказывает так мало. Пинг адреса локальной сети концентратора задействует первое решение, а пинг концентратора из головного офиса — третье. Пакет, который не проходит, имеет источником пул пользователей, а назначением — второй сайт, поэтому сначала запишите эти префиксы. Здесь пул — 10.80.0.0/24, локальная сеть концентратора — 10.10.0.0/24, а головной офис — 10.20.0.0/24.
Протолкните дальний префикс удалённому клиенту
На сервере удалённого доступа OpenVPN клиент узнаёт маршруты при подключении. Без push клиент с раздельным туннелем отправляет 10.20.0.50 на свой собственный шлюз, и пакет никогда не входит в туннель.
push "route 10.20.0.0 255.255.255.0"
Протолкнутый маршрут вступает в силу, когда клиент подключается, поэтому пользователь, который остаётся онлайн, ничего не увидит до переподключения. Проверьте на клиенте: ip route get 10.20.0.50 в Linux, route print в Windows. Вывод должен называть интерфейс туннеля.
push не помогает концентратору. Это сообщение клиенту, а не маршрут на сервере и не разрешение на пересылку, поэтому концентратор с идеальной строкой push всё равно отбрасывает поток на один шаг позже. Это обычная причина, по которой люди заключают, что push не сработал.
Дайте концентратору настоящий маршрут выхода
Концентратору нужен собственный следующий шаг для префикса головного офиса. На маршрутизируемом туннеле это обычный маршрут через интерфейс «сайт — сайт», и одна команда показывает и выбранный маршрут, и выбранный источник:
ip route get 10.20.0.50 from 10.80.0.25
sudo ip route add 10.20.0.0/24 via 172.30.0.2 dev s2s0
Там, где плечо «сайт — сайт» само является OpenVPN, маршрут может жить в этой конфигурации с адресом туннеля партнёра в качестве шлюза: route 10.20.0.0 255.255.255.0 172.30.0.2. Шлюз не является необязательным. Если его опустить, следующий шаг свалится на реализационное значение по умолчанию, которое различается между клиентом с одной удалённой точкой и концентратором с несколькими партнёрами.
IPsec на основе политик устроен иначе: ядро концентратора отправляет пакет на свой обычный шлюз локальной сети, и политика перехватывает его на выходе, поэтому маршрут туннеля либо ничего не делает, либо ведёт трафик в обход политики. Следите за источником в команде выше, потому что 10.10.0.1 вместо адреса пула означает, что ядро выбрало адрес, который дальняя сторона отклонит. iroute тоже не ответ; он говорит серверу, какой клиент владеет подсетью за своим собственным туннелем, а не куда отправлять трафик для третьего сайта.
Расширьте дальнюю сторону до пула пользователей
Головной офис уже покрывает локальную сеть концентратора, 10.10.0.0/24. Пул пользователей — это второй префикс, и он тоже должен быть в селекторах, иначе ни одна политика не покрывает ответ, адресованный 10.80.0.25. Каждый партнёр называет одну и ту же пару наборов префиксов со своей стороны:
# strongSwan swanctl.conf, on the hub
local_ts = 10.10.0.0/24, 10.80.0.0/24
remote_ts = 10.20.0.0/24
# on the headquarters peer
local_ts = 10.20.0.0/24
remote_ts = 10.10.0.0/24, 10.80.0.0/24
local_ts одного устройства — это remote_ts другого. Скопируйте блок концентратора в головной офис, и пара перевернётся, поэтому дочерняя SA никогда не поднимется.
Более старый синтаксис ipsec.conf использует leftsubnet, разделённый запятыми. Работающая ассоциация безопасности сохраняет селекторы, о которых договорилась, поэтому переустановите туннель после правки. Селектор, изменённый в 10:00 и проверенный против SA, поднятой в 09:40, всё равно не пройдёт, хотя файл конфигурации всё это время выглядит правильным.
Затем проверьте последний шаг. ip route get 10.80.0.25 на дальнем конце должен указывать в туннель. Если служба использует маршрутизатор локальной сети как свой шлюз по умолчанию, этому маршрутизатору тоже нужен обратный маршрут, иначе ответ умирает там. Запуск tcpdump -ni eth1 host 10.80.0.25 на этом сегменте показывает, покинул ли ответ дальний конец вообще.
Разрешите поток на концентраторе
Пересылка должна быть включена, а путь — разрешён. Ограничьте правила двумя префиксами вместо того, чтобы принимать всё между интерфейсами.
sysctl -w net.ipv4.ip_forward=1
iptables -I FORWARD -i tun0 -o s2s0 -s 10.80.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -I FORWARD -i s2s0 -o tun0 -s 10.20.0.0/24 -d 10.80.0.0/24 -j ACCEPT
Фильтрация обратного пути — это тихий сбой рядом: когда два плеча на разных интерфейсах, rp_filter=1 может отбросить ответ, тогда как счётчик разрешающего правила не двигается. Сравните iptables -vnL FORWARD до и после попытки. Правило, которое никогда не растёт, не достигается, поэтому смотрите на уровень ниже, а не переписывайте его.
Если транзит нужен только одной группе, положите маршрут в файл для отдельного клиента в client-config-dir вместо расширения глобального push. Source NAT на концентраторе тоже убирает необходимость в обратном маршруте на дальней стороне, но он скрывает адрес пользователя, поэтому журналы дальнего сайта и правила на основе адресов перестают различать пользователей.
Проверьте с клиента, затем откатите в обратном порядке
Проверьте TCP-порт, а не только ICMP, потому что ping может проходить, пока служба остаётся заблокированной. nc -vz 10.20.0.50 445 и traceroute -n 10.20.0.50 с клиента показывают, является ли второй шаг адресом туннеля концентратора. На концентраторе tcpdump -ni tun0 host 10.20.0.50 и тот же фильтр на интерфейсе «сайт — сайт»: запрос на обоих без ответа на любом переносит проблему на дальнюю сторону.
Затем проверьте то, что должно остаться заблокированным. Если хост, до которого пул никогда не должен доходить, тоже отвечает, вы открыли больше, чем транзит, и правила нужно сузить. Концентратор, который пересылает всё каждому ответвлению, проходит первую проверку и проваливает вторую.
Держите список отката, потому что изменились четыре объекта, и три легко забыть: протолкнутый маршрут, маршрут концентратора, селекторы и правила межсетевого экрана. Отмените их в обратном порядке, переустановите SA и дайте одному пользователю переподключиться. Частичный откат оставляет маршрут, указывающий на туннель, который больше не подходит, и это читать труднее, чем исходную тишину. Руководство OpenVPN 2.6 документирует push, route и iroute для вашей версии.