Настройка чистого 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-атаки, но при этом процесс настройки клиентов сведется к вводу сервера, логина и пароля. Просто и безопасно!

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

1
2
3
4
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-сервер, то выключите его перед получением сертификата,

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

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

1
2
3
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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:

1
2
3
4
5
6
sudo nano /etc/sysctl.conf
---
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

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

1
2
3
4
5
6
7
8
9
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# В данном случае проще зайти под рутом
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 такую запись:

1
2
3
4
5
6
sudo nano /etc/network/interfaces
---
...
pre-up iptables-restore < /etc/iptables.rules

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

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

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

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

1
2
3
4
5
6
7
8
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

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

1
2
3
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 за его статью и пару дельных советов!