Настройка чистого IPsec посредством strongSwan с максимальной совместимостью

В интернете не так уж много хороших статей по поводу настройки чистого IPsec без использования L2TP. Несмотря на то, что гайды в интернете хоть и имеются, все они имеют какие-то недостатки. К примеру, большинство уже устарели и потеряли свою актуальность. Например, зачем нам поддержка IKEv1, если в текущих macOS и iOS уже добавили поддержку IKEv2? На момент публикации этой статьи IKEv2 поддерживается практически везде:

Мобильные ОС:

  • Android (через приложение strongSwan)
  • iOS8+
  • Windows Phone 8.1
  • Windows 10 Mobile
  • BlackBerry 10+

Настольные ОС:

  • Windows
  • macOS
  • Linux

Разумеется речь преимущественно про современные ОС, но к примеру в Windows IKEv2 есть ещё со времен Vista. А вот в macOS поддержка появилась совсем недавно. Ворошить трупы мы сегодня не будем, расчет на людей, которые стабильно обновляют свои ОС. Благо Apple практически всегда предоставляет такую возможность, а с другими ОС проблем возникнуть не должно, они поддерживают данный протокол давным давно.

Исключением будет лишь одна платформа -- Android. Как гласит заголовок статьи, я собираюсь достичь максимальной совместимости со всеми платформами, поэтому мы добавим поддержку IKEv1 c аунтефикацией через Xauth. Таким образом в случае с Android мы будем иметь два способа подключения:

  1. Нативно, через системные настройки, используя IPsec Hybrid RSA
  2. Через официальное приложение strongSwan, используя IKEv2

Многие упрекают IPsec в тяжелой настройке и отсутствии некой гибкости, и поэтому советуют OpenVPN. Но у OpenVPN есть фатальный недостаток -- нативно этот протокол нигде не поддерживается, за очень редким исключением. Другими словами OpenVPN требует приложение-клиент, которое пользователь должен предварительно скачать и настроить. Более того, OpenVPN нет в природе для Windows Phone, Windows 10 Mobile и BlackBerry. А я как раз являюсь владельцем этих устройств.

Дисклеймер: С IPsec, strongSwan, iptables и dnsmasq я имел дело впервые, так что смело кидайте камни в комментариях, буду рад любым советам. Для меня главным была работоспособность.

В качестве сервера я использую VPS на базе Debian Jessie, поэтому все команды будут актуальны именно для него. Однако их можно будет с легкостью применить в любом другом Linux-дистрибутиве. Что ж, приступим.

Первым делом следует обсудить подводные камни, которые я встретил. Их всего два, но решить их сразу у меня не удалось:

  1. В интернете никто не уделял внимания настройке NAT и iptables. Видимо это слишком очевидно для любого сисадмина.
  2. В Windows 10 и Windows 10 Mobile по умолчанию включен split tunneling, поэтому пришлось сильно помучаться, чтобы всё работало и на этих платформах. (Если в настольной Windows 10 split tunneling ещё можно было отключить через PowerShell и спрятанной галочкой в старом GUI, то в Windows 10 Mobile ни галочки, ни PowerShell нет).

Сам процесс аутентификации мы будем проходить с использованием логина и пароля. Поэтому нам не придется таскать с собой сертификат и PSK-ключ, который могут украсть. Данный метод сведет на нет MITM-атаки, но при этом процесс настройки клиентов сведется к вводу сервера, логина и пароля. Просто и безопасно!

Первым делом установим набор ПО, который нам понадобится:

sudo apt-get install strongswan libcharon-extra-plugins dnsmasq
 
# Let's Encrypt загружаем из jessie-backports
sudo apt-get install -t jessie-backports letsencrypt

Процесс настройки сведем к нескольким этапам:

  1. Получение сертификата средствами Let's Encrypt
  2. Конфигурация strongSwan
  3. Настройка iptables
  4. Конфигурация dnsmasq

Получение сертификата

Если у вас есть HTTP-сервер, то выключите его перед получением сертификата,

sudo letsencrypt certonly --standalone --email mail@domain.xyz -d domain.xyz --rsa-key-size 4096

Теперь скопируем полученные сертификаты в директорию /etc/ipsec.d. Помимо этого мы загрузим сертификат CA с официального сайта Let's Encrypt:

cp /etc/letsencrypt/live/domain.xyz/fullchain.pem /etc/ipsec.d/certs
cp /etc/letsencrypt/live/domain.xyz/privkey.pem /etc/ipsec.d/private
wget -O /etc/ipsec.d/cacerts/lets-encrypt-x3-cross-signed.pem https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem

Конфигурация strongSwan

Для настройки нам потребуется лишь отредактировать основной файл конфигурации:

sudo nano /etc/ipsec.conf
 
---
 
config setup
	# Раскомментируйте, если хотите несколько подключений на один логин
	# uniqueids=no	

conn %default
	dpdaction=clear
	dpddelay=35s
	dpdtimeout=300s

	fragmentation=yes
	rekey=no

	left=%any
	leftsubnet=0.0.0.0/0
	leftcert=fullchain
	leftfirewall=yes
	leftsendcert=always

	right=%any
	rightsourceip=192.168.103.0/24
	rightdns=8.8.8.8,8.8.4.4

	eap_identity=%identity

# IKEv2
conn IPSec-IKEv2
	keyexchange=ikev2
	auto=add

# BlackBerry, Windows, Android
conn IPSec-IKEv2-EAP
	also="IPSec-IKEv2"
	rightauth=eap-mschapv2

# macOS, iOS
conn IKEv2-MSCHAPv2-Apple
	also="IPSec-IKEv2"
	rightauth=eap-mschapv2
	leftid=vpn.krasovsky.me

# Android IPsec Hybrid RSA
conn IKEv1-Xauth
	keyexchange=ikev1
	rightauth=xauth
	auto=add

include /var/lib/strongswan/ipsec.conf.inc

Теперь нужно включить два параметра в конфигурационном файле ОС /etc/sysctl.conf:

sudo nano /etc/sysctl.conf
 
---
 
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Напоследок заполняем файл /etc/ipsec.secrets

sudo nano /etc/ipsec.secrets
 
---
 
: RSA privkey.pem

user1 : EAP "password1"
user2 : XAUTH "password2"
"Windows Phone\user3" : EAP "password3"

Отдельно стоит заметить, что Windows Phone 8.1 автоматически добавляет имя домена "Windows Phone". Его можно сменить в настройка телефона в меню "Об устройстве".

Настройка iptables

Воспользуемся командами iptables-restore и iptables-save, предварительно создав пустой файл /etc/iptables.rules:

# В данном случае проще зайти под рутом
su

iptables -t nat -A POSTROUTING -s 192.168.103.0/24 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.103.0/24 -o eth0 -j MASQUERADE

# Настройка MTU для Android IKEv1
iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir in --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
iptables -t mangle -I FORWARD -p tcp -m policy --pol ipsec --dir out --syn -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
 
# Сохраняем iptables в пустой файл:
iptables-save > /etc/iptables.rules
 
# Ctrl+D - выходим из рута

После этого нужно будет подредактировать файл /etc/network/interfaces, добавив к интерфейсу eth0 такую запись:

sudo nano /etc/network/interfaces
 
---
 
...
pre-up iptables-restore < /etc/iptables.rules

Таким образом новые iptables будут прогружаться сразу же после старта системы. Кстати остальными правилами займется сам strongSwan, так как мы указали в конфигурации параметр leftfirewall = yes.

Конфигурация dnsmasq

Последним этапом нашей настройки будет DHCP-сервер, который будет заниматься раздачей маршрутов. В стандартной конфигурации можно обойтись и без него, но тогда нужно будет выключать пресловутый split tunneling. А в случае с Windows 10 Mobile это вовсе невозможно.

Так как dnsmasq уже установлен, остается только сконфигурировать:

sudo nano /etc/dnsmasq.conf
 
---
 
dhcp-vendorclass=set:msipsec,MSFT 5.0
dhcp-range=tag:msipsec,192.168.103.0,static
dhcp-option=tag:msipsec,6
dhcp-option=tag:msipsec,249, 0.0.0.0/1,0.0.0.0, 128.0.0.0/1,0.0.0.0

Наконец перезапускаем сервисы:

sudo systemctl restart ipsec
sudo systemctl restart dnsmasq
sudo systemctl restart networking

Впрочем можно просто перезагрузить весь сервер командой sudo reboot. Настройка клиентов сводится к указанию протокола IKEv2, имени сервера, логина и пароля.

Собственно как уже было сказано, данная конфигурация работает на всех этих платформах! (По ссылкам инструкции по настройке в картинках).

Мобильные ОС:

Настольные ОС:

C каким протоколом можно добиться такого же разнобразия?

На данный момент под вопросом остаются три актуальных платформы:

  • Sailfish OS
  • Tizen
  • Ubuntu Touch

По этим трём платформам я не нашел никакой путевой информации. Судя по всему на Ubuntu Touch есть только OpenVPN, а на Sailfish и Tizen за VPN ещё не взялись вовсе. Желательно проверить эту информацию, но устройств для тестирования не имею.

P.S. Отдельное спасибо хабровчанину ValdikSS за его статью и пару дельных советов!