· 16 мин чтения

OpenVPN-сервер на Linux с нуля: от PKI до клиентских профилей

Семёнов Евгений Сергеевич, директор АйТи Фреш. За 15+ лет я поднял больше сотни OpenVPN-инсталляций — от VPS для фрилансера до многофилиальных корпоративных узлов с отказоустойчивостью. И каждый раз вижу типовые ошибки: CA-ключ лежит на сервере, все клиенты используют один сертификат, TCP вместо UDP, дефолтный 1194, нет CRL. В статье — рабочий гайд, которым я пользуюсь у нас на практике: Ubuntu 22.04, easy-rsa, TLS-crypt, split-tunnel, нормальный мониторинг.

Когда OpenVPN действительно нужен

OpenVPN — один из старейших open-source VPN, которому уже больше 20 лет. На фоне современных WireGuard и VLESS у него есть минусы (однопоточность, ресурсоёмкая криптография), но и свои плюсы:

Я рекомендую OpenVPN когда нужна интеграция с существующим AD/NPS, split-tunneling, учёт трафика на пользователя, или когда клиент работает с оборудованием MikroTik/Fortinet, которое нативно поддерживает OpenVPN.

Подготовка сервера

Беру свежий VPS или виртуалку: Ubuntu 22.04 LTS, 2 vCPU с AES-NI, 2 ГБ RAM, 30 ГБ SSD, белый IP. На нашем стенде в дата-центре МТС типовая конфигурация для клиента до 100 сотрудников — виртуалка в кластере Proxmox на хостах Dell Xeon Platinum 8280 с AES-NI, которая спокойно держит 250 Мбит/с зашифрованного трафика на ядро.

# Первичная настройка
apt update && apt upgrade -y
apt install openvpn easy-rsa ufw fail2ban iptables-persistent -y

# Отключаем IPv6, если не используется
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf

# Включаем форвардинг
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-openvpn.conf
sysctl -p /etc/sysctl.d/99-openvpn.conf

PKI через easy-rsa

easy-rsa — скрипты управления собственным CA. Я всегда поднимаю CA на отдельной машине (или в chroot-директории на сервере), чтобы приватный ключ CA никогда не попадал на рабочий OpenVPN:

mkdir -p /root/openvpn-ca
cp -r /usr/share/easy-rsa/* /root/openvpn-ca/
cd /root/openvpn-ca

# Инициализация PKI
./easyrsa init-pki

# Параметры CA в vars
cat > pki/vars << EOF
set_var EASYRSA_REQ_COUNTRY    "RU"
set_var EASYRSA_REQ_PROVINCE   "Moscow"
set_var EASYRSA_REQ_CITY       "Moscow"
set_var EASYRSA_REQ_ORG        "ITfresh"
set_var EASYRSA_REQ_EMAIL      "admin@itfresh.ru"
set_var EASYRSA_REQ_OU         "IT"
set_var EASYRSA_KEY_SIZE       2048
set_var EASYRSA_ALGO           rsa
set_var EASYRSA_CA_EXPIRE      3650
set_var EASYRSA_CERT_EXPIRE    1095
EOF

# Создаём CA (запомните парольную фразу!)
./easyrsa build-ca

# Серверный сертификат без пароля
./easyrsa --batch build-server-full server nopass

# Параметры DH и TLS-crypt ключ
./easyrsa gen-dh
openvpn --genkey secret pki/ta.key

После создания ключи лежат в pki/. Для сервера нам нужны: ca.crt, issued/server.crt, private/server.key, dh.pem, ta.key.

Конфигурация сервера

Копируем ключи в /etc/openvpn/server/, создаём конфиг:

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun

ca   /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key  /etc/openvpn/server/server.key
dh   /etc/openvpn/server/dh.pem
tls-crypt /etc/openvpn/server/ta.key

topology subnet
server 10.88.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# Корпоративные сети, к которым открываем доступ
push "route 10.10.0.0 255.255.0.0"
push "route 192.168.100.0 255.255.255.0"
push "dhcp-option DNS 10.10.0.10"
push "dhcp-option DOMAIN corp.example.ru"

# Split-tunnel — не гнать весь трафик в VPN
# Уберите комментарий, если нужен full-tunnel:
# push "redirect-gateway def1 bypass-dhcp"

client-to-client
keepalive 10 120

cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305
auth SHA256
tls-version-min 1.2

user nobody
group nogroup
persist-key
persist-tun

status /var/log/openvpn/status.log 30
log-append /var/log/openvpn/server.log
verb 3
mute 20

# CRL для отзыва сертификатов
crl-verify /etc/openvpn/server/crl.pem

# Аутентификация по сертификату + логин/пароль через PAM
# (раскомментируйте, если нужна двухфакторная)
# plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login
# verify-client-cert require
systemctl enable --now openvpn-server@server
systemctl status openvpn-server@server
ss -ulnp | grep 1194

Firewall и NAT

Без правильного firewall VPN работать не будет — клиенты получат IP, но в корпоративную сеть пакеты не пройдут:

# UFW allow
ufw allow 22/tcp
ufw allow 1194/udp
ufw default deny incoming
ufw default allow outgoing

# В /etc/ufw/before.rules в начало файла добавляем:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.88.0.0/24 -o eth0 -j MASQUERADE
COMMIT

# В /etc/default/ufw меняем
DEFAULT_FORWARD_POLICY="ACCEPT"

ufw disable && ufw enable

# Проверяем
iptables -t nat -L POSTROUTING -n -v

Для корпоративных сетей, к которым открыт доступ по VPN, на маршрутизаторе корпоративной сети добавляем обратный маршрут: 10.88.0.0/24 via IP_OpenVPN_сервера.

Клиентские сертификаты и ovpn-профиль

Я никогда не раздаю один сертификат всем сотрудникам. Для каждого — свой:

# На машине с CA
cd /root/openvpn-ca
./easyrsa --batch build-client-full ivanov nopass

# Собираем inline-профиль
cat > /root/clients/ivanov.ovpn << 'EOF'
client
dev tun
proto udp
remote vpn.example.ru 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
verb 3

<ca>
EOF
cat pki/ca.crt >> /root/clients/ivanov.ovpn
echo "</ca>" >> /root/clients/ivanov.ovpn

echo "<cert>" >> /root/clients/ivanov.ovpn
openssl x509 -in pki/issued/ivanov.crt >> /root/clients/ivanov.ovpn
echo "</cert>" >> /root/clients/ivanov.ovpn

echo "<key>" >> /root/clients/ivanov.ovpn
cat pki/private/ivanov.key >> /root/clients/ivanov.ovpn
echo "</key>" >> /root/clients/ivanov.ovpn

echo "<tls-crypt>" >> /root/clients/ivanov.ovpn
cat pki/ta.key >> /root/clients/ivanov.ovpn
echo "</tls-crypt>" >> /root/clients/ivanov.ovpn

Файл ivanov.ovpn отправляется сотруднику (лучше через корпоративный чат или зашифрованный канал) и импортируется в OpenVPN Connect или Tunnelblick.

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

Уволили сотрудника — обязательно отзываем его сертификат, иначе он продолжит ходить в корпоративную сеть:

cd /root/openvpn-ca
./easyrsa revoke ivanov
./easyrsa gen-crl
cp pki/crl.pem /etc/openvpn/server/

systemctl reload openvpn-server@server

CRL нужно обновлять регулярно даже без отзывов — срок его действия 180 дней по умолчанию. Я ставлю в cron ежемесячную регенерацию.

Таблица параметров для разных сценариев

СценарийПротоколПортCipherCompression
Домашние пользователиUDP1194AES-256-GCMНет
Обход блокировокTCP443CHACHA20-POLY1305Нет
Корпоративный филиалUDP1194AES-128-GCMНет
Медленный канал (3G)UDP1194CHACHA20-POLY1305LZ4-v2

Мини-кейс: сеть из 6 филиалов

В октябре 2025 года к нам на проект пришла сеть розничной торговли — 6 филиалов по Москве и Подмосковью, 85 рабочих мест. Задача — связать все филиалы с центральным офисом и дать удалённый доступ 15 руководителям. На центральном офисе стоит MikroTik CCR2004, в филиалах — MikroTik hEX S.

Решение:

Пропускная способность между филиалами — 180–220 Мбит/с, задержка до центра — 4–8 мс. Стоимость проекта: 165 000 руб. за разовую настройку + 12 000 руб./мес. за мониторинг и сопровождение. За 6 месяцев — один инцидент (выпал MikroTik в филиале после отключения электричества, перезалив сертификата за 15 минут).

Мониторинг и аудит

status.log на сервере обновляется раз в 30 секунд и показывает активные сессии с IP, временем коннекта, пройденным трафиком. Я парсю его через openvpn-exporter и отправляю в Prometheus:

# Docker-контейнер
docker run -d --name openvpn-exporter \
  --network host \
  -v /var/log/openvpn/status.log:/etc/openvpn_exporter/status.log:ro \
  kumina/openvpn-exporter \
  -openvpn.status_paths /etc/openvpn_exporter/status.log

В Grafana собираю дашборд: количество активных сессий, топ-10 пользователей по трафику, карта гео-распределения подключений, ошибки аутентификации. Для корпоративного аудита критически важно видеть, кто когда подключался и откуда.

Типичные ошибки при развёртывании

Настроим OpenVPN для офиса за 2–3 дня

Разворачиваем корпоративный OpenVPN с PKI, клиентскими профилями под каждого сотрудника, интеграцией с AD, мониторингом в Grafana. Работаем с инфраструктурой от 10 до 500 пользователей, VPS или ваши серверы. 15+ лет опыта, выделенные SLA, круглосуточная поддержка.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — частые вопросы по OpenVPN

UDP или TCP выбрать для OpenVPN?
По умолчанию — UDP на 1194 или 443. UDP быстрее и стабильнее на потерях. TCP используйте только как fallback, когда UDP режется провайдером. Можно поднять два инстанса и раздать клиентам оба профиля.
Сколько клиентов выдержит один OpenVPN?
На VPS 2 vCPU/2 ГБ — до 100 одновременных сессий. На выделенном сервере с AES-NI — 500+. Узким местом обычно становится однопоточность OpenVPN — для больших инсталляций разворачивают несколько инстансов за балансировщиком.
Нужен ли статический IP для OpenVPN-сервера?
Предпочтительно да. Если IP меняется — клиентам приходится менять remote-адрес в конфиге. Либо используйте DynDNS-сервис с автоматическим обновлением A-записи.
Безопасно ли хранить CA-ключ на сервере?
Нет. CA-ключ должен лежать на отдельной машине или на внешнем носителе. На сервере хранятся только серверный сертификат и CRL. Компрометация OpenVPN-сервера не должна означать компрометацию CA.
Как отозвать сертификат уволенного сотрудника?
easy-rsa revoke client-name, затем gen-crl и скопировать crl.pem в директорию OpenVPN. Сервер проверяет CRL при каждом подключении — клиент с отозванным сертификатом получит отказ.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.