Делаем свой собственный IKEv2 VPN сервер на базе Ubuntu 20.04

Linux IKEv2 VPN StrongSwan

Введение

Виртуальная частная сеть, или VPN, позволяет надежно шифровать трафик, когда он проходит через ненадежные сети, например, в кафе, на конференции или в аэропорту. А еще получить доступ к вему-то что вам не дают увитеть.

Internet Key Exchange v2 или IKEv2 — это протокол, позволяющий осуществлять прямое туннелирование IPSec между сервером и клиентом. В реализациях IKEv2 VPN IPSec обеспечивает шифрование сетевого трафика. IKEv2 изначально поддерживается на некоторых платформах без дополнительных приложений.

Предпосылки

Для выполнения этого урока вам понадобятся:

  • Один сервер Ubuntu 20.04
  • Немного терпения

Шаг 1 — Установка StrongSwan

Во-первых, мы установим StrongSwan, демон IPSec с открытым исходным кодом, который мы настроим в качестве нашего VPN-сервера. Мы также установим компонент инфраструктуры открытых ключей (PKI), чтобы мы могли создать центр сертификации (CA) для предоставления учетных данных для нашей инфраструктуры.

Начните с обновления локального кеша пакетов:

sudo apt update

Затем установите программное обеспечение, набрав:

sudo apt install strongswan strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins libstrongswan-extra-plugins

Дополнительный libcharon-extauth-plugins пакет используется для обеспечения того, чтобы различные клиенты могли аутентифицироваться на вашем сервере, используя общее имя пользователя и парольную фразу. Пакет libstrongswan-extra-plugins включен, так что Strongswan поддерживает наборы шифров на эллиптических кривых, которые используют Curve25519 набор криптографии.

Тут важно вставить отдельную ремарку: в ubuntu 20.04 по умолчанию не устанавливается плагин md4, который очень важен для Windows клиентов. Без него ничего работать не будет. Этот модуль еще есть в 18.04, но в 20.04 его уже нет. Просто скопируйте /usr/lib/ipsec/plugins/libstrongswan-md4.so или соберите его из исходников (в линуксе всегда так - ха-ха). Я собрал и получилось вот что. Можете скачать и взять себе.

Теперь, когда все установлено, давайте перейдем к созданию наших сертификатов.

Шаг 2 — Создание центра сертификации

Серверу IKEv2 требуется сертификат, чтобы идентифицировать себя для клиентов. Чтобы помочь создать требуемый сертификат, в strongswan-pki пакет входит утилита, вызываемая pkiдля создания центра сертификации и сертификатов сервера.

Для начала давайте создадим несколько каталогов для хранения всех ресурсов, над которыми мы будем работать. Структура каталогов соответствует некоторым каталогам в /etc/ipsec.d, куда мы в конечном итоге переместим все созданные нами элементы:

mkdir -p ~/pki/{cacerts,certs,private}

Затем заблокируйте разрешения, чтобы другие пользователи не могли видеть наши личные файлы:

chmod 700 ~/pki

Теперь, когда у нас есть структура каталогов для хранения всего, мы можем сгенерировать корневой ключ. Это будет 4096-битный ключ RSA, который будет использоваться для подписи нашего корневого центра сертификации.

Выполните эти команды, чтобы сгенерировать ключ:

pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/ca-key.pem

После этого мы можем перейти к созданию нашего корневого центра сертификации, используя только что сгенерированный ключ для подписи корневого сертификата:

pki --self --ca --lifetime 3650 --in ~/pki/private/ca-key.pem --type rsa --dn "CN=VPN root CA" --outform pem > ~/pki/cacerts/ca-cert.pem

Флаг --lifetime 3650 используется для гарантии того, что корневой сертификат центра сертификации будет действителен в течение 10 лет. Корневой сертификат для центра обычно не меняется, поскольку его придется перераспределять на каждый сервер и клиент, которые полагаются на него, поэтому 10 лет — это безопасное значение срока действия по умолчанию.

Вы можете изменить значение отличительного имени (DN) на другое, если хотите. Общее имя (поле CN) здесь является просто индикатором, поэтому оно не должно соответствовать чему-либо в вашей инфраструктуре.

Теперь, когда у нас есть корневой центр сертификации, мы можем создать сертификат, который будет использовать VPN-сервер.

Шаг 3 — Генерация сертификата для VPN-сервера

Теперь мы создадим сертификат и ключ для VPN-сервера. Этот сертификат позволит клиенту проверить подлинность сервера, используя только что созданный нами сертификат ЦС.

Сначала создайте закрытый ключ для VPN-сервера с помощью следующей команды:

pki --gen --type rsa --size 4096 --outform pem > ~/pki/private/server-key.pem

Теперь создайте и подпишите сертификат VPN-сервера с помощью ключа центра сертификации, который вы создали на предыдущем шаге. Выполните следующую команду, но измените поля «Общее имя» (CN) и «Альтернативное имя субъекта» (SAN) на DNS-имя или IP-адрес вашего VPN-сервера:

pki --pub --in ~/pki/private/server-key.pem --type rsa \ 
 | pki --issue --lifetime 1825 \ 
 --cacert ~/pki/cacerts/ca-cert.pem \ 
 --cakey ~/pki/private/ca-key.pem \ 
 --dn "CN=server_domain_or_IP" --san server_domain_or_IP \ 
 --flag serverAuth --flag ikeIntermediate --outform pem \ 
 > ~/pki/certs/server-cert.pem

Параметр --flag serverAuth используется для указания того, что сертификат будет явно использоваться для проверки подлинности сервера до того, как будет установлен зашифрованный туннель. Этот --flag ikeIntermediate параметр используется для поддержки старых клиентов macOS.

Теперь, когда мы сгенерировали все файлы TLS/SSL, которые нужны StrongSwan, мы можем переместить файлы на место в /etc/ipsec.d каталоге, набрав:

sudo cp -r ~/pki/* /etc/ipsec.d/

На этом шаге мы создали пару сертификатов, которая будет использоваться для защиты связи между клиентом и сервером. Мы также подписали сертификаты ключом ЦС, поэтому клиент сможет проверить подлинность VPN-сервера с помощью сертификата ЦС. Когда все эти сертификаты готовы, мы перейдем к настройке программного обеспечения.

Шаг 4 — Настройка StrongSwan

StrongSwan имеет файл конфигурации по умолчанию с некоторыми примерами, но большую часть конфигурации нам придется выполнить самостоятельно. Давайте создадим резервную копию файла для справки, прежде чем начинать с нуля:

sudo mv /etc/ipsec.conf{,.original}

Создайте и откройте новый пустой файл конфигурации с помощью предпочитаемого вами текстового редактора. Здесь мы будем использовать nano:

sudo nano /etc/ipsec.conf

Во-первых, мы скажем StrongSwan регистрировать статусы демона для отладки и разрешать дублирование соединений. Добавьте эти строки в файл /etc/ipsec.conf:

config setup
    charondebug="ike 1, knl 1, cfg 0"
    uniqueids=no

Затем мы создадим раздел конфигурации для нашей VPN. Мы также скажем StrongSwan создать VPN-туннели IKEv2 и автоматически загрузить этот раздел конфигурации при запуске. Добавьте в файл следующие строки:

. . .
conn ikev2-vpn
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes

Мы также настроим обнаружение мертвых узлов, чтобы очищать любые «зависшие» соединения в случае неожиданного отключения клиента. Добавьте эти строки:

. . .
conn ikev2-vpn
    . . .
    dpdaction=clear
    dpddelay=300s
    rekey=no

Далее мы настроим параметры IPSec «левой» стороны сервера. Каждый из следующих параметров гарантирует, что сервер настроен на прием соединений от клиентов и правильную идентификацию. Вы добавите каждый из этих параметров в /etc/ipsec.conf файл после того, как ознакомитесь с тем, что они из себя представляют и почему они используются:

  • left=%any Это %any значение гарантирует, что сервер будет использовать сетевой интерфейс, через который он получает входящие соединения для последующей связи с клиентами. Например, если вы подключаетесь к клиенту через частную сеть, сервер будет использовать частный IP-адрес, по которому он получает трафик для остальной части соединения.
  • leftid=@server_domain_or_IP Этот параметр управляет именем, которое сервер представляет клиентам. В сочетании со следующей опцией leftcert этот leftid параметр гарантирует, что настроенное имя сервера и отличительное имя (DN), содержащееся в общедоступном сертификате, совпадают.
  • leftcert=server-cert.pem Этот параметр представляет собой путь к общедоступному сертификату для сервера, который вы настроили на шаге 3. Без него сервер не сможет аутентифицировать себя с клиентами или завершить согласование настройки IKEv2.
  • leftsendcert=always Это always значение гарантирует, что любой клиент, который подключается к серверу, всегда будет получать копию общедоступного сертификата сервера как часть первоначальной настройки подключения.
  • leftsubnet=0.0.0.0/0 Последняя «левая» опция, которую вы добавите, сообщает клиентам о доступных подсетях за сервером. В этом случае 0.0.0.0/0 используется для представления всего набора адресов IPv4, а это означает, что сервер по умолчанию будет указывать клиентам отправлять весь свой трафик через VPN.

Теперь, когда вы знакомы с каждым из соответствующих «левых» параметров, добавьте их все в файл следующим образом:

. . .
conn ikev2-vpn
    . . .
    left=%any
    leftid=@server_domain_or_IP
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0

Далее мы можем настроить параметры IPSec «правой» стороны клиента. Каждый из следующих параметров сообщает серверу, как принимать подключения от клиентов, как клиенты должны аутентифицироваться на сервере, а также диапазоны частных IP-адресов и DNS-серверы, которые будут использовать клиенты. Добавьте каждый из этих параметров в /etc/ipsec.conf файл, как только вы ознакомитесь с тем, что они собой представляют и почему они используются:

  • right=%any Параметр %any для right стороны подключения указывает серверу принимать входящие подключения от любого удаленного клиента.
  • rightid=%any Этот параметр гарантирует, что сервер не будет отклонять подключения от клиентов, предоставляющих удостоверение, до того, как будет установлен зашифрованный туннель.
  • rightauth=eap-mschapv2 Этот параметр настраивает метод аутентификации, который клиенты будут использовать для аутентификации на сервере. eap-mschapv2 здесь используется для широкой совместимости для поддержки таких клиентов, как устройства Windows, macOS и Android.
  • rightsourceip=10.10.10.0/24 Этот параметр указывает серверу назначать частные IP-адреса клиентам из указанного 10.10.10.0/24 пула IP-адресов.
  • rightdns=8.8.8.8,8.8.4.4 Эти IP-адреса являются общедоступными преобразователями DNS Google. Их можно изменить, чтобы использовать другие общедоступные преобразователи, преобразователи VPN-сервера или любые другие преобразователи, доступные клиентам.
  • rightsendcert=never Этот параметр указывает серверу, что клиентам не нужно отправлять сертификат для аутентификации.

Теперь, когда вы знакомы с необходимыми параметрами «правильной» стороны для VPN, добавьте следующие строки в /etc/ipsec.conf:

. . .
conn ikev2-vpn
    . . .
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never

Теперь мы скажем StrongSwan запрашивать у клиента учетные данные пользователя при подключении:

. . .
conn ikev2-vpn
    . . .
    eap_identity=%identity

Наконец, добавьте следующие строки для поддержки клиентов Linux, Windows, macOS, iOS и Android. Эти строки определяют различные алгоритмы обмена ключами, хеширования, аутентификации и шифрования (обычно называемые наборами шифров ), которые StrongSwan позволит использовать различным клиентам:

. . .
conn ikev2-vpn
    . . .
    ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
    esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!

Каждый поддерживаемый набор шифров отделяется от других запятой. Например chacha20poly1305-sha512-curve25519-prfsha512 есть один, а aes256gcm16-sha384-prfsha384-ecp384есть другой. Наборы шифров, перечисленные здесь, выбраны для обеспечения максимальной совместимости с клиентами Windows, macOS, iOS, Android и Linux.

Полный файл конфигурации должен выглядеть так:

config setup
    charondebug="ike 1, knl 1, cfg 0"
    uniqueids=no

conn ikev2-vpn
    auto=add
    compress=no
    type=tunnel
    keyexchange=ikev2
    fragmentation=yes
    forceencaps=yes
    dpdaction=clear
    dpddelay=300s
    rekey=no
    left=%any
    leftid=@server_domain_or_IP
    leftcert=server-cert.pem
    leftsendcert=always
    leftsubnet=0.0.0.0/0
    right=%any
    rightid=%any
    rightauth=eap-mschapv2
    rightsourceip=10.10.10.0/24
    rightdns=8.8.8.8,8.8.4.4
    rightsendcert=never
    eap_identity=%identity
    ike=chacha20poly1305-sha512-curve25519-prfsha512,aes256gcm16-sha384-prfsha384-ecp384,aes256-sha1-modp1024,aes128-sha1-modp1024,3des-sha1-modp1024!
    esp=chacha20poly1305-sha512,aes256gcm16-ecp384,aes256-sha256,aes256-sha1,3des-sha1!

Сохраните и закройте файл, как только убедитесь, что вы правильно добавили каждую строку.

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

Шаг 5 — Настройка аутентификации VPN

Наш VPN-сервер теперь настроен на прием клиентских подключений, но у нас еще нет настроенных учетных данных. Нам нужно настроить пару вещей в специальном файле конфигурации с именем ipsec.secrets:

  • Нам нужно указать StrongSwan, где найти закрытый ключ для нашего сертификата сервера, чтобы сервер мог аутентифицировать клиентов.
  • Нам также необходимо настроить список пользователей, которым будет разрешено подключаться к VPN.

Откроем файл секретов для редактирования:

sudo nano /etc/ipsec.secrets

Во-первых, мы сообщим StrongSwan, где найти наш закрытый ключ и как его разобрать. /etc/ipsec.secrets

: RSA "server-key.pem"

Убедитесь, что строка начинается с : символа и после него стоит пробел, чтобы вся строка читалась как : RSA "server-key.pem".

Затем мы определим учетные данные пользователя. Вы можете составить любую комбинацию имени пользователя или пароля, которая вам нравится:

your_username : EAP "your_password"

Сохраните и закройте файл. Теперь, когда мы закончили работу с параметрами VPN, перезапустим службу VPN, чтобы наша конфигурация применилась:

sudo systemctl restart strongswan-starter

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

Шаг 6 — Настройка брандмауэра и IP-переадресации ядра

Когда конфигурация StrongSwan завершена, нам нужно настроить брандмауэр, чтобы разрешить прохождение и пересылку VPN-трафика.

Если вы следовали обязательному руководству по начальной настройке сервера, у вас должен быть включен брандмауэр UFW. Если вы еще не настроили UFW, вам следует начать с добавления правила, разрешающего SSH-соединения через брандмауэр, чтобы ваш текущий сеанс не закрывался при включении UFW:

sudo ufw allow OpenSSH

Затем включите брандмауэр, набрав:

sudo ufw enable

Затем добавьте правило, разрешающее трафик UDP на стандартные порты IPSec, 500 и 4500:

sudo ufw allow 500,4500/udp

Далее мы откроем один из файлов конфигурации UFW, чтобы добавить несколько низкоуровневых политик для маршрутизации и пересылки пакетов IPSec. Однако прежде чем мы сможем это сделать, нам нужно найти, какой сетевой интерфейс на нашем сервере используется для доступа в Интернет. Найдите этот интерфейс, запросив устройство, связанное с маршрутом по умолчанию:

ip route show default

Ваш общедоступный интерфейс должен следовать за словом «dev». Например, этот результат показывает интерфейс с именем eth0, который выделен в следующем примере:

default via your_server_ip dev eth0 proto static

Если у вас есть общедоступный сетевой интерфейс, откройте /etc/ufw/before.rules файл в текстовом редакторе. Правила в этом файле добавляются в брандмауэр перед остальными обычными правилами ввода и вывода. Они используются для настройки преобразования сетевых адресов (NAT), чтобы сервер мог правильно маршрутизировать соединения с клиентами и Интернетом.

sudo nano /etc/ufw/before.rules

В верхней части файла (перед *filter строкой) добавьте следующий блок конфигурации. Измените каждый экземпляр eth0 в приведенной выше конфигурации, чтобы он соответствовал имени интерфейса, которое вы нашли с помощью ip route. Строки *nat создают правила, чтобы брандмауэр мог правильно маршрутизировать и управлять трафиком между VPN-клиентами и Интернетом. Строка *mangle регулирует максимальный размер сегмента пакета, чтобы предотвратить возможные проблемы с некоторыми VPN-клиентами:

*nat
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
COMMIT

*mangle
-A FORWARD --match policy --pol ipsec --dir in -s 10.10.10.0/24 -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360
COMMIT

*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
. . .

Далее после *filter строк определения цепочки и добавьте еще один блок конфигурации:

. . .
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]

-A ufw-before-forward --match policy --pol ipsec --dir in --proto esp -s 10.10.10.0/24 -j ACCEPT
-A ufw-before-forward --match policy --pol ipsec --dir out --proto esp -d 10.10.10.0/24 -j ACCEPT

Эти строки указывают брандмауэру пересылать трафик ESP (Encapsulating Security Payload), чтобы VPN-клиенты могли подключаться. ESP обеспечивает дополнительную безопасность наших пакетов VPN, поскольку они проходят через ненадежные сети.

Перед перезапуском брандмауэра мы изменим некоторые параметры сетевого ядра, чтобы разрешить маршрутизацию с одного интерфейса на другой. Файл, управляющий этими настройками, называется /etc/ufw/sysctl.conf. Нам нужно настроить несколько вещей в файле.

Сначала необходимо включить пересылку пакетов IPv4, чтобы трафик мог перемещаться между VPN и общедоступными сетевыми интерфейсами на сервере. Далее мы отключим обнаружение Path MTU, чтобы предотвратить проблемы с фрагментацией пакетов. Наконец, мы не будем принимать перенаправления ICMP и отправлять перенаправления ICMP, чтобы предотвратить атаки посредника.

Откройте файл конфигурации параметров ядра UFW с помощью nanoлюбого текстового редактора:

sudo nano /etc/ufw/sysctl.conf

Теперь добавьте следующий net/ipv4/ip_forward=1 параметр в конец файла, чтобы разрешить пересылку пакетов между интерфейсами:

. . .
net/ipv4/ip_forward=1
. . .
net/ipv4/conf/all/accept_redirects=0
net/ipv4/conf/all/send_redirects=0
. . .
net/ipv4/ip_no_pmtu_disc=1

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

sudo ufw disable 
sudo ufw enable

Вам будет предложено подтвердить процесс. Введите Y, чтобы снова включить UFW с новыми настройками.

Шаг 7 — Тестирование VPN-подключения в Windows

Теперь, когда у вас все настроено, пришло время попробовать. Во-первых, вам нужно скопировать созданный сертификат ЦС и установить его на свои клиентские устройства, которые будут подключаться к VPN. Самый простой способ сделать это — войти на свой сервер и вывести содержимое файла сертификата:

cat /etc/ipsec.d/cacerts/ca-cert.pem

Чтобы импортировать сертификат корневого ЦС с помощью PowerShell, сначала откройте командную строку PowerShell с правами администратора.

Import-Certificate -CertStoreLocation cert:\LocalMachine\Root\ -FilePath ~\Documents\ca-cert.pem

Теперь, чтобы настроить VPN с помощью PowerShell, выполните следующую команду. Замените DNS-имя или IP-адрес вашего сервера в -ServerAddress строке. Различные флаги гарантируют, что Windows правильно настроена с соответствующими параметрами безопасности, которые соответствуют параметрам, установленным в файлах /etc/ipsec.conf.

Add-VpnConnection -Name "VPN Connection" ` 
 -ServerAddress "server_domain_or_IP" ` 
 -TunnelType "IKEv2" ` 
 -AuthenticationMethod "EAP" ` 
 -EncryptionLevel "Maximum" ` 
 -RememberCredential

Set-VpnConnectionIPsecConfiguration -Name "VPN Connection" ` 
 -AuthenticationTransformConstants GCMAES256 ` 
 -CipherTransformConstants GCMAES256 ` 
 -DHGroup ECP384 ` 
 -IntegrityCheckMethod SHA384 ` 
 -PfsGroup ECP384 ` 
 -EncryptionMethod GCMAES256

Подключение к VPN

После импорта сертификата и настройки VPN любым из этих способов ваше новое VPN-подключение будет отображаться в списке сетей. Выберите VPN и нажмите «Подключиться» . Вам будет предложено ввести имя пользователя и пароль. Введите их, нажмите OK , и вы будете подключены.