VPN
IPsec между Linux и Windows 2012 R2
Вводная часть
Есть такая клёвая штука, называется Seafile. Это «облачное хранилище», с возможностью развёртывания на своих серверах. Реально функциональная и удобная вещь. Позволяет шарить папки/файлы, как на определённый, так и неопределённый круг пользователей. Позволяет расшарить папку для аплоада, причём содержимое пользователям видно не будет, можно только заливать файлы. Есть клиенты Seafile под винду, линукс и макось. И самое клёвое — серверная часть работает под FreeBSD :-) Домашнее облачко перевёл с Owncloud/Netxtcloud на Seafile.
Развернули в конторе для внутренних нужд Seafile, правда, не на фре, а на CentOS. Я начал настраивать авторизацию пользователей Seafile в AD через LDAP, и напоролся на граблю. По LDAP авторизация идёт, а по LDAPS — нет. А это неправильно, когда пароли по сетке ходят в открытом виде — всё-таки у нас тут инфобез, и всё такое, и по локальной сетке наши пентестеры шарятся тоже только в путь. Начал копать, как же дальше жить, в свете открывшихся фактов. Оказалось, я в этой проблеме не одинок, и существует она (применительно к версии Seafile 6 и CentOS 7) ажно с марта месяца. Нашёл на профильном форуме обсуждение. Если резюмировать, то суть там сводится к тому, что «да, LDAPS сломан, потому что несовместимы либы, которые есть в системе, и которыми пользуется Seafile. Можете попробовать закостылить путём переноса части сиафайловских библиотек в отдельный каталожек и перезапуска сервиса, чтобы Seafile стал использовать системные библиотеки». Но в моём случае это не прокатило. И у народа с форума тоже. По итогам вялого обсуждения разработчики обещали пересобрать Seafile под центось. 23-го июня, на вопрос: «чуваки, ну когда же?!» от разработчиков был получен ответ: «Сорян, пацаны, времени ваще нет!».
В общем, стало понятно, что милостей от природы ждать не стоит, и нужно думать, что делать. Основная задача — зашифровать трафик между сервером Seafile и контроллерами домена. Т. е. нужен туннель. Мы же серьёзная контора, поэтому и туннель у нас должен быть серьёзный. Не какой-нибудь жалкий PPTP/L2TP, или OpenVPN, прости-господи, а самый что ни на есть IPsec. Для разнообразия — не в туннельном, а в транспортном режиме. Так как скрывать IP-адреса нам не нужно, и достаточно только шифрования data payload, то транспортный.
Процесс настройки.
Итак, в красном углу ринга у нас CentOS 7. В синем — её соперник, Windows 2012 R2. Если с настройкой IPsec в винде вопросов особо не возникло — там это делается с помощью Windows Firewall, то с линуксом пришлось пое... эээ... поекспериментировать :-) И после каких-то жалких 4-х дней непрерывной возни, с помощью гугла, профильных сообществ и такой-то матери удалось поднять IPsec транспорт между CentOS (IP 192.168.100.15) и Windows 2012 R2 (192.168.170.10).
Изначально проблема была в том, что не устанавливалась фаза 1. Несмотря на совпадающие параметры, соединение не поднималось и SA не создавались. В дампе это выглядело так:
12:09:36.117723 IP (tos 0x0, ttl 64, id 29646, offset 0, flags [DF], proto UDP (17), length 204) 192.168.100.15.isakmp > 192.168.170.10.isakmp: [udp sum ok] isakmp 1.0 msgid 00000000 cookie e6d44de9c8641db7->0000000000000000: phase 1 I ident: (sa: doi=ipsec situation=identity (p: #0 protoid=isakmp transform=1 (t: #1 id=ike (type=enc value=3des)(type=hash value=sha1)(type=group desc value=modp2048)(type=auth value=preshared)(type=lifetype value=sec)(type=lifeduration value=2a30)))) (vid: len=8) (vid: len=16) (vid: len=20) (vid: len=16) (vid: len=16) 12:09:36.118423 IP (tos 0x0, ttl 128, id 19867, offset 0, flags [none], proto UDP (17), length 236) 192.168.170.10.isakmp > 192.168.100.15.isakmp: [udp sum ok] isakmp 1.0 msgid 00000000 cookie e6d44de9c8641db7->b2c0c64ce5211438: phase 1 R ident: (sa: doi=ipsec situation=identity (p: #0 protoid=isakmp transform=1 (t: #1 id=ike (type=enc value=3des)(type=hash value=sha1)(type=group desc value=modp2048)(type=auth value=preshared)(type=lifetype value=sec)(type=lifeduration len=4 value=00002a30)))) (vid: len=20) (vid: len=16) (vid: len=16) (vid: len=16) (vid: len=16) (vid: len=16)
Т. е. инициирующий пакет с центоси улетает, винда на него отвечает, но центось больше ничего не предпринимает. И так продолжалось по кругу. В логах при этом было следующее:
Aug 10 17:31:29 03[MGR] checkin IKE_SA dc01[3] Aug 10 17:31:29 03[MGR] checkin of IKE_SA successful Aug 10 17:31:29 16[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] Aug 10 17:31:33 09[MGR] checkout IKEv1 SA with SPIs bf2f04e4730454f7_i 0000000000000000_r Aug 10 17:31:33 09[MGR] IKE_SA dc01[3] successfully checked out Aug 10 17:31:33 09[IKE] sending retransmit 1 of request message ID 0, seq 1 Aug 10 17:31:33 09[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) Aug 10 17:31:33 09[MGR] checkin IKE_SA dc01[3] Aug 10 17:31:33 09[MGR] checkin of IKE_SA successful Aug 10 17:31:33 16[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] Aug 10 17:31:40 10[MGR] checkout IKEv1 SA with SPIs bf2f04e4730454f7_i 0000000000000000_r Aug 10 17:31:40 10[MGR] IKE_SA dc01[3] successfully checked out Aug 10 17:31:40 10[IKE] sending retransmit 2 of request message ID 0, seq 1 Aug 10 17:31:40 10[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) Aug 10 17:31:40 10[MGR] checkin IKE_SA dc01[3] Aug 10 17:31:40 10[MGR] checkin of IKE_SA successful Aug 10 17:31:40 16[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] Aug 10 17:31:53 03[MGR] checkout IKEv1 SA with SPIs bf2f04e4730454f7_i 0000000000000000_r Aug 10 17:31:53 03[MGR] IKE_SA dc01[3] successfully checked out Aug 10 17:31:53 03[IKE] sending retransmit 3 of request message ID 0, seq 1 Aug 10 17:31:53 03[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) Aug 10 17:31:53 03[MGR] checkin IKE_SA dc01[3] Aug 10 17:31:53 03[MGR] checkin of IKE_SA successful Aug 10 17:31:53 16[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] Aug 10 17:32:17 07[MGR] checkout IKEv1 SA with SPIs bf2f04e4730454f7_i 0000000000000000_r Aug 10 17:32:17 07[MGR] IKE_SA dc01[3] successfully checked out Aug 10 17:32:17 07[IKE] sending retransmit 4 of request message ID 0, seq 1 Aug 10 17:32:17 07[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) Aug 10 17:32:17 07[MGR] checkin IKE_SA dc01[3] Aug 10 17:32:17 07[MGR] checkin of IKE_SA successful Aug 10 17:32:17 16[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] Aug 10 17:32:59 07[MGR] checkout IKEv1 SA with SPIs bf2f04e4730454f7_i 0000000000000000_r Aug 10 17:32:59 07[MGR] IKE_SA dc01[3] successfully checked out Aug 10 17:32:59 07[IKE] sending retransmit 5 of request message ID 0, seq 1 Aug 10 17:32:59 07[NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) Aug 10 17:32:59 07[MGR] checkin IKE_SA dc01[3] Aug 10 17:32:59 07[MGR] checkin of IKE_SA successful
Т. е. центось считала, что винда ей не отвечает. Несмотря на многочисленные попытки, побороться с этим не удалось.
В процессе чтения мудрых указаний партии документации с сайта Strongswan сниошло озарение, что теперь, оказывается, есть две схемы конфигурации и запуска IPsec. Первый — это по старинке, через демон strongswan и настройками в файле ipsec.conf. Именно этот способ и был изначально использован. Но суровая практическая реальность показала, что при этом как минимум не идёт логирование событий IPsec, настраиваемое в файле /etc/strongswan/strongswand.d/charon-logging.conf.
И есть более стильный-модный-молодёжный способ — это настройка через конфиг /etc/strongswan/swanctl/swanctl.conf и последующий запуск с помощью сервиса strongswan-swanctl. Это два взаимоисключающих способа настройки и использования Strongswan. В итоге после долгих и бесплодных попыток запустить Strongswan с конфигом из ipsec.conf было принято волевое решение перенести настройки в swanctl.conf.
Форматы файлов разные, минимум необходимых настроек неизвестен, поэтому на конвертацию потребовалось также немало времени. Документация, описывающая параметры, есть, но нет ни примеров, ни указания, какие параметры являются обязательным. В итоге получился такой конфиг:
connections { dc01 { version = 1 local_addrs = 192.168.100.15 remote_addrs = 192.168.170.10 aggressive = no unique = no proposals = 3des-sha1-modp2048 reauth_time = 30m local { auth = psk id = 192.168.100.15 } remote { auth = psk id = 192.168.170.10 } children { dc01 { mode = transport esp_proposals = aes256-sha1 start_action = trap } } } } secrets { ike01 { id = 192.168.170.10 secret =} }
Перезапускаем сервис strongswan-swanctl, иии... Ничего. Туннель не поднимается. Начинаем запускать его руками: swanctl —load-all:
loaded ike secret 'ike01' no authorities found, 0 unloaded no pools found, 0 unloaded loaded connection 'dc01' successfully loaded 1 connections, 0 unloaded
Ну, так красиво сразу не получилось, конечно, пришлось исправить пару багов и опечаток в конфиге. Но в итоге конфиг загрузился. Проверяем список загруженных соединений:
# swanctl —list-conns dc01: IKEv1, reauthentication every 1800s local: 192.168.100.15 remote: 192.168.170.10 local pre-shared key authentication: id: 192.168.100.15 remote pre-shared key authentication: id: 192.168.170.10 dc01: TRANSPORT, rekeying every 3600s local: dynamic remote: dynamic
Есть контакт. Проверяем, создались ли SA-шки (в фоне постоянно висит пинг на соседа по туннелю):
[root@msk01-seafile01 ~]# swanctl —list-conns [root@msk01-seafile01 ~]#
Ответ отрицательный. И пинги уходят по чистому каналу, как показывает tcpdump. Иными словами — соединение загрузилось, но не активировалось. Пробуем запустить руками:
# swanctl -i —child dc01 [IKE] initiating Main Mode IKE_SA dc01[16] to 192.168.170.10 [ENC] generating ID_PROT request 0 [ SA V V V V V ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (176 bytes) [NET] received packet: from 192.168.170.10[500] to 192.168.100.15[500] (208 bytes) [ENC] parsed ID_PROT response 0 [ SA V V V V V V ] [IKE] received MS NT5 ISAKMPOAKLEY vendor ID [IKE] received NAT-T (RFC 3947) vendor ID [IKE] received draft-ietf-ipsec-nat-t-ike-02\n vendor ID [IKE] received FRAGMENTATION vendor ID [ENC] received unknown vendor ID: fb:1d:e3:cd:f3:41:b7:ea:16:b7:e5:be:08:55:f1:20 [ENC] received unknown vendor ID: e3:a5:96:6a:76:37:9f:e7:07:22:82:31:e5:ce:86:52 [ENC] generating ID_PROT request 0 [ KE No NAT-D NAT-D ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (372 bytes) [NET] received packet: from 192.168.170.10[500] to 192.168.100.15[500] (388 bytes) [ENC] parsed ID_PROT response 0 [ KE No NAT-D NAT-D ] [ENC] generating ID_PROT request 0 [ ID HASH ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (68 bytes) [NET] received packet: from 192.168.170.10[500] to 192.168.100.15[500] (68 bytes) [ENC] parsed ID_PROT response 0 [ ID HASH ] [IKE] IKE_SA dc01[16] established between 192.168.100.15[192.168.100.15]...192.168.170.10[192.168.170.10] [IKE] scheduling reauthentication in 1753s [IKE] maximum IKE_SA lifetime 1933s [ENC] generating QUICK_MODE request 4130174163 [ HASH SA No ID ID ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (172 bytes) [NET] received packet: from 192.168.170.10[500] to 192.168.100.15[500] (220 bytes) [ENC] parsed QUICK_MODE response 4130174163 [ HASH SA No ID ID N(24576) ] [IKE] CHILD_SA dc01{28} established with SPIs c856809b_i b619b0e4_o and TS 192.168.100.15/32 === 192.168.170.10/32 [ENC] generating QUICK_MODE request 4130174163 [ HASH ] initiate completed successfully
Проверяем, установились ли SA-шки:
# swanctl —list-sas dc01: #1, ESTABLISHED, IKEv1, c95a166b86ec3d0b_i* 6df2b856fdeff612_r local '192.168.100.15' @ 192.168.100.15[500] remote '192.168.170.10' @ 192.168.170.10[500] 3DES_CBC/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048 established 1189s ago, reauth in 604s [root@msk01-seafile01 ~]# swanctl -i —child dc01 [ENC] generating QUICK_MODE request 1540311929 [ HASH SA No ID ID ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (172 bytes) [NET] received packet: from 192.168.170.10[500] to 192.168.100.15[500] (220 bytes) [ENC] parsed QUICK_MODE response 1540311929 [ HASH SA No ID ID N(24576) ] [IKE] CHILD_SA dc01{3} established with SPIs c587449e_i a113d280_o and TS 192.168.100.15/32 == 192.168.170.10/32 [ENC] generating QUICK_MODE request 1540311929 [ HASH ] [NET] sending packet: from 192.168.100.15[500] to 192.168.170.10[500] (60 bytes) initiate completed successfully
Работает. Т. е. руками туннель запускается, а при перезапуске сервиса он не грузится, и не активируется. Начинаем копать, в чём тут дело. Перезапуск сервиса с последующим анализом /var/log/messages приносит следующие новости:
Aug 11 16:26:06 msk01-seafile01 systemd: Starting strongSwan IPsec IKEv1/IKEv2 daemon using swanctl... Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading ca certificates from '/etc/strongswan/ipsec.d/cacerts' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading aa certificates from '/etc/strongswan/ipsec.d/aacerts' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading ocsp signer certificates from '/etc/strongswan/ipsec.d/ocspcerts' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading attribute certificates from '/etc/strongswan/ipsec.d/acerts' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading crls from '/etc/strongswan/ipsec.d/crls' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loading secrets from '/etc/strongswan/ipsec.secrets' Aug 11 16:26:06 msk01-seafile01 charon-systemd: loaded plugins: charon-systemd charon-systemd aes des rc2 sha2 sha1 md4 md5 random nonce x509 revocation constraints acert pubkey pk cs1 pkcs8 pkcs12 pgp dnskey sshkey pem openssl gcrypt fips-prf gmp curve25519 xcbc cmac hmac ctr ccm gcm curl attr kernel-netlink resolve socket-default farp stroke vici updown eap -identity eap-md5 eap-gtc eap-mschapv2 eap-tls eap-ttls eap-peap xauth-generic xauth-eap xauth-pam xauth-noauth dhcp unity Aug 11 16:26:06 msk01-seafile01 charon-systemd: spawning 16 worker threads Aug 11 16:26:06 msk01-seafile01 swanctl: no files found matching '/etc/strongswan/strongswan.conf' Aug 11 16:26:06 msk01-seafile01 swanctl: no files found matching '/etc/strongswan/swanctl/swanctl.conf' Aug 11 16:26:06 msk01-seafile01 swanctl: failed to open config file '/etc/strongswan/swanctl/swanctl.conf' Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509ca' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509ocsp' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509aa' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509ac' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/x509crl' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/pubkey' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/private' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/rsa' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/ecdsa' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/bliss' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/pkcs8' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: opening directory '/etc/strongswan/swanctl/pkcs12' failed: Permission denied Aug 11 16:26:06 msk01-seafile01 swanctl: no authorities found, 0 unloaded Aug 11 16:26:06 msk01-seafile01 swanctl: no pools found, 0 unloaded Aug 11 16:26:06 msk01-seafile01 swanctl: no connections found, 0 unloaded Aug 11 16:26:06 msk01-seafile01 systemd: Started strongSwan IPsec IKEv1/IKEv2 daemon using swanctl.
То есть, swanctl, запускаемый с правами рута из-под systemd не получает доступа к каталогам и конфигу swanctl.conf. Лихо, что сказать... Вот за такие вещи я и «люблю» Linux... :-)
Права на каталоги и файлы выставлены следующим образом:
drwxr-xr-x. 15 root root 204 Aug 11 15:31 . drwx———. 6 root root 132 Aug 11 15:46 .. drwxr-xr-x. 2 root root 6 Jun 19 22:15 bliss drwxr-x—-. 2 root root 6 Jun 19 22:15 ecdsa drwxr-x—-. 2 root root 6 Jun 19 22:15 pkcs12 drwxr-x—-. 2 root root 6 Jun 19 22:15 pkcs8 drwxr-x—-. 2 root root 6 Jun 19 22:15 private drwxr-xr-x. 2 root root 6 Jun 19 22:15 pubkey drwxr-x—-. 2 root root 6 Jun 19 22:15 rsa -rw-r——-. 1 root root 14539 Aug 11 15:31 swanctl.conf drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509 drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509aa drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509ac drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509ca drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509crl drwxr-xr-x. 2 root root 6 Jun 19 22:15 x509ocsp
Добавил права на чтение swanctl.conf для others. Не помогло — всё равно жалуется, что нет доступа. Полез смотреть логи SELinux. В них тоже чисто. Опять было достал бубен, но потом вспомнил, что есть категории событий, которые блокируются по-тихому, и в /var/log/audit/audit.log не попадают. Включаем логирование всех событий:
После перезапуска сервиса смотрим в логи. Ну точно! Опять проклятый SELinux:
И начинается кропотливый процесс докидывания разрешений в политиках SELinux. Итоговый файл политик получился такой:
module swanctl2conf 1.0; require { type ipsec_conf_file_t; type ipsec_mgmt_t; class dir { open read search }; } #============= ipsec_mgmt_t ============== allow ipsec_mgmt_t ipsec_conf_file_t:dir open; #!!!! This avc is allowed in the current policy allow ipsec_mgmt_t ipsec_conf_file_t:dir { read search };
Применяем всю эту красоту:
# checkmodule -m -M -o swanctl2conf.mod swanctl2conf.te # semodule_package -o swanctl2conf.pp -m swanctl2conf.mod # semodule -i swanctl2conf.pp
После этого перезапускаем сервис и смотрим в логи:
Aug 11 17:16:45 msk01-seafile01 systemd: Stopping strongSwan IPsec IKEv1/IKEv2 daemon using swanctl... Aug 11 17:16:45 msk01-seafile01 charon-systemd: SIGTERM received, shutting down Aug 11 17:16:45 msk01-seafile01 systemd: Starting strongSwan IPsec IKEv1/IKEv2 daemon using swanctl... Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading ca certificates from '/etc/strongswan/ipsec.d/cacerts' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading aa certificates from '/etc/strongswan/ipsec.d/aacerts' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading ocsp signer certificates from '/etc/strongswan/ipsec.d/ocspcerts' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading attribute certificates from '/etc/strongswan/ipsec.d/acerts' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading crls from '/etc/strongswan/ipsec.d/crls' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loading secrets from '/etc/strongswan/ipsec.secrets' Aug 11 17:16:45 msk01-seafile01 charon-systemd: loaded plugins: charon-systemd charon-systemd aes des rc2 sha2 sha1 md4 md5 random nonce x509 revocation constraints acert pubkey pk cs1 pkcs8 pkcs12 pgp dnskey sshkey pem openssl gcrypt fips-prf gmp curve25519 xcbc cmac hmac ctr ccm gcm curl attr kernel-netlink resolve socket-default farp stroke vici updown eap -identity eap-md5 eap-gtc eap-mschapv2 eap-tls eap-ttls eap-peap xauth-generic xauth-eap xauth-pam xauth-noauth dhcp unity Aug 11 17:16:45 msk01-seafile01 charon-systemd: spawning 16 worker threads Aug 11 17:16:45 msk01-seafile01 charon-systemd: loaded IKE shared key with id 'ike01' for: '192.168.170.10' Aug 11 17:16:45 msk01-seafile01 swanctl: no authorities found, 0 unloaded Aug 11 17:16:45 msk01-seafile01 swanctl: no pools found, 0 unloaded Aug 11 17:16:45 msk01-seafile01 charon-systemd: added vici connection: dc01 Aug 11 17:16:45 msk01-seafile01 charon-systemd: installing 'dc01' Aug 11 17:16:45 msk01-seafile01 swanctl: loaded ike secret 'ike01' Aug 11 17:16:45 msk01-seafile01 swanctl: loaded connection 'dc01' Aug 11 17:16:45 msk01-seafile01 swanctl: successfully loaded 1 connections, 0 unloaded Aug 11 17:16:45 msk01-seafile01 systemd: Started strongSwan IPsec IKEv1/IKEv2 daemon using swanctl.
Иными словами — кррррасота! Всё работает.
L2TP+IPSec
Решил наконец-то разобраться с этой мутной доселе темой — IPSec. И в частности — с её реализацией на FreeBSD.
Если не вдаваться в кровавые подробности, то в общих чертах дело обстоит так: L2TP настраивается как обычно, абсолютно без какой-либо оглядки на то, что должен быть ещё и IPSec. Я это делаю обычно на mpd5, путём небольшой правки дефолтного конфига, который идёт с mpd.
IPSec в данном случае логически представляет собой некую надстройку, в которой нужно указать, что «трафик, идущий с такого-то IP на такой-то по таким-то портам и такого-то протокола — требует шифрования (это так называемый „транспортный режим“ работы IPSec). В случае с L2TP эти параметры выставляются так: трафик с любого IP и любого порта, идущий на IP-адрес сервера и порт 1701 (стандартный порт L2TP) по протоколу UDP, потребно шифровать.
Во фре IPSec реализуется с помощью пакета ipsec-tools (он же racoon).
После установки ipsec-tools потребуются следующие модификации в /etc/rc.conf:
...
ipsec_program="/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf"
racoon_enable="YES"
racoon_flags="-l /var/log/racoon.log"
...
Далее идут конфиги самого racoon и утилиты setkey, а также список pre-shared key по-клиентно:
flush;
spdflush; spdadd 0.0.0.0/0[any] 192.168.2.2[1701] udp -P in ipsec esp/transport//require;
spdadd 192.168.2.2[1701] 0.0.0.0/0[any] udp -P out ipsec esp/transport//require;
path pre_shared_key "/usr/local/etc/racoon/psk.txt";
log debug;
listen
{
isakmp 192.168.2.2 [500];
isakmp_natt 192.168.2.2 [4500];
strict_address;
}
remote anonymous
{
exchange_mode main;
passive on;
proposal_check obey;
support_proxy on;
nat_traversal off;
ike_frag on;
dpd_delay 20;
proposal
{
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group modp1024;
}
proposal
{
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group modp1024;
}
}
sainfo anonymous
{
encryption_algorithm aes,3des;
authentication_algorithm hmac_sha1;
compression_algorithm deflate;
pfs_group modp1024;
}
192.168.2.4 Password
192.168.2.5 Password1
192.168.1.4 Password2
Клиентом выступает маршрутизатор Mikrotik. Там схема та же — настраивается как обычно L2TP-клиент, а затем топаем в раздел IP ==> IPSec и добавляем записи на вкладке Peers и Policies. Вкладка Peers:

Собственно, здесь я изменил только поля Address (в нём указываем IP VPN-сервера) и Secret (это и есть pre-shared key), а также поле Hash algorithm (по дефолту стоял md5). Остальные поля оставил как есть.
И добавляем запись в разделе Policies:


«Как вы понимаете из названия» (с), поля Src. address и SA src. address — это IP-адрес клиента, а Dst. address и SA dst. address — это адрес VPN-сервера.
MikroTik и OpenVPN
Есть у нас в офесе VPN. Точнее, между 40 офесами. По мере роста сети всплыла грабля — некоторые удалённые (и отсталые) провайдеры грешат packet reordering. Что напрочь сносит крышу модулю, ответственному за реализацию MPPC/MPPE в mpd5. Симптомы при этом такие — туннель визуально жив, и по нему спокойно ходят LCP-пакеты, но вот трафик уже не ходит. В логах mpd при этом наличествуют сообщения:
ng_mppc_decompress: too many (4094) packets dropped, disabling node
Если вы такие обнаружили — знайте, это вилы. Надо валить. Потому что не лечится никак. Хотя вот эксперимент показал, что с микротика на микротик такой же канал, с MPPC/MPPE держится нормально. Т. е. микротиковцы в RouterOS этот вопрос решили. Но ни фря, ни линукс в качестве VPN-сервера с packet reordering бороться не умеют. В связи с чем было принято волевое решение проблемных клиентов перевести на OpenVPN. По той же схеме — сервер на FreeBSD, клиенты — микротики RB750.
Спустя некоторое время вдумчивого курения манов и некоторого количества глупых вопросов в ru_root наступило просветление и я принялся ваять конфиги сервера и создавать сертификаты. Создав всё, начал терзать первого проблемного клиента, отключив L2TP-линк на нём и создав клиентский интерфейс OpenVPN. Ну, момент истины, нажимаю «Apply» в настройках openvpn-интерфейса на микротике, и... теряю связь с объектом вообще. А он километров за 600 от меня.
Сначала грешил на то, что забыл убрать галку Add default route у openvpn-интерфейса. Проверил на тестовом роутере — ни фига, по умолчанию эта галка отсутствует. А шо же за ботва? Повторяю процедуру на тестовом роутере, подключившись к нему по локалке, и... теряю связь уже с тестовым роутером. Правда, как-то странно — winbox не отвалился, но списка интерфейсов получить не удаётся, выдаётся ошибка «out of index». Странно. Однако роутер частично подконтролен — его удаётся перезагружать. И если всё сделать очень быстро, то openvpn-интерфейс подняться ещё не успевает, и его можно отключить. Тогда роутер остаётся на связи и можно им рулить.
В общем, практика показала, что в RouterOS, зашитых в наших микротиках (v4.11) есть суровый баг. Который приводит к тому, что при поднятии openvpn-интерфейса у роутера сваливается WAN-интерфейс в несознанку, и тянет за собой что-то ещё. Только проапгрейдившись до версии 5.21 удалось нормально создать связь по OpenVPN с микротиком. И ещё одно западло в микротиках — они не умеют openvpn по UDP, только TCP. Что заметно снижает скорость, по сравнению с L2TP — так раза в полтора.