MAATRIX / Блог / Multi-user OpenVPN с сертификатами через easy-rsa: управление доступом команды

Multi-user OpenVPN с сертификатами через easy-rsa: управление доступом команды

MAATRIX

Когда в команде больше двух-трёх человек, один общий .ovpn-файл на всех превращается в проблему: непонятно, кто именно подключён, а при увольнении сотрудника приходится либо менять пароль всем разом, либо пересобирать сервер целиком. Решение — собственный удостоверяющий центр (CA) на easy-rsa: у каждого человека свой сертификат, а отзыв доступа занимает одну команду и не трогает остальных.

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

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

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

Почему общий сертификат — плохая идея для команды

Быстрая установка OpenVPN обычно создаёт один клиентский сертификат и раздаёт его всем. Пока людей двое, это терпимо. С ростом команды вылезают три проблемы:

  • Нет аудита — в логах все подключения выглядят одинаково, вы не отличите сотрудника от того, кому файл переслали "на минутку".
  • Отзыв доступа = смена секрета для всех — уволили человека, значит либо оставляете ему рабочий доступ, либо меняете сертификат и заново раздаёте его всей команде.
  • Нет привязки к устройству — один .ovpn можно скопировать куда угодно, сервер этого не увидит.

Свой CA через easy-rsa снимает все три проблемы: каждый сертификат подписан один раз, привязан к конкретному Common Name (обычно — имени сотрудника), и отзывается индивидуально через список отзыва (CRL), который сервер перечитывает на лету.

Разворачиваем свой CA через easy-rsa

Дальше — сценарий для Ubuntu 24.04 / Debian 12 на арендованном VPS. Если сервер OpenVPN ещё не поднят, сначала разверните базовую установку по шагам из статьи про установку OpenVPN на Ubuntu 24.04.

Устанавливаем easy-rsa в отдельную PKI-директорию — не смешивайте её с конфигами сервера, так проще делать бэкап CA отдельно:

sudo apt update && sudo apt install -y easy-rsa
mkdir -p ~/pki-vpn && cd ~/pki-vpn
ln -s /usr/share/easy-rsa/* .
./easyrsa init-pki
./easyrsa build-ca nopass

Флаг nopass убирает пароль с ключа CA ради удобства выпуска сертификатов. Файл pki/private/ca.key — самое ценное, что у вас есть, его нельзя хранить на самом VPN-сервере. Держите PKI-директорию на отдельной защищённой машине, а на сервер копируйте только то, что нужно для его работы — сертификат сервера, ключ, CA-сертификат и CRL.

Выпускаем ключ и сертификат сервера:

./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh
openvpn --genkey secret ta.key

gen-dh может занять несколько минут даже на быстром CPU — это нормально.

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

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

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

Настройка сервера под multi-user

В /etc/openvpn/server/server.conf укажите пути к файлам из PKI и включите проверку CRL:

port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key
dh dh.pem
tls-auth ta.key 0
crl-verify crl.pem

topology subnet
server 10.8.0.0 255.255.255.0
client-config-dir /etc/openvpn/ccd
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"

keepalive 10 120
persist-key
persist-tun
verb 3

client-config-dir — ключ к управлению командой: позволяет задать каждому сотруднику фиксированный внутренний IP и отдельные маршруты:

sudo mkdir -p /etc/openvpn/ccd
echo "ifconfig-push 10.8.0.10 255.255.255.0" | sudo tee /etc/openvpn/ccd/ivanov

Если нужно жёстко запретить одновременный вход с одним сертификатом на двух устройствах, не добавляйте duplicate-cn в конфиг — второе подключение с тем же CN вышибет первое, и это будет видно в логе.

Выпуск сертификата на каждого сотрудника

Дальше — рутина, которую вы повторяете при каждом найме. Для сотрудника Иванова:

cd ~/pki-vpn
./easyrsa gen-req ivanov nopass
./easyrsa sign-req client ivanov

На этапе sign-req easy-rsa покажет отпечаток запроса и попросит подтвердить подпись — сверьте его с тем, что прислал сотрудник, если запрос генерировался не у вас.

Итоговый .ovpn собирается простым скриптом, который склеивает шаблон с содержимым сертификатов:

#!/bin/bash
CN="$1"; OUT="${CN}.ovpn"
cat client-template.txt > "$OUT"
echo "<ca>"   >> "$OUT"; cat pki/ca.crt          >> "$OUT"; echo "</ca>"   >> "$OUT"
echo "<cert>" >> "$OUT"; cat pki/issued/${CN}.crt >> "$OUT"; echo "</cert>" >> "$OUT"
echo "<key>"  >> "$OUT"; cat pki/private/${CN}.key >> "$OUT"; echo "</key>" >> "$OUT"
echo "<tls-auth>" >> "$OUT"; cat ta.key           >> "$OUT"; echo "</tls-auth>" >> "$OUT"
echo "key-direction 1" >> "$OUT"

В client-template.txt — обычные клиентские директивы (client, remote ваш-сервер 1194 udp, dev tun, remote-cert-tls server). Готовый ${CN}.ovpn передавайте сотруднику по защищённому каналу, не по почте открытым текстом.

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

Отзыв сертификата без пересборки сервера

Вот ради чего всё затевалось. Сотрудник уволился — отзываем именно его сертификат, не трогая остальных:

cd ~/pki-vpn
./easyrsa revoke ivanov
./easyrsa gen-crl
sudo cp pki/crl.pem /etc/openvpn/server/crl.pem
sudo chmod 644 /etc/openvpn/server/crl.pem

Перезапускать OpenVPN не обязательно — crl-verify заставляет процесс перечитывать файл при каждой новой попытке подключения. Если Иванов уже был подключён в момент отзыва, активная сессия упадёт на ближайшем keepalive-таймауте. Чтобы оборвать её прямо сейчас — зайдите в management-интерфейс OpenVPN (порт задаётся директивой management) и выполните kill ivanov, либо перезапустите сервис: это разорвёт все туннели разом, но легитимные пользователи переподключатся за секунды.

Держите бэкап ~/pki-vpn — потеряете ca.key, придётся пересобирать CA с нуля и перевыпускать сертификаты всей команде. Права на PKI-директорию ограничьте одним администратором; общие вопросы разграничения доступа на сервере разобраны в статье про пользователей и группы в Linux.

Учёт и мониторинг подключений

Раз у каждого сотрудника свой сертификат, лог сервера становится инструментом аудита. В server.conf включите файл статуса:

status /var/log/openvpn/openvpn-status.log 10
status-version 2

Файл обновляется каждые 10 секунд и показывает текущие подключения с указанием Common Name, реального IP клиента, внутреннего VPN-IP и объёма трафика. Для истории событий добавьте скрипты подключения/отключения:

script-security 2
client-connect /etc/openvpn/scripts/on-connect.sh
client-disconnect /etc/openvpn/scripts/on-disconnect.sh

Простейший on-connect.sh — одна строка вида echo "$(date) CONNECT $common_name $trusted_ip" >> /var/log/openvpn/access.log. Если сервер время от времени "теряет" пользователей или соединения обрываются без видимой причины, загляните в статью про типичные ошибки OpenVPN на сервере — там разобраны похожие ситуации отдельно от темы сертификатов.

Отдельно заведите таблицу (хоть CSV в PKI-директории) с колонками: имя, дата выпуска, дата отзыва, кто выпустил. easy-rsa хранит это в pki/index.txt, но человекочитаемый вид нужен, особенно если наймом и увольнениями занимается не тот, кто администрирует сервер.

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

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

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

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

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

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

Можно ли ограничить сотруднику доступ только к части внутренней сети, а не давать полный туннель?

Да, через client-config-dir пропишите для конкретного CN push "route ..." вместо общего redirect-gateway, либо используйте iroute в CCD-файле совместно с route на сервере — так у разных сотрудников будет разный набор подсетей на одном сервере.

Что если сотрудник потерял ноутбук с .ovpn-файлом?

Отзовите его сертификат так же, как при увольнении, и выпустите новый. Старый файл с этого момента бесполезен, даже если попадёт в чужие руки.

Нужно ли ставить пароль на приватный ключ клиента?

Для чувствительных сценариев — да: замените nopass на обычный gen-req без флага, easy-rsa запросит пароль на ключ. Добавит шаг при подключении, зато защитит от кражи самого файла.

CRL нужно обновлять по расписанию, даже если никого не отзывали?

Да — у crl.pem есть срок действия (по умолчанию около 180 дней, регулируется EASYRSA_CRL_DAYS). Просроченный файл заставит OpenVPN отклонять все подключения. Добавьте в cron ежемесячный easyrsa gen-crl с копированием на сервер.

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

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

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