Для начала давайте разберемся зачем нам, собственно, нужен 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