В данной статье кратко описывается конфигурирование OCserv, сервера VPN-протокола Cisco AnyConnect на базе SSL, и HTTPS-сервера nginx с целью обеспечения их совместной работы на одном IP-адресе в ОС Linux (RHEL/CentOS/Fedora).
Эта статья не является инструкцией по настройке OCserv "с нуля". Для такой настройки воспользуйтесь одной из множества имеющихся в Сети инструкций (например, этой).
Рассмотрим случай, когда у нас уже есть сервер nginx, обслуживающий сайт domain.com
, и нам необходимо обеспечить подключение VPN-клиентов OCserv к субдомену sub.domain.com
. Если оба домена резолвятся на один и тот же IP-адрес, возникает проблема одновременного обслуживания соединений HTTPS и VPN на одном и том же порту (443/tcp). Предлагаемое в данной статье решение позволяет обойтись без дополнительного прокси-сервера типа haproxy, используя только имеющиеся у nginx средства для работы с SSL-соединениями.
Для начала необходимо удостовериться, что nginx скомпилирован с модулями stream_ssl_preread_module
/http_realip_module
. В nginx из репозитория EPEL в RHEL/CentOS/Fedora данные модули присутствуют "из коробки". В случае иных дистрибутивов Linux, или если nginx был установлен из другого репозитория, убедитесь, что в результате выполнения следующей команды в списке опций компиляции nginx присутствуют оба модуля:
$ nginx -V 2>&1 | tr ' ' '\n' | grep -E 'stream_ssl_preread_module|http_realip_module'
--with-http_realip_module
--with-stream_ssl_preread_module
Далее, добавляем секцию stream
в /etc/nginx/nginx.conf
:
...
stream {
map $ssl_preread_server_name $name {
sub.domain.com ocserv;
default https;
}
upstream https {
server 127.0.0.1:8443;
}
upstream ocserv {
server 127.0.0.1:9443;
}
server {
listen 443;
ssl_preread on;
proxy_protocol on;
proxy_pass $name;
}
}
http {
...
}
В данной секции определяются два upstream
с именами https
и ocserv
, для подключений HTTPS и VPN соответственно. Модуль stream_ssl_preread_module
читает имя сервера из заголовка SSL в переменную $ssl_preread_server_name
, после чего в map
оно преобразуется в имя апстрима, сохраняемое в переменную $name
. Преобразование осуществляется следующим образом: если имя сервера для подключения совпадает с sub.domain.com
, то выбирается апстрим ocserv
, для всех же остальных имен выбирается апстрим https
. После этого входящее подключение перенаправляется в выбранный апстрим посредством директивы proxy_pass
, при этом добавляется заголовок proxy_protocol
, в который сохраняется реальный IP-адрес клиента.
Далее необходимо поправить конфигурацию /etc/nginx/conf.d/domain.conf
:
server {
listen 127.0.0.1:8443 ssl http2 proxy_protocol;
listen [::1]:8443 ssl http2 proxy_protocol;
server_name domain.com;
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
...
}
В директиве listen
необходимо указать те же адрес и порт, что и в секции upstream https {}
. Помимо этого, с помощью опции proxy_protocol
включается чтение записанного в секции stream
заголовка, из которого получается реальный IP-адрес клиента с помощью директивы real_ip_header
. Директива set_real_ip_from
задает диапазон доверенных адресов источников, для которых разрешается использование данных из заголовка proxy_protocol
.
В файле конфигурации /etc/ocserv/ocserv.conf
необходимо поправить (или добавить) следующие директивы:
...
listen-host = 127.0.0.1
listen-proxy-proto = true
tcp-port = 9443
keepalive = 300
server-cert = /etc/letsencrypt/live/domain.com/fullchain.pem
server-key = /etc/letsencrypt/live/domain.com/privkey.pem
...
Директива listen-proxy-proto = true
включает чтение реального IP-адреса клиента VPN из заголовка, добавленного опцией proxy_protocol
nginx. Значение keepalive
(в секундах) должно быть меньше значения proxy_timeout в конфигурации nginx (по умолчанию 10 минут). Директивы server-cert
и server-key
задают пути к SSL-сертификату. Обратите внимание, что данный сертификат является общим для nginx и OCserv, поэтому он должен включать в себя оба имени, domain.com
и sub.domain.com
.
Таким образом, описанные выше настройки представляют собой минимальный пример конфигурирования OCserv и nginx для их совместного использования на одном IP-адресе.
Комментарии