Поднимаем свой VPN – IKEv2 на Ubuntu

IKEv2 на Ubuntu

Добрый день, дорогие гости и читатели. Сегодня я публикую последнюю на ближайшее время статью на тему запуска своего VPN и эта статья о запуске собственного IKEv2 на Ubuntu 16.04.

Для выполнения задачи нам понадобится:

  • VPS или выделенный сервер с установленной ОС Ubuntu 16.04 LTS и внешним IP адресом;
  • Зарегистрированный и делегированный домен;
  • Уметь добавлять записи в DNS вашего домена.

Напоминаю, что дешевые VPS во Франции для запуска своего VPN вы можете посмотреть здесь. Для примера, в статье я использую вымышленные данные: поддомен vpn.alexell.ru для подключения к VPN, внешний IP сервера 55.55.55.55 и почту на домене test@alexell.ru. При настройке своего IKEv2 на Ubuntu по этой статье, заменяйте эти значения на свои собственные.

Итак, если все из списка выше у вас имеется, тогда начнем приготовления:

  1. Добавляем A запись в DNS домена чтобы сопоставить поддомен vpn.alexell.ru с IP адресом сервера 55.55.55.55, на котором будем запускать VPN.
  2. Создаем почту в собственном домене, например test@alexell.ru (не обязательно);
  3. Определяемся с внутренней подсетью для клиентов. Для примера возьмем 10.10.1.0/24;
  4. Подключаемся по SSH к нашему VPS, например через PuTTY.

Настройки системы и фаервола

Открываем файл /etc/sysctl.conf и добавляем в самый конец следующие строки:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1

Это активирует пересылку пакетов и отключит ICP-редиректы.

Стираем все правила фаервола командой iptables -F. Если у вас вдруг не установлен iptables, то просто установите его командой apt-get install iptables.

Узнайте название вашего сетевого интерфейса командой ifconfig. Запомните буквенный префикс, он может быть eth, ens или абсолютно другим. Например, если ваш интерфейс называется ens3, как было у меня, то при добавлении правил фаервола ниже, мы будем использовать обозначение ens+.

Для корректной работы NAT и протоколов IKE и ESP добавляем следующие правила:

iptables --append INPUT --protocol udp --destination-port 500 --jump ACCEPT
iptables --append INPUT --protocol udp --destination-port 4500 --jump ACCEPT
iptables --append INPUT --protocol esp --jump ACCEPT
iptables -t nat -A POSTROUTING -j SNAT --to-source 55.55.55.55 -o ens+

Не забудьте заменить 55.55.55.55 на внешний IP вашего сервера.

Теперь нужно сохранить правила, чтобы они работали после перезагрузки системы. Сделать это можно по старинке или более универсальным методом. С ним можете ознакомиться здесь, а я продолжу о старом методе.

Сохраняем правила NAT в файл командой:

iptables-save > /etc/iptables.conf

Открываем файл /etc/network/interfaces и добавляем в конец файла строку:

pre-up /sbin/iptables-restore < /etc/iptables.conf

Открываем файл /etc/rc.local и добавляем в конец файла, но до строки exit 0 следующую строку:

for vpn in /proc/sys/net/ipv4/conf/*; do echo 0 > $vpn/accept_redirects; echo 0 > $vpn/send_redirects; done

Теперь можно перезагрузить сервер для применения всех изменений.

Получение SSL сертификата для IKEv2 на Ubuntu

Клиенты, подключающиеся к нашему IKEv2 будут проверять подлинность сервера, дабы исключить возможность того, что какой-то другой сервер «притворяется» нашим (атаки класса MITM). Получить SSL сертификат можно в любом действующем удостоверяющем центре за деньги, например GlobalSign и Comodo, но мы воспользуемся бесплатным Let’s Encrypt.

Установим пакет software-properties-common, который позволит подключать внешние репозитории:

apt-get install software-properties-common

Установим утилиту certbot:

add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install certbot

Получаем сертификат следующей командой:

certbot certonly --standalone --agree-tos -m test@alexell.ru -d vpn.alexell.ru

Не забудьте изменить ваш домен/поддомен и email. После окончания процедуры, в папке /etc/letsencrypt/live/vpn.alexell.ru появятся файлы: chain.pem – корневой и промежуточный сертификаты, cert.pem – сертификат сервера и privkey.pem – приватный ключ.

UPD 2023: На новых Ubuntu, например 20 или 22, для установки certbot лучше воспользоваться менеджером snap:

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot certonly --standalone --agree-tos -m test@alexell.ru -d vpn.alexell.ru

Установка и настройка IPsec

На этом шаге мы установим демон для работы IPsec и набор плагинов, в которых есть нужный нам EAP-MSCHAPv2 для аутентификации клиентов.

apt-get install strongswan libcharon-extra-plugins

Теперь нам необходимо создать ссылки на полученные сертификаты в директории ipsec.d, внутри которой находятся cacerts (для корневых сертификатов), certs (для сертификатов X.509 и PGP) и private для приватных ключей.

Для этого выполним команды:

sudo ln -s /etc/letsencrypt/live/vpn.alexell.ru/chain.pem /etc/ipsec.d/cacerts/ca.pem
sudo ln -s /etc/letsencrypt/live/vpn.alexell.ru/cert.pem /etc/ipsec.d/certs/certificate.pem
sudo ln -s /etc/letsencrypt/live/vpn.alexell.ru/privkey.pem /etc/ipsec.d/private/key.pem

Открываем файл /etc/ipsec.conf, стираем его содержимое и добавляем следующую конфигурацию:

# ipsec.conf - strongSwan IPsec configuration file

config setup
  #  Allows few simultaneous connections with one user account.
  #  By default only one active connection per user allowed.
  #  This option also usefull if you have limited rightsourceip pool and want to kick your ghost connection while reconnecting.
  uniqueids=yes

  # Increase debug level
  #charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2,  mgr 2"

conn %default
  keyexchange=ikev2

  # More advanced ciphers. Uncomment if you need it.
  # Default ciphers will works on most platforms.
  #ike=aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes256-aes128-sha256-sha1-modp2048-modp4096-modp1024,aes256-sha1-modp1024,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16-aes256gcm12-aes128gcm16-aes128gcm12-sha256-sha1-modp2048-modp4096-modp1024,3des-sha1-modp1024!
  #esp=aes128-aes256-sha1-sha256-modp2048-modp4096-modp1024,aes128-sha1,aes128-sha1-modp1024,aes128-sha1-modp1536,aes128-sha1-modp2048,aes128-sha256,aes128-sha256-ecp256,aes128-sha256-modp1024,aes128-sha256-modp1536,aes128-sha256-modp2048,aes128gcm12-aes128gcm16-aes256gcm12-aes256gcm16-modp2048-modp4096-modp1024,aes128gcm16,aes128gcm16-ecp256,aes256-sha1,aes256-sha256,aes256-sha256-modp1024,aes256-sha256-modp1536,aes256-sha256-modp2048,aes256-sha256-modp4096,aes256-sha384,aes256-sha384-ecp384,aes256-sha384-modp1024,aes256-sha384-modp1536,aes256-sha384-modp2048,aes256-sha384-modp4096,aes256gcm16,aes256gcm16-ecp384,3des-sha1!

  # Dead peer detection will ping clients and terminate sessions after timeout
  dpddelay=300s
  dpdtimeout=2000s
  dpdaction=clear

  # Left is a server side
  leftcert=certificate.pem
  leftsendcert=always

  # Routes pushed to clients. If you don't have ipv6 then remove ::/0
  leftsubnet=0.0.0.0/0

  #rekey=no
  #reauth=no
  auto=add
  fragmentation=yes

  #authby=pubkey
  #left=%any
  #leftid=vpn.alexell.ru
  #right=%any

  # Right is a remote client side
  rightsourceip=10.10.1.0/24
  rightdns=8.8.8.8

  eap_identity=%identity

# All clients
conn ikev2-mschapv2
  leftid=vpn.alexell.ru
  rightauth=eap-mschapv2

Здесь leftcert – имя сертификата из /etc/ipsec.d/certs, leftid – ваш поддомен, на который был выдан сертификат, rightsourceip – пул внутренних IP адресов для клиентов, rightdns – DNS сервер, который будет использоваться при соединении через наш VPN.

Учетные записи для наших клиентов IKEv2  мы будем добавлять в файл /etc/ipsec.secrets, откройте его и замените содержимое на следующую конфигурацию:

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

# This is private key located at /etc/ipsec.d/private/key.pem
: RSA key.pem

# Create VPN users accounts
user : EAP "password"

Здесь : RSA key.pem – имя файла приватного ключа из /etc/ipsec.d/private, user – имя пользователя, password – пароль. В будущем, учетные записи вы можете добавлять в этот файл по аналогии.

Перезапускаем демон:

ipsec restart

Теперь можно проверить корректность подключения сертификатов. Для этого выполните команду ipsec listcerts. Результат выполнения команды будет примерно такой:

List of X.509 End Entity Certificates:

  altNames:  vpn.alexell.ru
  subject:  "CN=vpn.alexell.ru"
  issuer:   "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3"
  serial:    03:ba:ba:68:d6:11:06:2d:69:e8:7e:f6:f9:05:cf:6a:27:29
  validity:  not before May 03 17:34:04 2018, ok
             not after  Aug 01 17:34:04 2018, ok 
  pubkey:    RSA 2048 bits, has private key
  keyid:     59:d3:1c:bb:5a:bf:fd:e7:4b:0d:7d:dd:09:d8:74:69:73:e8:6a:1f
  subjkey:   ee:3d:f6:f5:c6:11:1d:fa:3e:f2:e9:15:a9:52:ed:d1:cb:58:a8:63
  authkey:   a8:4a:6a:63:04:7d:dd:ba:e6:d1:39:b7:a6:45:65:ef:f3:a8:ec:a1

Обратите внимание, фраза has private key должна быть обязательно.

Получить информацию о загруженной конфигурации и текущем состоянии можно командой:

ipsec statusall

Теперь можно подключиться к вашему новому VPN и убедиться что все работает. При подключении, выбирайте тип IKEv2.

Дополнительная информация об IKEv2 на Ubuntu

Авторизация и проблемы с подключением

При использовании приведенной конфигурации, клиент с одной учетной записью сможет иметь только одно открытое соединение с VPN одновременно, т.е. если под этим же логином произойдет второе подключение при активном первом – первое будет разъединено. Если вы хотите сделать одну общую учетную запись, например anonymous, то пропишите логин и пароль в ipsec.secrets, затем откройте ipsec.conf и измените uniqueids=yes на uniqueids=no.

Если у вас возникнут проблемы с подключением или вылетами на некоторых мобильных устройствах (вообще, эту конфигурацию я проверял только на Windows 7, 10 и iOS) или появится желание настроить свой IKEv2 на Ubuntu таким образом, чтобы под одной учетной записью можно было подключаться одновременно с одного мобильного устройства и с одного ПК, то в файле ipsec.conf замените единую секцию подключения на несколько секций под разные устройства (для лучшей совместимости).

Убираем эту секцию:

# All clients
conn ikev2-mschapv2
  leftid=vpn.alexell.ru
  rightauth=eap-mschapv2

Добавляем вместо нее 2 секции:

# BlackBerry, Windows, Android
conn ikev2-mschapv2
  rightauth=eap-mschapv2

# macOS, iOS
conn ikev2-mschapv2-apple
  rightauth=eap-mschapv2
  leftid=vpn.alexell.ru

Можно еще попробовать такой вариант:

# 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.alexell.ru

Обновление сертификатов

Как известно, сертификаты Let’s Encrypt выдаются на 3 месяца, после чего их необходимо обновлять.

Для этого добавляем ежедневное ночное задание в etc/crontab:

0  3	* * *	root	certbot renew --noninteractive

UPD 2023: если вы устанавливали certbot на новых Ubuntu 20 или 22 через snap, то сертификаты там продляются автоматически и делать вообще ничего не нужно. Разве что убедиться что сервис продления запущен: sudo systemctl status snap.certbot.renew.service

Также вы можете запустить симуляцию продления: sudo certbot renew --dry-run

Хранение логов

Если вы не хотите хранить логи работы IKEv2 на Ubuntu и подключений клиентов, тогда можно писать их в /dev/null, для чего просто выполните команды:

sudo rm /var/log/syslog && sudo ln -s /dev/null /var/log/syslog
sudo rm /var/log/auth.log && sudo ln -s /dev/null /var/log/auth.log