GRE через IPSec (Libreswan + MikroTik)

—

от автора

Здравствуйте!

Данная статья рассматривает пример реализации GRE через IPSec на основе связки LibreSwan + MikroTik.

Предполагается наличие предустановленного Linux дистрибутива, стека iproute2+NetFilter+IPTABLES и поддержки автозагрузки скриптов Runlevel Local.

Техническое задание

Вводные:

  • Есть некая организация в Москве. У нее есть сотрудники и офисы разбросанные по соседним странам.

  • Есть некие внутренние ресурсы опубликованные в публичном облаке (почта, документооборот, unified comms,)

  • Доступ к этим ресурсам разрешен только с публичных адресов этой компании

Проблема:

  • Удаленные сотрудники не получат доступа к этим ресурсам, не смотря на то, что смогут резолвить их FQDNs

Решение:

  • Реализация удаленного доступа для сотрудников и маршрутизация их трафика через периметр нашей компании

Проблема:

  • У компании ограниченная полоса пропускания на внешних каналах и забивать их лишним трафиком не хотелось бы. К тому же, гонять трафик, скажем, из Казахстана в Россию и обратно в Казахстан — дело такое себе

Решение:

  • Реализовать Split Tunneling и, как следствие, разрешить выход в Интернет как через локального ISP, так и через туннель

Топология

  • Топология представлена двумя зонами: Zone1 и Zone2

  • Каждая из зон имеет подключение к сети Интернет со статическими публичными адресами

  • Клиентский доступ предполагает возможность выхода в сеть как через ISP1, так и через ISP2

  • Наличие GRE позволяет описать IPSec SAs одним правилом по IP Protocol 47

Подбор оборудования

Требования Zone1:

  • Обеспечить динамическую конфигурацию CE интерфейса средствами PPP/DHCP opt. 82

  • Обеспечить связь в локальной сети средствами IEEE 802.11

  • Поддержка GRE, IPSec, PBR, NAT, Traffic Filtering

  • Удобство администрирования предполагает наличие GUI

  • Минимальные финансовые вложения 

Требования Zone2:

  • Поддержка GRE, IPSec, NAT, Traffic Filtering

  • Минимальные финансовые вложения 

Выводы:

Исходя из требований выбор «железа» пал на MikroTik RouterOS и стек Libreswan + IPTABLES. MikroTik и IPTABLES объяснять, думаю, излишне, а вот выбор Libreswan основывался на сравнении характеристик Libreswan/strongSwan

Credits to www.researchgate.net

Credits to www.researchgate.net

GRE

MikroTik

  • Поднимаем GRE интерфейс (Interfaces >> GRE Tunnel)

  • Назначаем IP адрес (IP >> Addresses)

  • Прописываем правила фильтрации (IP >> Firewall)

Debian

  • Подгружаем GRE модуль в ядро

modprobe ip_gre
  • Проверяем

lsmod | grep gre
  • Поднимаем GRE интерфейс

ip tunnel add gre1 mode gre local PubIP2 remote PubIP1 ttl 255 ip addr add 10.254.254.254/30 dev gre1 ip link set gre1 up
  • Выставляем MTU с учетом размера заголовков IP (20 байт), GRE (4 байта), IPSec (64 байта)

ip link set dev gre1 mtu 1412
  • Проверяем

ifconfig gre1
gre1: flags=209<UP,POINTOPOINT,RUNNING,NOARP>  mtu 1412         inet 10.254.254.254  netmask 255.255.255.252  destination 10.254.254.254
  • Добавляем в автозагрузку (см здесь)

nano -w /etc/rc.local
# GRE modprobe ip_gre ip tunnel add gre1 mode gre local PubIP2 remote PubIP1 ttl 255 ip addr add 10.254.254.254/30 dev gre1 ip link set dev gre1 mtu 1412 ip link set gre1 up
  • Прописываем правила фильтрации (см здесь)

nano -w /etc/iptables/rc.firewall
# GRE gre_iface="gre1" remote_peer="PubIP1" $ipt -A INPUT -i $iface -p 47 -m state --state NEW -s $remote_peer -j ACCEPT $ipt -A OUTPUT -o $iface -p 47 -m state --state NEW -d $remote_peer -j ACCEPT $ipt -A INPUT -i $gre_iface -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
  • Проверяем

/etc/iptables/rc.firewall iptables -nvL

Тестируем

  • Проверяем (потеря первого пакета ожидаема, поскольку туннелю необходимо время для инициализации)

[username@fw1] > ping address=10.254.254.254 src-address=10.254.254.253 size=1500   SEQ HOST                                     SIZE TTL TIME       STATUS     0 10.254.254.254                                               timeout     1 10.254.254.254                           1500  64 2ms488us     2 10.254.254.254                           1500  64 1ms829us     3 10.254.254.254                           1500  64 1ms883us     4 10.254.254.254                           1500  64 1ms931us     5 10.254.254.254                           1500  64 1ms953us     sent=6 received=5 packet-loss=16% min-rtt=1ms829us avg-rtt=2ms16us max-rtt=2ms488us

IPSec

MikroTik

  • Задаем параметры криптографии Phase 1 (IP >> IPSec >> Profiles)

  • Задаем параметры пира (IP >> IPSec >> Peers)

  • Генерим сертификаты для IKEv2 аутентификации

> /certificate/ /certificate> add name=root_ca common-name=root_ca key-size=2048 key-usage=key-cert-sign,crl-sign days-valid=3650  /certificate> print  /certificate> sign 0
/certificate> add name=fw1_ike common-name=fw1_ike key-size=2048 days-valid=3650 /certificate> add name=fw2_ike common-name=fw2_ike key-size=2048 days-valid=3650  /certificate> print  /certificate> sign 1 ca=root_ca /certificate> sign 2 ca=root_ca
  • Задаем параметры аутентификации для нашего пира (IP >> IPSec >> Identities)

Несколько слов о Notrack Chain:

Все дело в том, что у MikroTik (впрочем у меня есть подозрение что это проблема netfilter) есть серьезные проблемы с трекингом IPSec (желающие попробовать вернуться в Dial-Up эру могут прогнать через FastTrack 🙂 ) Поэтому будем отключать в дальнейшем.

  • Задаем параметры криптографии Phase 2 (IP >> IPSec >> Proposals)

  • Описываем SAs (IP >> IPSec >> Policies)

  • Описываем правила фильтрации IPSec (IP >> Firewall)

Libreswan

  • Устанавливаем пакет

apt install libreswan
  • Инициализируем NSS и устанавливаем пароль на доступ к базе

ipsec initnss certutil -W -d sql:/var/lib/ipsec/nss

Несколько слов о NSS:

NSS есть ничто иное как пользовательская библиотека используемая Libreswan IKE демоном pluto. NSS не обрабатывает IPSec криптографию внутри ядра; за это отвечают NETKEY или KLIPS модули.

Основной плюс использования NSS в том, что для pluto нет необходимости знать о том как работает криптографический шлюз. Pluto не требует доступа к ключам или данным, вместо этого используя PK11 wrapper API независимо от криптографического шлюза. Вся обработка осуществляется через доступ к NSS средствами PK11 интерфейса, тем самым избегая необходимости прямого доступа к ключам шифрования. Все IKE операции осуществляются с использованием NSS. RSA ключи (как чистые RSA, так и X.509 ключи) хранятся внутри NSS и не упоминаются напрямую в /etc/ipsec.secrets. X.509 ключи и сертификаты описываются при помощи их «никнеймов» (вместо их реальных имен) в /etc/ipsec.conf

  • Задаем пароль подключения к NSS для pluto

touch /etc/ipsec.d/nsspassword nano -w /etc/ipsec.d/nsspassword
NSS Certificate DB:secret
  • Включаем Libreswan

systemctl enable ipsec systemctl status ipsec
  • Выгружаем сертификаты из MikroTik (System >> Certificates) На выходе получатся 3 PEM пары с защищенными паролем ключами

  • Загружаем на Libreswan сервер и снимаем защиту

openssl rsa -in root_ca.key_encr -out root_ca.key openssl rsa -in fw1_ike.key_encr -out fw1_ike.key openssl rsa -in fw2_ike.key_encr -out fw2_ike.key
  • Создаем PKCS#12 архивы

openssl pkcs12 -export -in fw1_ike.crt -inkey fw1_ike.key -certfile root_ca.crt -out fw1_ike.p12 -name fw1_ike openssl pkcs12 -export -in fw2_ike.crt -inkey fw2_ike.key -certfile root_ca.crt -out fw2_ike.p12 -name fw2_ike
  • Импортируем сертификаты аутентификации IKE в NSS (подробнее можно прочитать здесь)

certutil -A -a -i /home/username/certs/root_ca.crt -d sql:/var/lib/ipsec/nss -n "RootCA" -t 'CT,,' ipsec import /home/username/certs/fw1_ike.p12 ipsec import /home/username/certs/fw2_ike.p12
  • Настраиваем IPSec (подробнее здесь)

touch /etc/ipsec.d/fw1-fw2.conf nano -w /etc/ipsec.d/fw1-fw2.conf
conn fw1-fw2         # Peers         left=PubIP2         right=PubIP1         # Phase 1 Settings         keyexchange=ike         ikev2=insist         ike=aes256-sha256;dh21         ikelifetime=24h         dpddelay=8s         dpdtimeout=32s         dpdaction=clear         fragmentation=yes         # IKEv2 Auth         authby=rsasig         leftcert=fw2_ike         leftid=%fromcert         leftsendcert=always         leftrsasigkey=%cert         rightcert=fw1_ike         rightid=%fromcert         rightca=%same         rightrsasigkey=%cert         # Phase 2 Settings         type=tunnel         phase2=esp         phase2alg=aes256-sha256;dh21         salifetime=12h         rekey=yes         pfs=yes         # SAs         leftsourceip=PubIP2         leftprotoport=gre         rightsourceip=PubIP1         rightprotoport=gre         # Auto Start During Bootup         auto=start
  • Указываем интерфейс на котором будем слушать трафик (аргумент interfaces оказался устаревшим, работаем через listen) В том же файле при необходимости можно включить дебаги.

nano -w /etc/ipsec.conf
listen=PubIP2
  • Рестартим сервис

systemctl restart ipsec systemctl status ipsec
  • Задаем правила фильтрации

nano -w /etc/iptables/rc.firewall
# IPSec $ipt -A INPUT -i $iface -p udp -m state --state NEW -s $remote_peer --dport 500 -j ACCEPT $ipt -A OUTPUT -o $iface -p udp -m state --state NEW -d $remote_peer --dport 500 -j ACCEPT $ipt -A INPUT -i $iface -p 50 -m state --state NEW -s $remote_peer -j ACCEPT $ipt -A OUTPUT -o $iface -p 50 -m state --state NEW -d $remote_peer -j ACCEPT
  • Проверяем

/etc/iptables/rc.firewall iptables -nvL

Тестируем

  • Проверяем (та же самая ситуация с первым пакетом)

[username@fw1] > ping address=10.254.254.254 src-address=10.254.254.253 size=1500   SEQ HOST                                     SIZE TTL TIME       STATUS     0 10.254.254.254                                               timeout     1 10.254.254.254                           1500  64 3ms69us     2 10.254.254.254                           1500  64 2ms865us     3 10.254.254.254                           1500  64 2ms861us     4 10.254.254.254                           1500  64 2ms918us     5 10.254.254.254                           1500  64 2ms944us     sent=6 received=5 packet-loss=16% min-rtt=2ms861us avg-rtt=2ms931us max-rtt=3ms69us
ipsec whack --trafficstatus

Маршрутизация и NAT

MikroTik

  • Создаем новую таблицу маршрутизации (Routing >> Tables)

  • Укладываем дефолт для вновь созданной таблицы маршрутизации в туннель (IP >> Routes)

  • Тегируем необходимый нам трафик для последующей переброски в GRE RT (IP >> Firewall >> Mangle) Здесь пока работаем c туннельным интерфейсом нашего GRE пира

  • Изолируем наши таблицы маршрутизации (Routing >> Rules)

  • Описываем трансляцию адресов (IP >> Firewall >> NAT) В данном случае чтобы не утруждаться контролем обратных маршрутов со стороны Libreswan используем NAT через GRE интерфейс MikroTik

  • Описываем фильтрацию (IP >> Firewall)

Тестируем

  • Проверяем со стороны клиента

ping 10.254.254.254 -l 1500  Pinging 10.254.254.254 with 1500 bytes of data: Reply from 10.254.254.254: bytes=1500 time=2ms TTL=63 Reply from 10.254.254.254: bytes=1500 time=2ms TTL=63 Reply from 10.254.254.254: bytes=1500 time=3ms TTL=63 Reply from 10.254.254.254: bytes=1500 time=3ms TTL=63  Ping statistics for 10.254.254.254:     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds:     Minimum = 2ms, Maximum = 3ms, Average = 2ms

Заключение

В принципе вот и получился у нас сплит-туннель. Закончить хотелось бы выходом «наружу» 🙂 Тем более у нас с вами остался нерассмотренным вопрос проблемы FastTrack.

Приступим !

  • Включаем IPv4 форвардинг

nano -w /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
  • Задаем правила фильтрации и трансляции адресов

# Stateful rules $ipt -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT  # # FORWARD #  # GRE FWD $ipt -A FORWARD -i $gre_iface -m state --state NEW -j ACCEPT  # # NAT #  # OB MASQUERADE remote_peer_tu="10.254.254.253" $ipt -t nat -A POSTROUTING -o $iface ! -p 47 -s $remote_peer_tu -j MASQUERADE
  • Проверяем

iptables -nvL iptables -nvL -t nat
  • Тегируем трафик на внешний адрес (IP >> Firewall >> Mangle) Здесь работаем с FQDN null.somedomain.name и задаем две метки: первую — для маршрутизации через GRE RT и вторую — для байпаса FastTrack

  • Включаем байпас на FastTrack

  • Проверяем пути от клиента

tracert -d 8.8.8.8  Tracing route to 8.8.8.8 over a maximum of 30 hops    1    <1 ms    <1 ms    <1 ms  10.10.10.10   2     7 ms     2 ms    11 ms  58.162.26.204   3     1 ms     1 ms     1 ms  203.50.60.72   4     2 ms     2 ms     3 ms  203.50.61.144   5     2 ms     2 ms     1 ms  203.50.11.195   6     3 ms     2 ms     2 ms  142.250.162.28   7     2 ms     2 ms     2 ms  142.250.234.217   8     3 ms     3 ms     2 ms  216.239.59.109   9     2 ms     2 ms     1 ms  8.8.8.8  Trace complete.
tracert -d null.somedomain.name  Tracing route to null.somedomain.name [45.32.236.11] over a maximum of 30 hops:    1    <1 ms    <1 ms    <1 ms  10.10.10.10   2     2 ms     2 ms     2 ms  10.254.254.254   3     *        *        *     Request timed out.   4     2 ms     2 ms     2 ms  100.100.200.1   5    11 ms    10 ms    31 ms  10.91.0.1   6     2 ms     2 ms     2 ms  10.91.0.17   7     2 ms     2 ms     2 ms  10.91.0.1   8    80 ms     9 ms     7 ms  67.199.141.33   9   244 ms   244 ms   244 ms  141.136.106.174  10     *        *        *     Request timed out.

На этом все 🙂 Спасибо всем, кто дочитал до конца и по традиции ссылка на внешний ресурс <Project Null> — заглядывайте иногда.

Буду рад ответить на вопросы по теме.


ссылка на оригинал статьи https://habr.com/ru/articles/874612/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *