Блокировка VPN в России уже не маловероятное событие. В конце мая 2023 года весь Рунет взорвался от сообщений пользователей и информагентств о неработоспособности VPN и подозрениях об умышленной блокировке VPN-трафика (ссылки: habr, securitylab, tproger). Давайте настроим, чтобы наше VPN-соединение выглядело как защищенное соединение HTTPS. VPN-трафик, замаскированный под web-трафик, пустим на обычном для web-трафика порту 443. А работу VPN сервера на порту 443 скроем работой обычного web сервера на этом же порту 443. Это позволит нам обойти блокировку VPN.
Блокировка VPN
В сообщениях информагентств (ссылки см. выше) говорилось о блокировке именно OpenVPN соединений. Мне также попадались сообщения от пользователей о неработоспособности PPTP тоннелей.
Типы протоколов VPN
Привожу список популярных протоколов VPN:
- PPTP (Point-to-Point Tunneling Protocol). Это один из наиболее распространенных протоколов VPN. Однако, он не считается самым безопасным вариантом, поскольку его шифрование может быть уязвимым.
- L2TP/IPsec (Layer 2 Tunneling Protocol/IP Security). Этот VPN протокол обеспечивает более высокий уровень безопасности, так как использует IPsec для шифрования данных. Он часто используется в сочетании с другими протоколами, такими как PPTP.
- OpenVPN. OpenVPN является открытым и гибким протоколом VPN. Обеспечивает высокий уровень безопасности и поддерживается в различных операционных системах. Он использует SSL/TLS протоколы для шифрования данных и обмена ключами. Является популярным выбором для многих VPN-сервисов.
- SSTP (Secure Socket Tunneling Protocol). SSTP является проприетарным протоколом, разработанным компанией Microsoft. Он использует SSL/TLS для шифрования данных и работает через TCP порт 443, что делает труднее его блокировку.
- WireGuard. WireGuard — это новый протокол VPN. Основная цель разработки — обеспечить простоту, безопасность и высокую производительность. Весь обмен происходит по UDP.
- OpenConnect. Опенсорсная реализация протокола Cisco AnyConnect VPN на основе SSL. При настройке работы только по TCP (по умолчанию работает по UDP), трафик становится похож на обычный HTTPS.
Возможности OpenConnect VPN
Главная возможность OpenConnect VPN, благодаря которой мы будем настраивать именно OpenConnect VPN, это возможность маскировки VPN-трафика под обычный web-трафик (трафик при просмотре в браузере HTTPS сайтов из сети Интернет). Другими словами, главная возможность OpenConnect VPN — это устойчивость к глубокой проверке пакетов (Deep Packet Inspection, сокращенно DPI) из-за неотличимости VPN пакетов от обычного web-трафика.
Основные возможности OpenConnect VPN:
- Устойчивость к глубокой проверке пакетов (DPI).
- Высокая скорость передачи данных: можно смотреть видео YouTube 4K.
- Сервер OpenConnect VPN — под ОС Linux.
- Клиентское программное обеспечение — под Linux, Windows, MacOS.
- Мобильное клиентское ПО для Android и iOS — это клиент Cisco AnyConnect.
- Аутентификация по паролю или по сертификату.
- Легкая настройка.
Web сервер и VPN сервер на порту 443
Мы настроим OpenConnect VPN сервер слушать порт 443. Получится, VPN-трафик, замаскированный под web-трафик, на стандартном для web-трафика порту 443. Очень неподозрительный вариант!
Чтобы замаскировать работу OpenConnect VPN сервера, этот же порт 443 будет слушать обычный web сервер (Nginx). Совместная работа двух сервисов на одном порту возможная благодаря трем вещам: Server Name Indication (SNI), High Availability Proxy (HAProxy) и DNS over HTTPS (DoH).
DNS over HTTPS (DoH)
DNS (Domain Name System) переводит доменные имена в IP адреса. По умолчанию запросы и ответы DNS отправляются открытым текстом, в незашифрованном виде. И, следовательно, могут быть прочитаны третьими лицами, отслеживающими передачи.
DNS over HTTPS (DoH) — это протокол для шифрования трафика DNS, чтобы третьи лица не могли интерпретировать пересылаемые данные. DoH использует порт 443, который используется и для всего остального трафика HTTPS.
Server Name Indication (SNI)
TLS (Transport Layer Security) — это протоколы для шифрования передаваемых данных, для аутентификации, целостности и конфиденциальности информации в сети Интернет.
Server Name Indication (SNI) — это расширение TLS, которое позволяет серверу размещать несколько веб-сайтов с поддержкой TLS на одном IP адресе, требуя от клиентов указать, к какому сайту они хотят подключиться во время начального рукопожатия TLS (ClientHello).
Желая подключиться к VPN, клиент будет добавлять расширение SNI, содержание имя сайта vpn.yourdomain.com, в сообщение ClientHello. Желая подключиться к обычному web серверу, клиент будет добавлять расширение SNI c www.yourdomain.com в сообщение ClientHello. Без добавления расширения SNI, без указания желаемого веб-сайта, клиент будет подключен к web серверу.
В версии TLS 1.3 содержимое расширения SNI шифруется. Как это происходит? Сервер публикует открытый ключ в известной записи DNS, которую клиент может получить перед подключением. Затем клиент добавляет зашифрованное расширение SNI в ClientHello. Сервер, которому принадлежит закрытый ключ, расшифровывает расширение. Так зашифрованный SNI не может быть расшифрован и доступен третьим лицам.
Таким образом, связка зашифрованного SNI с TLS 1.3 и DoH закрывает одну из немногих оставшихся дыр, обеспечивающих слежку и цензуру в Интернете.
High Availability Proxy (HAProxy)
High Availability Proxy (HAProxy) — это бесплатный и открытый прокси-сервер и балансировщик нагрузки. Будет распределять входящий трафик на порт 443 между web сервером и VPN сервером в зависимости от желания, куда клиент хочет подключиться, указанного в расширении SNI.
Практическая реализация
От описания идеи сразу переходим к реализации. Блокировка VPN может случиться неожиданно, так встретим ее во всеоружии!
Виртуальный сервер не в России
На виртуальном сервере мы будем разворачивать OpenConnect VPN сервер. Создание виртуального сервера не в России и с оплатой в рублях описано: «Виртуальный (VDS/VPS) сервер не в России» (читаем только один раздел).
Доменное имя
Чтобы включить HTTPS для OpenConnect VPN, нам понадобится доменное имя. Мне нравится регистрировать доменное имя на https://www.namecheap.com/. Тут недорогая стоимость домена и бесплатная пожизненная защита конфиденциальности Whois. Эта защита конфиденциальности скрывает личную информацию в общедоступной базе данных Whois и помогает избежать спама. Все хорошо, но к оплате не принимаются российские банковские карты.
Перенаправление DNS
После регистрации домена необходимо настроить DNS записи, чтобы указать, на какой IP адрес должно быть перенаправление для домена. Для этого создадим две DNS записи.
Первая запись с типом А, в поле host указываем символ @, а в значении записи — публичный IP адрес виртуального сервера. Символ @ используется для перенаправления корневого домена, т.е. yourdomain.com, на IP адрес.
Вторая запись тоже с типом А, в поле host указываем *, а в значении записи — тоже публичный IP адрес виртуального сервера. Символ * используется для перенаправления всех поддоменов на IP адрес.

Имейте в виду, чтобы новые записи DNS вступили в силу, нужно выждать время.
DNS over HTTPS
Настраиваем безопасный DNS (DNS over HTTPS), чтобы не было «утечки», к vpn.yourdomain.com или к www.yourdomain.com мы собираемся подключаться. Настраиваем и на виртуальном сервере, и на компьютере, с которого будем подключаться к виртуальному серверу. Подробная инструкция: «DNS over HTTPS. Настройка в Linux (Debian) и Windows«.
Nginx веб-сервер
На виртуальном сервере веб-сервер нам нужен для маскировки на порту 443 OpenConnect VPN сервера. Установка и настройка Nginx веб-сервера описаны: «Установка и настройка Nginx» (читаем только один раздел).
В результате должен получиться виртуальный хост www.yourdomain.com с установленным для него сертификатом.
Виртуальный хост vpn.yourdomain.com и TLS сертификат
TLS сертификат — это современная версия SSL сертификата. Поскольку SSL (Secure Sockets Layer) протокол устарел и был заменен более современным и безопасным протоколом TLS (Transport Layer Security). И SSL сертификаты теперь обычно называются TLS сертификатами, поскольку они используют протокол TLS для установления защищенного соединения с веб-сайтом и шифрования передаваемых данных.
Создаем конфигурационный файл /etc/nginx/sites-available/vpn.yourdomain.com.conf:
touch /etc/nginx/sites-available/vpn.yourdomain.com.conf
И добавляем в файл следующее содержимое:
server {
listen 80;
server_name vpn.yourdomain.com;
root /var/www/ocserv/;
location ~ /.well-known/acme-challenge {
allow all;
}
}
Создаем символическую ссылку:
ln -s /etc/nginx/sites-available/vpn.yourdomain.com.conf /etc/nginx/sites-enabled/vpn.yourdomain.com.conf
Создаем корневую веб-директорию /var/www/ocserv/:
mkdir -p /var/www/ocserv
-p
— опция, указывающая при необходимости создавать промежуточные директории для достижения указанного пути.
Перезагружаем веб-сервер Nginx, чтобы заработал виртуальный хост vpn.yourdomain.com:
nginx -s reload
Запускаем Certbot для получения TLS сертификата от Let’s Encrypt:
certbot certonly --webroot --agree-tos -d vpn.yourdomain.com -w /var/www/ocserv --register-unsafely-without-email
certonly
— получить TLS сертификат, но не устанавливать его.
--webroot
— специальный плагин, помогающий получить TLS сертификат в случае, если на сервере работает веб-сервер, прослушивающий порты 80 и 443.
--agree-tos
— принять условия обслуживания Let’s Encrypt.
-d vpn.yourdomain.com
— TLS сертификат будет принадлежать домену vpn.yourdomain.com.
-w /var/www/ocserv
— путь к корневой веб-директории /var/www/ocserv/.
--register-unsafely-without-email
— получить TLS сертификат и не указывать почтовый ящик (email).

Ура! TLS сертификат получен. Это два файла: /etc/letsencrypt/live/vpn.yourdomain.com/fullchain.pem и /etc/letsencrypt/live/vpn.yourdomain.com/privkey.pem.
OpenConnect VPN
По умолчанию OpenConnect VPN сервер прослушивает порт 443 по протоколам TCP и UDP. Но этот же порт 443 по протоколу TCP уже прослушивает веб-сервер Nginx. Временно остановим веб-сервер, чтобы настроить и проверить работоспособность OpenConnect VPN на порту 443. В следующем же разделе статьи будем настраивать одновременную работу веб-сервера и VPN сервера на порту 443.
На виртуальном сервере останавливаем Nginx веб-сервер:
nginx -s stop
Далее, на виртуальном сервере необходимо установить и настроить OpenConnect VPN сервер. А на компьютере, с которого будем подключаться к VPN, необходимо установить VPN клиент. Действуем по инструкции: «OpenConnect VPN. Подробное руководство«.
VPN сервер и Nginx одновременно на порту 443 с помощью HAProxy
Порт 443 будет слушать прокси-сервер HAProxy. Благодаря использованию функции SNI (индикации имени сервера) в TLS, прокси-сервер HAProxy будет различать трафик VPN и обычный трафик HTTPS. Когда vpn.yourdomain.com находится в клиентском TLS Hello, прокси-сервер HAProxy будет перенаправлять трафик на OpenConnect VPN сервер. Когда www.yourdomain.com находится в клиентском TLS Hello, прокси-сервер HAProxy будет перенаправлять трафик на веб-сервер Nginx. Если клиент не указал имя сервера в клиентском TLS Hello, тогда HAProxy будет перенаправлять трафик на веб-сервер Nginx.
Приступим к настройкам. Отредактируем конфигурационный файл OpenConnect VPN сервера /etc/ocserv/ocserv.conf.
OpenConnect VPN cервер будет получать соединения от прокси-сервера HAProxy, который поддерживает Proxy протокол. И чтобы VPN сервер получал корректные клиентские адреса, раскомментируем следующую строку:
#listen-proxy-proto = true
Чтобы она стала такой:
listen-proxy-proto = true
OpenConnect VPN сервер будет принимать соединения на IP адресе 127.0.0.1. Для этого находим строку:
#listen-host = [IP|HOSTNAME]
И приводим ее к виду:
listen-host = 127.0.0.1
Сохраняем конфигурационный файл и перезагружаем OpenConnect VPN сервер:
systemctl restart ocserv

Отредактируем конфигурационный файл Nginx веб-сервера /etc/nginx/sites-available/www.yourdomain.com.conf.
Nginx веб-сервер будет принимать соединения на IP адресе 127.0.0.2:443. Для этого находим строку:
listen 443 ssl;
И меняем ее на следующую строку:
listen 127.0.0.2:443 ssl;
Сохраняем конфигурационный файл.
Отредактируем основной конфигурационный файл Nginx веб-сервера, который называется /etc/nginx/nginx.conf.
Будем использовать только протокол TLS 1.3. Поэтому предыдущие версии протокола TLS отключим. Для этого находим строку:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
И приводим ее к виду:
ssl_protocols TLSv1.3;
Сохраняем конфигурационный файл и стартуем Nginx веб-сервер:
nginx

Осталось установить и настроить прокси-сервер HAProxy. Устанавливаем:
apt install haproxy
В конец конфигурационного файла прокси-сервера /etc/haproxy/haproxy.cfg добавляем следующий текст:
frontend https
bind 12.34.56.78:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend ocserv if { req_ssl_sni -i vpn.yourdomain.com }
use_backend nginx if { req_ssl_sni -i www.yourdomain.com }
use_backend nginx if { req_ssl_sni -i yourdomain.com }
default_backend nginx
backend ocserv
mode tcp
option ssl-hello-chk
server ocserv 127.0.0.1:443 send-proxy-v2
backend nginx
mode tcp
option ssl-hello-chk
server nginx 127.0.0.2:443 check
где 12.34.56.78
— это публичный IP адрес виртуального сервера. Если же сервер стоит за роутером, то указывается локальный IP адрес сервера.
Сохраняем конфигурационный файл и рестартуем прокси-сервер HAProxy:
systemctl restart haproxy
Ошибки прокси-сервера HAProxy смотрим в файле /var/log/haproxy.log.
Все готово! Запускайте VPN клиент и проверяйте соединение с VPN сервером vpn.yourdomain.com. А если в адресной строке браузера набрать www.yourdomain.com, то уже веб-сервер должен предоставить запрошенную веб-страницу.
Выводы
Я думаю, что блокировка VPN в России в итоге все-таки состоится. Это только вопрос времени. А для тех, кому жизненно необходимо подстраховаться, и написана эта статья.
Пожалуйста, все вопросы — в комментариях под статьей.
Комментарии
вместо bind 12.34.56.78:443
можно же просто bind *:443 указать, а энжинкс с хапроксёй на разные порты разнести
и вместо толстого сертбота acme.sh отлично заходит
ну и если мы дефолт бакенд указали, то записи с «use_backend nginx if» не нужны
а так всё классно, если опенконнект действительно не палится
Статья требует редактирования. Все, что написано в статье, светится: «Здрасте, Я VPN, можете меня РКН банить»
0.1(1) Please enter your username.
This XML file does not appear to have any style information associated with it. The document tree is shown below.
Zalan, согласна с Вами. На самом деле, если в адресной строке браузера набрать vpn.yourdomain.com, то OpenConnect VPN сервер любезно и всем подряд сообщает:
config-auth client="vpn" type="auth-request">
version who="sg">0.1(1)/version>
auth id="main">
message>Please enter your username./message>
form method="post" action="/auth">
input type="text" name="username" label="Username:"/>
/form>
/auth>
/config-auth>
Именно поэтому я для себя настраивала несколько разных типов обходов блокировок. Поскольку, как будет действовать РКН, одному ему и известно. Вот ссылка на статью с другим типом обхода: «Обход блокировок Рунета. Наработки китайцев домохозяйке на заметку«.