Мне понадобился VPN, работающий поверх HTTPS, чтобы его можно было протащить через корпоративный firewall. Одним из вариантов реализации такого VPN является SSTP, однако это разработка Microsoft и свободных реализаций до недавнего времени не было.
https://github.com/sorz/sstp-server
https://www.digitalocean.com/community/tutorials/how-to-setup-a-multi-protocol-vpn-server-using-softether
https://habrahabr.ru/post/211136/
http://www.prianichnikov.info/2015/06/softether-vpn-debian.html
https://linuxconfig.org/setting-up-softether-vpn-server-on-ubuntu-16-04-xenial-xerus-linux
Сервер SSTP на базе Ubuntu + SoftEther
Softether - это мультиплатформенный, мультипротокольный VPN-сервер. Моя задача - поднять на базе него SSTP VPN-сервер (для того, чтобы выбраться из-под гнёта корпоративного файервола имя которому - ironport).
SSTP за Haproxy с SNI
В моем случае, сам сервер Softether находится за NAT и HAproxy. То есть на роутере прокинут (mapping) порт 443 на lxc-контейнер с HAProxy, на котором, в свою очередь, настроен проброс HTTPS траффика по SNI (mode tcp) на контейнер с SoftEther. Фактически, HAProxy еще раз мапит порт 443.
Эта конфигурация позволяет держать на одном хосте и несколько HTTPS-сайтов (каждый со своим сертификатом), а также SoftEther. При этом, каждый сервис работает в собственном независимом lxc-контейнере.
Нужно учитывать, что SNI присутсвует не в в каждом пакете SSTP-трафика. Поэтому через HAProxy с SNI трафик SSTP будет нормально проходить только когда контейнер указан в качестве default_backend, либо будет использоватьться конфигурация, описанная тут:
frontend main 192.168.0.3:443 ssl tcp-request inspect-delay 5s tcp-request content accept if { req.ssl_hello_type } use_backend websites if { req_ssl_sni -m found } default_backend sstp
То есть, выполняется проверка наличия SNI и если он есть, то трафик направляется на Web-сервер, а если нет, то на сервер SSTP.
Устанавливаем сервер
Дистрибутив актуален на ноябрь 2017. Новые версии - http://www.softether-download.com/en.aspx?product=softether
sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get install wget nano build-essential -y wget http://www.softether-download.com/files/softether/v4.24-9651-beta-2017.10.23-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.24-9651-beta-2017.10.23-linux-x64-64bit.tar.gz tar -xvf ./softether-vpnserver-v4.24-9651-beta-2017.10.23-linux-x64-64bit.tar.gz cd vpnserver/ echo -e "1\n1\n1\n" | make
Запуск в виде сервиса systemd
Создаем файлик /lib/systemd/system/vpnserver.service
[Unit] Description=SoftEther VPN Server After=network.target [Service] Type=forking ExecStart=/usr/local/vpnserver/vpnserver start ExecStop=/usr/local/vpnserver/vpnserver stop [Install] WantedBy=multi-user.target
Включаем сервис:
sudo systemctl enable vpnserver
Запускаем:
sudo service vpnserver start
Администрирование сервера
Для администрирования сервера в комплект входит утилита vpncmd. Она позволяет администрировать как локальный, так и удаленный сервер. Также есть GUI, но он под Windows и под wine у меня не заработал.
sudo ./vpncmd
Во-первых нужно установить административный пароль:
ServerPasswordSet
Полный список доступных команд можно увидеть так:
help
Настройка SSTP
Включаем SSTP:
SstpEnable yes
Импорт сертификата сервера
Для работы SSTP нужен сертификат. Его может сгенерировать сам SoftEther, но я предпочитаю использовать нормальные сертификаты Let's Encrypt. Я их получаю так: Сертификаты Let's Encrypt
Для того, чтобы подсунуть сертификат в SoftEther есть команда:
ServerCertSet
при её выполнении нужно указать путь к сертификату и закрытому ключу. В случае с let's encrypt это /etc/letsencrypt/live/your.domain.com/fullchain.pem и /etc/letsencrypt/live/your.domain.com/privkey.pem.
Создание виртуального Хаба
SoftEther использует концепцию виртуальных хабов. Хабы используются для разграничения прав и изоляции траффика. Можно создать новый хаб, но можно использовать дефолтный. Я буду использовать дефолтный.
Hub DEFAULT
Создать новый хаб и перейти в него можно командами:
HubCreate AUTOSYS Hub Autosys
Задать административный пароль для хаба можно командой:
SetHubPassword
Создание пользователя
SoftEther поддерживает много разных вариантов авторизации, в том числе и AD, RADIUS, однако, настраивать их через CLI я пока не знаю как, поэтому - настраиваю локальных пользователей.
Создание пользователя:
UserCreate test
Задаем пароль для пользователя:
UserPasswordSet test
Режим маршрутизации траффика
После выбора хаба нужно задать режим маршрутизации VPN-сессий. Режимов два - Local Bridge и SecureNAT.
LocalBridge - вариант при котором клиент присоединяется к сегменту Ethernet-сети, подключенному к одному из физических сетевых адаптеров VPN-сервера. Соединение происходит на втором уровне модели OSI
SecureNAT - режим, в котором VPN-сервер маршрутизирует траффик как роутер. В этом случае в недрах сервера SoftEther поднимается собственный маршрутизатор и DHCP-сервер (не связанные с ядром ОС), способные работать в userspace.
Виду того, что я поднимаю SoftEther в контейнере lxc, я буду использовать режим SecureNAT:
SecureNatEnable
При включении режима SecureNat автоматически включается маршрутизатор и и DHCP-сервер.
Настроить параметры виртуального сетевого адаптера SecureNAT можно командой:
SecureNatHostSet
При выполнении SecureNatHostSet нужно задать MAC-адрес (произвольный, начинающийся с 00:AC), IP-адрес (по-умолчанию 192.168.30.1) и маску сети (по-умолчанию - 255.255.255.0).
Параметры MTU и таймаутов для Virtual NAT можно задать командой:
NatSet
Параметры сервера DHCP задаются командой:
DhcpSet
Посмотреть текущие выданные DHCP-сервером IP-адреса:
DhcpTable
Состояние сервера SoftEther
Список прослушиваемых в данный момент портов:
ListenerList
Настройки SecureNAT:
SecureNatHostGet
Состояние SecureNAT:
SecureNatStatusGet
Настройка L2TP/IPSec
Включаем L2TP/IPSec
> IPsecEnable /L2TP:yes /L2TPRAW:no /ETHERIP:no /PSK:<preshared-key> /DEFAULTHUB:DEFAULT
Проверяем статус OpenVPN
> OpenVpnGet OpenVPN Clone Server Enabled|Yes UDP Port List |1194
Настройка клиента SoftEther
Клиент SoftEther способен работать в режиме сервиса, самостоятельно поддерживая работоспособность канала.
wget http://www.softether-download.com/files/softether/v4.24-9651-beta-2017.10.23-tree/Linux/SoftEther_VPN_Client/64bit_-_Intel_x64_or_AMD64/softether-vpnclient-v4.24-9651-beta-2017.10.23-linux-x64-64bit.tar.gz tar -xvf ./softether-vpnclient-v4.24-9651-beta-2017.10.23-linux-x64-64bit.tar.gz cd vpnclient/ echo -e "1\n1\n1\n" | make
Запускаем клиента:
sudo ./vpnclient start
Настройка подключения
Запускаем утилитку управления клиентом.
sudo ./vpncmd
Теперь жмем 2.
При настройке клента надо сделать две вещи. Создать виртуальный сетевой адаптер и привязать к нему подключение.
Создаем адаптер:
NicCreate autosys
Создаем подключение:
AccountCreate autosys
При создании подключения сервер указвыавем с портом server:port. В моем случае как-то так:
VPN Client>NicCreate autosys NicCreate command - Create New Virtual Network Adapter The command completed successfully. VPN Client>AccountCreate autosys AccountCreate command - Create New VPN Connection Setting Destination VPN Server Host Name and Port Number: sstp.autosys.tk The host name and port number specification is invalid. Please specify using the format of host name:port number, or IP address:port number. Destination VPN Server Host Name and Port Number: sstp.autosys.tk:443 Destination Virtual Hub Name: DEFAULT Connecting User Name: mike Used Virtual Network Adapter Name: autosys The command completed successfully.
Теперь прописываем пароль для нового подключения:
AccountPasswordSet
тут нужно указать имя подключения, пароль и тип авторизации (standard или RADIUS) в нашем случае - standard.
VPN Client>AccountPasswordSet AccountPasswordSet command - Set User Authentication Type of VPN Connection Setting to Password Authentication Name of VPN Connection Setting: autosys Please enter the password. To cancel press the Ctrl+D key. Password: ******* Confirm input: ******* Specify standard or radius: standard The command completed successfully.
Установка связи
AccountConnect myconnection
Проверка состояния подключения
AccountStatusGet myconnection
Discussion