Для начала давайте разберемся зачем нам, собственно, нужен VPN сервер и почему выбор пал на L2TP туннель с IPsec.

VPN сервер есть ни что иное как виртуальная частная сеть, работающая поверх уже существующей сети. То есть это виртуальный туннели между вашими устройствами в сети Интернет. В случае с VPN ваши устройства не нуждаются в физическом подключении к частной сети, а значит находиться они могут в любой точке планеты и работать с другими устройствами так, как если бы они были участниками обычной локальной сети. Все что нужно, чтобы объединить несколько устройств в локальную сеть при помощи VPN это выход в интернет. Еще одним плюсом использования VPN является то, что канал защищен от доступа из вне, так как является зашифрованным.

В качестве примера использования VPN можно привести следующее:

  • Объединение нескольких удаленных друг от друга, например, филиалов, для совместного использования локальных ресурсов – в таком случае создается канал типа точка-точка.
  • Подключение к серверу IP-телефонии, находясь при этом вне локальной сети, чтобы звонить по домашним тарифам находясь при этом в роуминге (например, через WiFi)
  • Выход в интернет с сокрытием реального IP адреса (конечной точкой выхода в интернет будет IP адрес вашего VPN сервера)

Теперь перейдем к L2TP\IPsec. Названые технологии не являются чем-то целым или похожим, но дополняют друг друга. Конкретно в этом случае L2TP отвечает за создание туннеля между сервером и конечными устройствами, а IPsec (произошло от IP Secure) служит для авторизации и шифрования трафика.

Логичный вопрос – почему бы не выбрать «народный» OpenVPN? В Интернете и мануалов полно, и есть куча готовых скриптов чтобы за 2 минуты поднять сервер и выпустить сертификаты. Но меня OpenVPN не устраивает по нескольким причинам:

  • Сертификаты – возиться с ними на мобильных устройствах лично мне не очень удобно, в то время как с L2TP/IPSec достаточно связки логин/пароль/ключ PSK.
  • Нативная поддержка – пока мне не попадалось ни одно устройство, способное «из коробки» работать с OpenVPN, а значит необходимо на каждом клиенте устанавливать отдельно приложение и запихивать в него сертификаты, в то время как L2TP/IPSec подключается в настройках системы клиента.
  • Скорость работы – чисто субъективный пункт. Основывается на личных наблюдениях, поэтому его можете не учитывать, но по моим оценкам разница варьируется где-то в 15-20 процентах скорости работы.

На теории закончили, перейдем к практике.

Разумеется, чтобы поднять VPN сервер, для начала необходимо найти сам сервер. Это может быть что угодно – домашний или рабочий компьютер или сервер в стойке, VDS или VPS.

Мой выбор пал на VPS немецкого хостинга Fornex.com. Там я получил за небольшую сумму сервер на Debian 9, с одним процессорным ядром, гигобайтом оперативной памяти и 10 гигабайтами SSD диска. Стоит отметить что трафик полностью безлимитный, и в придачу ко всему вы получите хорошую админскую панель и внешний немецкий IP.

После того, как у вас появился доступ к VPS, рекомендую сразу создать пользователя, чтобы не подключаться к серверу от имени root. Лучше вообще запретить подключаться к серверу от имени root, и это касается не только нашего случая.

Далее идет фаерволл. В моем случае это набор скриптов CSF+LFD для iptables. О том как его настроить можете прочитать отдельную статью.

!!!В фаерволе необходимо сразу пробросить порты ssh и UDP 500 и 4500. Это важно сделать сразу, чтобы потом не столкнуться с проблемами, но об этом позже.

Установка Docker.

Не вижу смысла расписывать установку Docker’а, лучше сразу зайти на сайт официальной документации и сделать все по пунктам для своей системы.

Переходим непосредственно к VPN.

Прежде всего необходимо скачать образ будущего контейнера с Docker Hub:

docker pull fcojean/l2tp-ipsec-vpn-server

Либо собрать образ вручную:

apt install git -y

git clone https://github.com/fcojean/l2tp-ipsec-vpn-server.git

cd l2tp-ipsec-vpn-server

docker build -t fcojean/l2tp-ipsec-vpn-server .

Теперь мы уже почти готовы собрать контейнер и запустить сервис, осталось только поправить файл конфигурации, куда мы ведем данные для авторизации. Для это создаем файл vpn.env. Директория не важна, главное потом не забудьте вписать путь к файлу в параметры запуска контейнера.

nano vpn.env

Сюда копируем данный текст, изменяя данные на свои:

VPN_IPSEC_PSK=<IPsec pre-shared key>

VPN_USER_CREDENTIAL_LIST=[{"login":"userTest1","password":"test1"}]

VPN_NETWORK_INTERFACE=eth0

Здесь <IPsec pre-shared key> - PSK ключ. Он будет отвечать за шифрование вашего трафика. Ключ берется случайный, однако рекомендую генерировать случайную последовательность из примерно 15-20 символов.

[su_note]Важно – PSK не должен содержать символов = \ ‘ " [/su_note]

userTest1 – Ваш логин для подключения к серверу.

test1 – пароль для подключения к серверу.

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

eth0 – сетевой интерфейс с внешним IP адресом, к которому будут осуществляться подключения.

Для сборки контейнера осталось одна мелочь – включить модуль ядра af_key. Это важно сделать перед запуском контейнера.

modprobe af_key

Теперь создадим и запустим сам контейнер:

docker run \
--name l2tp-ipsec-vpn-server \
--env-file ./путь_к_файлу_vpn.env \
-p 500:500/udp \
-p 4500:4500/udp \
-v /lib/modules:/lib/modules:ro \
-d --privileged \
fcojean/l2tp-ipsec-vpn-server

На этом все. Делаем docker ps чтобы убедиться, что контейнер создан и работает:

docker ps

На выходе получим список работающих контейнеров, среди них будет контейнер с именем l2tp-ipsec-vpn-server. Значит все в порядке, можно пробовать подключиться.

Важно: если вы настраиваете фаервол после запуска контейнера, то рекомендую после этого перезапустить службу Docker

systemctl restart docker

и сам контейнер, чтобы избежать ошибок

docker restart “CONTAINER ID”

Также можно посмотреть логи самого контейнера, где можно просмотреть логин, пароль и PSK ключ, а также другие данные для подключения:

docker logs l2tp-ipsec-vpn-server

На выходе получим следующее

Connect to your new VPN with these details: Server IP: <IP вашего VPN сервера >

IPsec PSK: <PSK ключ для подключения>

Users credentials :

Login : <Логин пользователя> Password : <Пароль пользователя>

Если во время подключения возникли проблемы:

Windows:

Ошибка: The network connection between your computer and the VPN server could not be established because the remote server is not responding.

В этом случае открываем консоль CMD от имени администратора и делаем следующую правку в реестре:

Windwows 7-10 :

REG ADD HKLM\SYSTEM\CurrentControlSet\Services\PolicyAgent /v AssumeUDPEncapsulationContextOnSendRule /t REG_DWORD /d 0x2 /f

Windows XP:

REG ADD HKLM\SYSTEM\CurrentControlSet\Services\IPSec /v AssumeUDPEncapsulationContextOnSendRule /t REG_DWORD /d 0x2 /f

И перезагружаем ПК.

!!!Ошибка: The connection was terminated by the remote computer before it could be completed.

Чтобы исправить данную ошибку, нажмите Пуск – Выполнить – ncpa.cpl

Найдите сетевой VPN адаптер и откройте его свойства

Во вкладке безопасность выберите тип VPN L2TP/IPSec туннель

В пункте проверка подлинности – Разрешить следующие протоколы – поставить галочку на Протокол проверка пароля (CHAP)и все галочки на Протокол Microsoft CHAP.

Нажмите на кнопку Дополнительные параметры и введите в поле ваш PSK ключ.

Android (начиная от 6 и выше):

[su_note]Если при попытке подключения происходит сбой, то необходимо внести правки в конфигурацию ipsec.conf внутри Docker контейнера.[/su_note]

Для этого делаем:

docker exec –t –i “CONTAINER ID” bash

Теперь мы внутри контейнера, далее :

apt update && apt upgrade –y && apt install nano –y

nano /etc/ipsec.conf

Ищем строчки ike= и phase2alg= и дописываем к ним ,aes256-sha2_512. Также находим строку sha2-truncbug=yes и меняем yes на no.

Нажимаем клавиши Ctrl+O, соглашаемся на сохранение и Ctrl+X для выхода из nano.

Далее:

service ipsec restart

И нажимаем Ctrl+D для выхода из контейнера. На этом можно и закончить, но если вы перезапустите контейнер, то изменения сотрутся, и нужно будет вносить их заново, поэтому сделаем commit контейнера

docker commit l2tp-ipsec-vpn-server vpnserver/vidikon

Удалим старый контейнер

docker stop “CONTAINER ID”

docker rm “CONTAINER ID”

И пересоберем контейнер, но уже в качестве образа будем использовать наш свежесозданный образ:

docker run \

--name l2tp-ipsec-vpn-server \

--env-file ./путь_к_файлу_vpn.env \

-p 500:500/udp \    -p 4500:4500/udp \

-v /lib/modules:/lib/modules:ro \

-d --privileged \

vpnserver/vidikon