Установка и настройка openconnect на Ubuntu 22.04

Linux
Linux

OpenConnect — как следует из названия, это open source реализация всем известного Cisco AnyConnect. Клиент — серверный VPN

Официальная страничка ресурса: https://ocserv.openconnect-vpn.net/index.html

Gitlab репозиторий:https://gitlab.com/openconnect/ocserv

Основные преимущества данного сервиса:
Внешне подключение выглядит как обычное HTTPS
Для него существуют клиенты на все популярные платформы, в том числе он вполне внятно работает с Cisco Anyconnect клиентом.
Умеет работать с Active Directory, RADIUS много чем еще.
Очень удобен для настройки со стороны клиента, собственно там вообще никакой настройки не требуется.
А со стороны сервера, пакет которого называется OCserv, с настройкой — мы сейчас разберемся.

Собственно в статье буду рассматривать установку на Ubuntu 22.04 но на другие deb системы ставиться будет, плюс — минус, так же.

В целом OCserv можно установить в ubuntu из дефолтных репозиторев с помощью apt.

Однако на момент написания статьи в репозиториях предлагалась версия 1.1.3, когда актуальная версия 1.2.4. Само собой в более свежей версии решено много прошлых проблем, а так же добавлено много полезного функционала (например налажена стабильная работа с клиентами cisco anyconnect различных версий). Поэтому устанавливать мы будем самую свежую версию.

Для начала установим необходимые зависимости:

# Required
apt-get install -y libgnutls28-dev libev-dev build-essential pkg-config libgnutls28-dev libreadline-dev libseccomp-dev libwrap0-dev libnl-nf-3-dev liblz4-dev certbot
# Optional functionality and testing
apt-get install -y libpam0g-dev liblz4-dev libseccomp-dev \
	libreadline-dev libnl-route-3-dev libkrb5-dev libradcli-dev \
	libcurl4-gnutls-dev libcjose-dev libjansson-dev liboath-dev \
	libprotobuf-c-dev libtalloc-dev libhttp-parser-dev protobuf-c-compiler \
	gperf iperf3 lcov libuid-wrapper libpam-wrapper libnss-wrapper \
	libsocket-wrapper gss-ntlmssp haproxy iputils-ping freeradius \
	gawk gnutls-bin iproute2 yajl-tools tcpdump libgeoip-dev libmaxminddb-dev \
        
# For manpages
apt install -y ronn

Скачиваем исходники с ftp. На момент написания статьи самая свежая версия 1.2.4, вы можете на всякий случай проверить предварительно версию в gitlab в разделе release или непосредственно на самом ftp:

wget ftp://ftp.infradead.org/pub/ocserv/ocserv-1.2.4.tar.xz

Распаковываем скачанный архив и сразу проваливаемся в каталог:

tar xvf ocserv-1.2.4.tar.xz && cd ocserv-1.2.4

Далее запускаем проверку конфигурации, если на этом этапе чего то не хватает — можно доустановить.

./configure

Для примера мой результат команды:

Компилируем и устанавливаем:

make
sudo make install

Генерируем сертификат нужный для работы. Мой выбор пал на Let’s Encrypt:

certbot certonly --standalone --preferred-challenges http --agree-tos --email [email protected] -d yourdomain.ru

На всякий случай по параметрам выше:

  • certonly — только получаем сертификат, никуда не устанавливая
  • --standalone — плагин используемый для получения сертификата
  • --preferred-challenges http — Использовать для валидации http-01 (убедитесь что у вас открыт 80 порт)
  • --agree-tos — даем согласие на условия обслуживания (terms of service)
  • --email — почта используемая для регистрации аккаунта
  • -d — доменное имя

Возвращаемся к серверу. Для начала подготовим файл конфигурации, предварительно создав каталог в котором он будет лежать и скопировав туда шаблон:

mkdir /etc/ocserv
cp doc/sample.config /etc/ocserv/ocserv.conf

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


auth = "plain[passwd=/etc/ocserv/ocpasswd]"

# Номера портов TCP\UDP
tcp-port = 443
udp-port = 443
# пользователь от чьего имени запускать процесс
run-as-user = ocserv
run-as-group = ocserv

socket-file = /var/run/ocserv-socket

## Путь к сертификатам

server-cert = /etc/letsencrypt/live/vpn.ilccredits.com/fullchain.pem
server-key = /etc/letsencrypt/live/vpn.ilccredits.com/privkey.pem

isolate-workers = true
max-clients = 0
max-same-clients = 2
rate-limit-ms = 100
server-stats-reset-time = 604800
keepalive = 32400
dpd = 90
mobile-dpd = 1800
switch-to-tcp-timeout = 25
try-mtu-discovery = false
cert-user-oid = 0.9.2342.19200300.100.1.1
tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1"
auth-timeout = 240
min-reauth-time = 300
max-ban-score = 80
ban-reset-time = 1200
cookie-timeout = 300
deny-roaming = false
rekey-time = 172800
rekey-method = ssl
use-occtl = true
pid-file = /var/run/ocserv.pid
log-level = 2
device = vpns
predictable-ips = true

# укажите домен для вашего впна
default-domain = vpn.yourdomain.com

## Пул адресов выдаваемых впн клиенту.
## так же можно укзать подсеть, например 192.168.200.1/24
ipv4-network = 192.168.200.1
ipv4-netmask = 255.255.255.0

ping-leases = false

## маршруты которые будут пушится клиентам 
## если default то у клиента сменится основной шлюз
## и весь трафик завернет в впн. тогда не забудте
## добавить еще строчку dns = <dns.ip?
route = 192.168.168.0/255.255.255.0
route = 192.168.1.0/255.255.255.0
#route = fef4:db8:1000:1001::/64
#route = default

# маршруты которые изключить из пуша
#no-route = 192.168.5.0/255.255.255.0

cisco-client-compat = true
dtls-legacy = true
cisco-svc-client-compat = false
client-bypass-protocol = false
camouflage = false
camouflage_secret = "mysecretkey"
camouflage_realm = "Restricted Content"

# HTTP headers
included-http-headers = Strict-Transport-Security: max-age=31536000 ; includeSubDomains
included-http-headers = X-Frame-Options: deny
included-http-headers = X-Content-Type-Options: nosniff
included-http-headers = Content-Security-Policy: default-src 'none'
included-http-headers = X-Permitted-Cross-Domain-Policies: none
included-http-headers = Referrer-Policy: no-referrer
included-http-headers = Clear-Site-Data: "cache","cookies","storage"
included-http-headers = Cross-Origin-Embedder-Policy: require-corp
included-http-headers = Cross-Origin-Opener-Policy: same-origin
included-http-headers = Cross-Origin-Resource-Policy: same-origin
included-http-headers = X-XSS-Protection: 0
included-http-headers = Pragma: no-cache
included-http-headers = Cache-control: no-store, no-cache

Так же нам нужно создать пользователя от которого будет запускаться наш сервер, выполняем:

useradd ocserv

Разрешить форвард в параметрах ядра, для этого добавляем в файл /etc/sysctl.conf:

net.ipv4.ip_forward = 1  

И выполнить:

sysctl -p

А так же добавить systemd unit для запуска сервиса с помощью systemctl. Для этого создаем файл по пути /etc/systemd/system/ocserv.service вот с таким содержимым:

[Unit]
Description=OpenConnect SSL VPN server
Documentation=man:ocserv(8)
After=network-online.target

[Service]
PrivateTmp=true
PIDFile=/run/ocserv.pid
Type=simple
ExecStart=/srv/ocserv-1.2.4/src/ocserv --foreground --pid-file /run/ocserv.pid --config /etc/ocserv/ocserv.conf
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

Так же, что бы всё работало нужно поправить правила firewall, в моем случае ufw, редактируем /etc/default/ufw:

DEFAULT_FORWARD_POLICY="ACCEPT"

Редактируем политики по умолчанию /etc/ufw/before.rules , добавляем правила построутинга:

# OPENCONNECT RULES
*nat
:POSTROUTING ACCEPT [0:0]
# Разрешаем прохождение трафика от клиентов на локальный eth0 (смените на свой вариант)
-A POSTROUTING -s 192.168.200.0/24 -o eth0 -j MASQUERADE
COMMIT
# END OPENCONNECT RULES

Не забудьте добавить разрешаю правила для самого сервера 443 80 и 22 что бы не потерять к нему доступ.

Осталось создать пользователя с паролем. Для этого переходим в каталог /etc/ocserv и выполняем:

ocpasswd username

В процессе создания пользователя, диалог попросит дважды ввести его пароль и в результате в каталоге появится файл ocpasswd, который, если что редактировать в целом тоже можно в ручную.

В целом, после этого можно его запускать, выполнив

systemctl start ocserv

И проверять подключение. Если вы используете cisco anyconnect — достаточно в поле подключения указать доменное имя сервера. И пройти авторизацию

Отдельно распишу про режим маскировки.

При включении режима маскировки, сервер — ожидает перед подключением получения «секрета» от пользователя в конце строки подключения. Т.е. строка подключения будет выглядеть примерно так: https://vpn.your-domain.com/?secretword где ?secretword как раз и есть тот самый «секрет»

При этом, если в адресе для подключения данного слова не будет, то сервер вернет сообщение об ошибке, как простой веб-сервер.

Что бы включить этот функционал в конфигурации сервера /etc/ocserv.conf требуется исправить вот эти параметры:

## включаем работу в режиме маскировки
camouflage = true
## Указываем "секрет"
camouflage_secret = "mysecretkey"
## Указываем кем серверу прикдываться во время авторизации, например админ панель, или какой нибдуь
## личный кабинет. Если не указывать ничего, то в случае провальной авторизации сервер будет 
## возвращать http 404 (страница не найдена), если указать - то http 401 (Ошибка авторизации 
## Unauthorized) 
camouflage_realm = "Restricted Content"

6 Комментарии

  1. Добрый день! После установки получаю ошибку:

    root@wan-gw:~# systemctl status ocserv
    × ocserv.service — OpenConnect SSL VPN server
    Loaded: loaded (/usr/lib/systemd/system/ocserv.service; enabled; preset: enabled)
    Active: failed (Result: exit-code) since Mon 2024-09-16 07:45:31 UTC; 8s ago
    Duration: 10ms
    Docs: man:ocserv(8)
    Process: 1432 ExecStart=/usr/sbin/ocserv —log-stderr —foreground —pid-file /run/ocserv.pid —config /etc/ocserv/ocserv.conf (code=exited, status=1/FAILURE)
    Main PID: 1432 (code=exited, status=1/FAILURE)
    CPU: 6ms

    Sep 16 07:45:31 wan-gw systemd[1]: Started ocserv.service — OpenConnect SSL VPN server.
    Sep 16 07:45:31 wan-gw ocserv[1432]: note: skipping ‘pid-file’ config option
    Sep 16 07:45:31 wan-gw ocserv[1432]: note: vhost:default: setting ‘plain’ as primary authentication method
    Sep 16 07:45:31 wan-gw ocserv[1432]: error: the ‘server-cert’ and ‘server-key’ configuration options must be specified!
    Sep 16 07:45:31 wan-gw systemd[1]: ocserv.service: Main process exited, code=exited, status=1/FAILURE
    Sep 16 07:45:31 wan-gw systemd[1]: ocserv.service: Failed with result ‘exit-code’.

    Подскажите, что не устраивает систему инициализации?

    • Вероятно в конфигурационном файле не указаны параметры сертификата и ключа:
      error: the ‘server-cert’ and ‘server-key’ configuration options must be specified!

      Проверьте что данные параметры заданы корректно в файле /etc/ocserv/ocserv.conf и что сертификаты по указанным путям — существуют.
      Параметры server-cert и server-key в статье указан пример.

    • Либо создать домен в бесплатных зонах, если не готовы платить за него.
      Либо использовать в качестве имени сам ip адрес. На практике не проверял, но в целом должно работать.

        • В случае использования ip в качестве имени, вам нужно генерировать само подписной сертификат на ip адрес. Certbot вам в таком случае не потребуется. А сертификаты придется физически раскидывать между всеми хостами.
          В данном случае я бы всё таки рекомендовал регистрацию бесплатного домена.

Отправить ответ

Ваш e-mail не будет опубликован.


*