MAATRIX / Блог / ocserv (OpenConnect) на Ubuntu 24.04: пошаговая установка

ocserv (OpenConnect) на Ubuntu 24.04: пошаговая установка

MAATRIX

Протокол Cisco AnyConnect (SSL VPN) работает поверх TLS, слушает стандартный HTTPS-порт и почти не отличим от обычного веб-трафика для систем анализа пакетов — в отличие от WireGuard или OpenVPN, у которых характерный рисунок трафика легко распознаётся DPI. ocserv — открытая реализация этого протокола, совместимая с клиентом OpenConnect и встроенным клиентом Cisco AnyConnect на всех основных платформах. Ниже — установка с нуля на Ubuntu 24.04: пакет, сертификат, конфиг, аутентификация и первое подключение.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Установка ocserv на Ubuntu 24.04

ocserv есть в стандартных репозиториях Ubuntu 24.04, версия в них современная и обновляется вместе с системой — отдельный PPA не нужен.

apt update
apt install ocserv gnutls-bin -y

Пакет gnutls-bin даёт утилиты certtool и ocpasswd, которые понадобятся дальше для сертификатов и паролей. Сразу после установки сервис уже запущен на дефолтном конфиге — его стоит остановить, пока не настроен нормально:

systemctl stop ocserv
systemctl status ocserv

Проверьте, что порт 443 свободен от других сервисов (nginx, Apache, Caddy) — ocserv будет на нём слушать. Если на сервере уже висит веб-сервер на 443, либо переносите его на другой порт, либо настраивайте ocserv на альтернативный (об этом — в разделе про маскировку). Если для управления доступом вы используете UFW, добавьте правило заранее — принцип настройки описан в статье про файрвол UFW на Ubuntu 24.04:

ufw allow 443/tcp
ufw allow 443/udp

UDP на том же порту нужен для DTLS — ocserv поднимает основной канал по TCP и по возможности переключается на DTLS поверх UDP для собственно передачи данных, это снижает задержку по сравнению с TCP-over-TCP.

Сертификат: самоподписанный или Let's Encrypt

ocserv требует TLS-сертификат для сервера — без него клиент не сможет установить соединение. Есть два рабочих варианта, и выбор зависит от того, готовы ли клиенты добавлять сертификат в доверенные вручную.

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

Генерация центра сертификации и серверного сертификата через certtool:

mkdir -p /etc/ocserv/ssl && cd /etc/ocserv/ssl

certtool --generate-privkey --outfile ca-key.pem

cat > ca.tmpl <<EOF
cn = "VPN CA"
organization = "MyOrg"
serial = 1
expiration_days = 3650
ca
signing_key
cert_signing_key
crl_signing_key
EOF
certtool --generate-self-signed --load-privkey ca-key.pem \
  --template ca.tmpl --outfile ca-cert.pem

certtool --generate-privkey --outfile server-key.pem

cat > server.tmpl <<EOF
cn = "vpn.example.com"
dns_name = "vpn.example.com"
expiration_days = 3650
signing_key
encryption_key
tls_www_server
EOF
certtool --generate-certificate --load-privkey server-key.pem \
  --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem \
  --template server.tmpl --outfile server-cert.pem

Замените vpn.example.com на реальный домен или IP сервера — значение cn/dns_name должно совпадать с адресом подключения клиентов.

Let's Encrypt — правильный выбор, если у сервера есть доменное имя: клиенты подключаются без единого предупреждения, потому что сертификат подписан доверенным центром. Процесс выпуска и продления через certbot подробно разобран в статье про Let's Encrypt на VPS — там же описан автообновление по cron/systemd-таймеру. Коротко для ocserv:

apt install certbot -y
systemctl stop ocserv   # порт 443 должен быть свободен для standalone-режима
certbot certonly --standalone -d vpn.example.com

Сертификат и ключ окажутся в /etc/letsencrypt/live/vpn.example.com/fullchain.pem и privkey.pem — эти пути указываются прямо в конфиге ocserv, копировать файлы никуда не нужно. Нюанс: certbot по умолчанию продлевает сертификат тем же standalone-методом, а значит на момент продления ocserv придётся ненадолго остановить (либо переключить certbot на --webroot, если рядом работает веб-сервер).

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Настройка ocserv.conf

Основной конфиг лежит в /etc/ocserv/ocserv.conf. Сделайте бэкап дефолтного файла и приведите ключевые параметры к рабочему виду:

cp /etc/ocserv/ocserv.conf /etc/ocserv/ocserv.conf.orig

Минимальный рабочий набор параметров:

auth = "plain[passwd=/etc/ocserv/ocpasswd]"
tcp-port = 443
udp-port = 443
run-as-user = nobody
run-as-group = daemon
socket-file = /run/ocserv-socket
chroot-dir = /var/lib/ocserv

server-cert = /etc/ocserv/ssl/server-cert.pem
server-key = /etc/ocserv/ssl/server-key.pem

max-clients = 32
max-same-clients = 4
keepalive = 300
dpd = 90
mobile-dpd = 1800

mtu = 1400
cookie-timeout = 300
try-mtu-discovery = true

cisco-client-compat = true
dtls-legacy = true

ipv4-network = 192.168.90.0
ipv4-netmask = 255.255.255.0
dns = 1.1.1.1
dns = 8.8.8.8

route = default
tunnel-all-dns = true

device = vpns
predictable-ips = true

Если используете сертификаты от Let's Encrypt, замените строки server-cert/server-key на пути в /etc/letsencrypt/live/.... Диапазон ipv4-network — приватная подсеть, которую сервер будет раздавать клиентам; она не должна пересекаться с локальной сетью самого сервера.

Чтобы клиенты действительно выходили в интернет через сервер, а не только получали адрес в туннеле, нужен NAT и разрешённый форвардинг пакетов:

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

iptables -t nat -A POSTROUTING -s 192.168.90.0/24 -o eth0 -j MASQUERADE

Уточните имя внешнего интерфейса (eth0 может отличаться — проверьте через ip a) и сохраните правило постоянным через iptables-persistent, иначе оно исчезнет после перезагрузки.

Аутентификация: пароль или сертификат

ocserv поддерживает несколько схем аутентификации, их можно комбинировать. Две базовые:

По паролю (PAM-совместимый метод plain) — самый быстрый способ завести пользователей, файл с хешами паролей создаётся утилитой ocpasswd:

ocpasswd -c /etc/ocserv/ocpasswd ivan

Утилита спросит пароль дважды и добавит запись в файл, путь к которому уже указан в auth = "plain[passwd=...]". Добавить ещё одного пользователя — та же команда с другим именем, удалить — ocpasswd -c /etc/ocserv/ocpasswd -d ivan.

По клиентскому сертификату — надёжнее пароля, потому что скомпрометированный пароль можно подобрать или подсмотреть, а закрытый ключ сертификата физически лежит только на устройстве клиента. Требует выпуска отдельного сертификата на каждого пользователя тем же центром, что подписывал серверный:

certtool --generate-privkey --outfile client-key.pem

cat > client.tmpl <<EOF
cn = "ivan"
unit = "clients"
expiration_days = 365
EOF
certtool --generate-certificate --load-privkey client-key.pem \
  --load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem \
  --template client.tmpl --outfile client-cert.pem

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \
  -certfile ca-cert.pem -out ivan.p12

Файл ivan.p12 передаётся пользователю защищённым каналом (это фактически ключ доступа) и импортируется в клиент. В конфиге сервера для проверки клиентских сертификатов добавляется ca-cert = /etc/ocserv/ssl/ca-cert.pem, а для строгого режима — auth = "certificate" вместо plain. Для личного использования пароля достаточно; сертификат имеет смысл, когда пользователей много и нужен контроль отзыва доступа через CRL без смены общего пароля.

Порт 443 — маскировка под HTTPS

Ключевая особенность ocserv — работа на 443 порту как обычный HTTPS-сервис. Это не обход блокировок в строгом смысле (протокол всё равно определяется по паттернам TLS handshake при желании), но для сетей с ограничениями по портам (офисный файрвол, гостиничный Wi-Fi, мобильный оператор, режущий нестандартные порты) трафик ocserv проходит там же, где проходит обычный браузер — формально это TLS-сессия на 443.

Если 443 порт уже занят веб-сервером, есть два пути: повесить ocserv на другой порт (например, 8443) и указать его явно клиентам — теряется часть маскировки, но конфликта нет; либо разделить трафик по SNI между веб-сервером и ocserv через nginx stream или sslh — сложнее, но оба сервиса остаются на стандартном порту. Второй вариант обычно избыточен для одиночного VPN-сервера — проще выделить серверу единственную задачу (только VPN) или развести порты.

Параметр cisco-client-compat = true в конфиге выше отвечает как раз за совместимость с оригинальным AnyConnect-клиентом Cisco, который иначе может не опознать сервер как совместимый. Без него подключаются только клиенты на базе open-source OpenConnect.

Подключение клиентов OpenConnect

После правки конфига проверьте синтаксис и запустите сервис:

ocserv -c /etc/ocserv/ocserv.conf -d 1 -f   # тестовый запуск в форграунде с логами

Если сообщений об ошибках нет — прервите (Ctrl+C) и включите сервис штатно:

systemctl enable --now ocserv
systemctl status ocserv
journalctl -u ocserv -f   # смотреть логи подключений в реальном времени

На стороне клиента используется пакет openconnect — он есть в репозиториях Linux, есть сборки для Windows и macOS, а также официальные приложения для iOS и Android (в том числе GUI-обёртка OpenConnect для десктопа, если не хочется работать через терминал).

Подключение с Linux/macOS из терминала:

sudo openconnect --protocol=anyconnect vpn.example.com:443

Клиент запросит логин и пароль (или сертификат), после чего поднимет туннель. Для самоподписанного сертификата при первом подключении появится предупреждение с отпечатком — его нужно один раз подтвердить (флаг --servercert с отпечатком позволяет проходить эту проверку неинтерактивно в скриптах).

ПараметрСамоподписанныйLet's Encrypt
Нужен доменНетДа
Предупреждение у клиентаДа, при первом подключенииНет
АвтообновлениеНе требуется (10 лет)Нужен cron/таймер
Подходит дляЛичного использования, тестовПостоянной эксплуатации, нескольких пользователей

Если нужно сравнить ocserv с более распространёнными протоколами по эксплуатационным критериям (скорость настройки, клиентская поддержка, поведение при потере соединения), это разобрано в статье WireGuard или OpenVPN — что выбрать для сервера; там же логика применима и к выбору между этими протоколами и ocserv в целом.

Арендуйте сервер под свои задачи!

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем ocserv отличается от OpenVPN и WireGuard?

Протоколом и транспортом: ocserv реализует Cisco AnyConnect SSL VPN и по умолчанию работает на 443 порту как TLS-сервис, что упрощает прохождение через ограниченные сети. OpenVPN и WireGuard используют собственные протоколы и обычно работают на нестандартных портах, хотя OpenVPN тоже можно перенести на 443/TCP. Пошаговая установка каждого из них — в статьях про WireGuard на Ubuntu 24.04 и OpenVPN на Ubuntu 24.04.

Можно ли использовать один и тот же сертификат и для сайта, и для ocserv?

Технически да, если сертификат выпущен на тот же домен и путь к файлам доступен процессу ocserv. Практически удобнее держать для VPN отдельный сертификат (свой или через тот же Let's Encrypt на поддомене вроде vpn.example.com), чтобы продление одного сервиса не зависело от настроек другого.

Почему клиент подключается, но интернет не идёт?

Чаще всего забыт net.ipv4.ip_forward = 1 или правило MASQUERADE в iptables, либо неверно указан внешний интерфейс в правиле NAT. Проверьте sysctl net.ipv4.ip_forward и вывод iptables -t nat -L -n.

Нужен ли статический IP для сервера?

Не обязателен для самоподписанного сертификата (можно указывать IP вместо домена), но обязателен по факту для Let's Encrypt, так как выпуск и продление привязаны к DNS-записи, указывающей на актуальный IP сервера.

Как отозвать доступ у одного пользователя без смены пароля у всех?

При аутентификации по паролю — удалить конкретную запись через ocpasswd -c /etc/ocserv/ocpasswd -d логин. При аутентификации по сертификатам — отозвать конкретный сертификат через CRL или переиздать CA (более радикальный вариант, требующий переиздания всех клиентских сертификатов).

Сколько одновременных клиентов выдержит один сервер ocserv?

Зависит от канала и ресурсов сервера, а не от самого протокола — параметры max-clients и max-same-clients в конфиге лишь ограничивают потолок, реальную ёмкость нужно проверять нагрузочно под свой трафик.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →