Каковы правильные правила iptables для ipsec сайт к сайту?

Вопрос или проблема

Я пытаюсь настроить 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 основными элементами настройки являются:

  1. Основная конфигурация IPSec: Убедитесь, что параметры аутентификации, шифрования и алгоритмов соответствуют требованиям обеих сторон туннеля.
  2. Роутинг и маршрутизация на уровне ядра: Убедитесь, что маршруты корректно указывают на VTI-интерфейс для туннелирования трафика.
  3. Конфигурация 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

Применение

Шаги применения:

  1. Анализ и понимание сетевой схемы: Перед настройкой убедитесь, что вы полноценно понимаете топологию сети и назначение каждого IP-адреса и интерфейса. Это важно для правильного создания маршрутов и правил.

  2. Конфигурация VTI-интерфейса: Убедитесь, что интерфейс настроен правильно и значится в интерфейсах, используемых для маршрутизации IPSec-трафика.

  3. Настройка iptables согласно предложенному выше примеру: Убедитесь, что iptables настроен так, чтобы разрешать соответствующий трафик в обоих направлениях.

  4. Диагностика и отладка:

    • Используйте tcpdump или похожие инструменты для мониторинга трафика на интересующих интерфейсах.
    • Проверьте вывод iptables -L -v и iptables -t nat -L -v, чтобы убедиться, что нужные правила действуют.
    • Убедитесь, что пакетные трассировки (traceroute, tracepath) указывают на правильное использование маршрута через VTI.

Заключение

Правильная настройка iptables для IPSec-соединения типа "сайт-сайт" — это баланс между безопасностью и функциональностью. Она требует полного понимания инфраструктуры и ее политики маршрутизации. Следуя предложенным шагам и регулярно проверяя состояние соединения и безопасность ваших правил, вы можете наладить надежное и защищенное VPN-соединение. Если после следования указанным рекомендациям проблема не решается, рассмотрите возможность обращения за помощью к сетевым экспертам, имеющим опыт в конфигурации IPSec на Linux.

Оцените материал
Добавить комментарий

Капча загружается...