Вопрос или проблема
Я пытаюсь настроить IPSEC сайт к сайту, используя strongswan на Debian 12.
VPN поднят, как показано ниже
Статус демона IKE charon (strongSwan 5.9.8, Linux 6.1.0-30-cloud-amd64, x86_64):
время работы: 18 часов, с 22 января 14:58:17 2025
malloc: sbrk 2125824, mmap 0, использовано 1366096, свободно 759728
рабочие потоки: 11 из 16 бездействуют, 5/0/0/0 работают, очередь задач: 0/0/0/0, запланировано: 5
загруженные плагины: charon aesni aes rc2 sha2 sha1 md5 mgf1 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs12 pgp dnskey sshkey pem openssl pkcs8 fips-prf gmp agent xcbc hmac kdf gcm drbg attr kernel-netlink resolve socket-default connmark forecast farp stroke updown eap-identity eap-aka eap-md5 eap-gtc eap-mschapv2 eap-radius eap-tls eap-ttls eap-tnc xauth-generic xauth-eap xauth-pam tnc-tnccs dhcp lookip error-notify certexpire led addrblock unity counters
Слушаемые IP-адреса:
<внутренний IP/VTI IP>
<Основной внутренний IP>
Подключения:
server: <внутренний IP/VTI IP>...<Внешний IP клиента> IKEv2, dpddelay=30s
server: local: [<Мой внешний IP>] использует аутентификацию по предобщему ключу
server: remote: [<Внешний IP клиента>] использует аутентификацию по предобщему ключу
server: child: <Мой диапазон VPN IP> === <Диапазон VPN IP клиента> TUNNEL, dpdaction=start
Ассоциации безопасности (1 активно, 0 в процессе подключения):
server[34]: УСТАНОВЛЕН 2 часа назад, <внутренний IP/VTI IP>[<Мой внешний IP>]...<Внешний IP клиента>[<Внешний IP клиента>]
server[34]: IKEv2 SPIs: <некоторые символы> <другие символы>, повторная аутентификация по предобщему ключу через 4 часа
server[34]: IKE предложение: AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
server{27}: УСТАНОВЛЕН, TUNNEL, reqid 1, ESP SPIs: <некоторые символы> <другие символы>
server{27}: AES_CBC_128/HMAC_SHA2_256_128, 0 bytes_i, 0 bytes_o, повторное ключирование через 42 минуты
server{27}: <Мой диапазон VPN IP> === <Диапазон VPN IP клиента>
Но я думаю, что у меня проблемы с настройкой правильных правил IPTables.
Я пробовал следовать рекомендациям, показанным здесь, а также шагам из нескольких учебных пособий (я дошел до 2 страницы Google).
У меня есть маршрут до диапазона VPN клиента
<Диапазон VPN клиента> dev vti0 scope link
Интерфейс поднят
4: vti0@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/ipip <внутренний IP/VTI IP> peer <Внешний IP клиента>
inet6 <некоторый IPv6>/64 scope link
valid_lft forever preferred_lft forever
Что я заметил: когда я настраиваю snat для трансляции VPN-трафика, выходящего через мой vti-интерфейс, трафик не достигает интерфейса, так как TCPDump не может ничего захватить. Любое другое правило (или отсутствие правила) приводит к тому, что трафик появляется в TCPDump
tcpdump -i vti0 -n
tcpdump: подробный вывод подавлен, используйте -v[v]... для полного декодирования протокола
прослушивание на vti0, тип соединения RAW (Raw IP), длина снимка 262144 байт
13:41:14.939880 IP <Внутренний/VTI IP>.43140 > <IP сервера, который я тестирую с клиентской стороны VPN>.22: Flags [S], seq 3230932500, win 64800, options [mss 1440,sackOK,TS val 2922516277 ecr 0,nop,wscale 7], длина 0
13:41:15.942056 IP <Внутренний/VTI IP>.43140 > <IP сервера, который я тестирую с клиентской стороны VPN>.22: Flags [S], seq 3230932500, win 64800, options [mss 1440,sackOK,TS val 2922517280 ecr 0,nop,wscale 7], длина 0
Но получаю ошибки “Нет пути к хосту”, когда пытаюсь получить доступ к серверу, который я знаю, доступен на другой стороне.
Я понимаю, что проблема с “нет пути к хосту” может быть в том, что IP моего исходящего трафика использует мой внутренний IP, а не один из диапазона моих VPN IP, но как я объяснил ранее, как только я применяю SNAT, трафик останавливается, и я получаю тайм-аут соединения.
Некоторые из правил, которые я пробовал применять (не все одновременно, конечно)
iptables -A FORWARD -i eth0 -o vti0 -j ACCEPT
iptables -A FORWARD -i vti0 -o eth0 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -d <Внешний IP клиента> -j SNAT --to-source <Внутренний/VTI IP>
iptables -t nat -A POSTROUTING -o vti0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth0 -s <Диапазон VPN клиента> -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o vti0 -d <Диапазон VPN клиента> -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o vti0 -d 0.0.0.0/0 -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -s <Диапазон VPN клиента> -d <мой диапазон VPN IP> -J MASQUERADE
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
iptables -t nat -A POSTROUTING -o vti0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir in -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir out -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
iptables -t nat -A POSTROUTING -o vti0 -d <Диапазон VPN клиента> -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o eth0 -d <Внешний IP клиента> -j SNAT --to-source <Внутренний/VTI IP>
iptables -t nat -A POSTROUTING -s <Диапазон VPN клиента> -o vti0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s <Диапазон VPN клиента> -o vti0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o vti0 -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o vti0 -j SNAT --to-source <другой IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -s <мой диапазон VPN IP> -o vti0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s <мой диапазон VPN IP> -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o vti0 -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -d <Внешний IP клиента> -j ACCEPT
iptables -t mangle -A OUTPUT -d <Диапазон VPN клиента> -j MARK --set-mark 1
iptables -t nat -A POSTROUTING -m mark --mark 1 -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o vti0 -s <Внутренний/VTI IP> -d <IP сервера, который я тестирую с клиентской стороны VPN> -j SNAT --to-source <IP с моей стороны диапазона VPN>
iptables -t nat -A POSTROUTING -o vti0 -s <Внутренний/VTI IP> -d <IP сервера, который я тестирую с клиентской стороны VPN> -j SNAT --to-source <другой IP с моей стороны диапазона VPN>
Не знаю, имеет ли это значение, но мой сервер находится в Azure, с включенной пересылкой IP в Azure и в Debian. В Azure нет исходящих правил.
Ответ или решение
Настройка правил iptables для IPSec-соединения "сайт-сайт" может представлять собой особенно сложную задачу, особенно если учесть особенности окружения, такого как использование виртуальных туннельных интерфейсов (VTI) и необходимость настройки преобразования сетевых адресов (NAT). Рассмотрим теоретические основы, приведем примеры применения и рекомендации по их реализации на практике.
Теория
IPSec-соединение "сайт-сайт" подразумевает, что два удаленных сетевых сегмента могут беспрепятственно обмениваться данными через защищенный туннель. На сервере StrongSwan в Debian 12 основными элементами настройки являются:
- Основная конфигурация IPSec: Убедитесь, что параметры аутентификации, шифрования и алгоритмов соответствуют требованиям обеих сторон туннеля.
- Роутинг и маршрутизация на уровне ядра: Убедитесь, что маршруты корректно указывают на VTI-интерфейс для туннелирования трафика.
- Конфигурация iptables: Правильная настройка iptables жизненно важна. Она обеспечивает как маршрутизацию, так и безопасность, управляя трафиком, входящим в туннель и выходящим из него.
Пример
Ниже приведена базовая конфигурация правил iptables, которая должна удовлетворять требованиям для рабочей настройки:
# Разрешаем форвардинг пакетов через VTI-интерфейс
iptables -A FORWARD -i eth0 -o vti0 -j ACCEPT
iptables -A FORWARD -i vti0 -o eth0 -j ACCEPT
# Избегаем небезопасных преобразований для IPSec-трафика
iptables -t nat -I POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
# Настраиваем SNAT для исходящего трафика через vti0
iptables -t nat -A POSTROUTING -o vti0 -s <My VPN IP Range> -j SNAT --to-source <Internal/VTI IP>
# Устанавливаем правила, позволяющие трафику свободно проходить между локальной и удаленной сетями через туннель
iptables -A FORWARD -s <Моя локальная сеть> -d <Удаленная сеть> -j ACCEPT
iptables -A FORWARD -s <Удаленная сеть> -d <Моя локальная сеть> -j ACCEPT
Применение
Шаги применения:
-
Анализ и понимание сетевой схемы: Перед настройкой убедитесь, что вы полноценно понимаете топологию сети и назначение каждого IP-адреса и интерфейса. Это важно для правильного создания маршрутов и правил.
-
Конфигурация VTI-интерфейса: Убедитесь, что интерфейс настроен правильно и значится в интерфейсах, используемых для маршрутизации IPSec-трафика.
-
Настройка iptables согласно предложенному выше примеру: Убедитесь, что iptables настроен так, чтобы разрешать соответствующий трафик в обоих направлениях.
-
Диагностика и отладка:
- Используйте
tcpdump
или похожие инструменты для мониторинга трафика на интересующих интерфейсах. - Проверьте вывод
iptables -L -v
иiptables -t nat -L -v
, чтобы убедиться, что нужные правила действуют. - Убедитесь, что пакетные трассировки (
traceroute, tracepath
) указывают на правильное использование маршрута через VTI.
- Используйте
Заключение
Правильная настройка iptables для IPSec-соединения типа "сайт-сайт" — это баланс между безопасностью и функциональностью. Она требует полного понимания инфраструктуры и ее политики маршрутизации. Следуя предложенным шагам и регулярно проверяя состояние соединения и безопасность ваших правил, вы можете наладить надежное и защищенное VPN-соединение. Если после следования указанным рекомендациям проблема не решается, рассмотрите возможность обращения за помощью к сетевым экспертам, имеющим опыт в конфигурации IPSec на Linux.