Cайт веб-разработчика, программиста Ruby on Rails ESV Corp. Екатеринбург, Москва, Санкт-Петербург, Новосибирск, Первоуральск

Создание защищённого канала OpenVPN

Постараюсь вкратце, без лишней "воды" описать процесс создания и запуска в работу защищённого канала передачи данных между двумя узлами сети с использованием OpenVPN. Рассматривается установка в системе Linux Debian 12 Bookworm с использованием systemd. На начальном этапе важно прежде всего запустить работающий канал OpenVPN, а дальше уже заниматься изучением различных тонкостей его настроек и работы.

Материал основан на статьях из Интернет (список которых приведён в конце) и проверено всё на практике. Некоторые части информации вынесены в отдельные страницы:
Безопасность и шифрование в OpenVPN

Установка OpenVPN

sudo apt install openvpn easy-rsa -y

выполняется на обоих узлах сети - сервере и клиенте, в результате установки создается структура каталогов, на которые стоит обратить внимание:

/etc/openvpn - файлы конфигурации
/etc/openvpn/client - файлы конфигурации клинтской части
/etc/openvpn/server - файлы конфигурации серверной части
/usr/share/doc/openvpn - краткая документация и примеры конфигураций
/usr/share/easy-rsa - утилита EasyRSA

Создание сертификатов и ключей

Для создания ключей и сертификатов хорошей идеей будет добавить отдельную учётную запись, которая должна обладать правами выполнения команды sudo, и далее проводить все операции с ключами и сертификатами в ней, т.е. данная учётная запись у нас будет удостоверяющим центром (CA) или другими словами центром сертификации (ЦС). Имя ca-openvpn выбрано произвольно для наглядности.

adduser ca-openvpn
usermod -aG sudo ca-openvpn
usermod -rG users ca-openvpn

Далее все команды выполняем в созданном аккаунте, в домашнем каталоге пользователя.

mkdir ~/easy-rsa
ln -s /usr/share/easy-rsa/* ~/easy-rsa/
chmod 700 ~/easy-rsa

Создаём инфраструктуру публичных ключей (Public Key Infrastructure, PKI):

cd ~/easy-rsa
./easyrsa init-pki

в результате создаётся каталог ~/easy-rsa/pki и структура каталогов в нём - инфрастуктура PKI.

В каталоге инфраструктуры pki создаём файл (лучше использовать содержимое шаблона ~/easy-rsa/pki/vars.example) ~/easy-rsa/pki/vars следующего содержания (наши данные добавляем в конец файла), при этом важно, чтобы ни одно значение не оставалось пустым:

set_var EASYRSA_DIGEST         "sha512"

set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "California"
set_var EASYRSA_REQ_CITY       "San Francisco"
set_var EASYRSA_REQ_ORG        "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL      "me@example.net"
set_var EASYRSA_REQ_OU         "My Organizational Unit"

все определения EASYRSA_REQ_* заполняются, естественно, вашими собственными данными.

Создаём удостоверяющий центр CA (центр сертификации)

cd ~/easy-rsa
./easyrsa build-ca

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

Запрашивается два разных пароля: CA и PEM. PEM используется при генерации ключей и сертификатов сервера и клиента.

Вам также будет предложено указать общее имя (CN) вашего центра сертификации. CN — это имя, используемое для обозначения названия центра сертификации (удостоверяющего центра CA). Вы можете ввести любую строку символов в качестве общего имени ЦС, но для простоты нажмите ENTER, чтобы принять имя по умолчанию.

Чтобы избавиться от необходимости ввода пароля, можно при запуске команды build-ca задать опцию nopass:

./easyrsa build-ca nopass

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

Теперь у нас имеется два важных файла, ~/easy-rsa/pki/ca.crt и ~/easy-rsa/pki/private/ca.key. Эти файлы соответствуют публичному и частному компонентам Центра сертификации (удостоверяющего центра CA).

ca.crt — файл публичного сертификата ЦС. Пользователи, серверы и клиенты будут использовать этот сертификат для подтверждения единой сети доверия. Копия этого файла должна иметься у всех серверов и клиентов, использующих ваш ЦС. Все стороны будут использовать публичный сертификат для подтверждения подлинности системы и предотвращения атак через посредника. Данный файл указывается в конфигурации OpenVPN сервера и клиента.

ca.key — закрытый ключ, который используется только ЦС (нет необходимости копировать его на другие узлы сети), и ЦС будет использовать его для подписания сертификатов серверов и клиентов. Если злоумышленник получит доступ к файлу ca.key, все ключи будут скомпроментированы, и вам нужно будет уничтожить ЦС и полностью создать и обновить все ключи на всех узлах сети, использующих OpenVPN. Это очень важный файл - его содержимое должно быть известно только ЦС.

Выпустим и подпишем пару "ключ-сертификат" для сервера и клиента


Сервер

./easyrsa gen-req server-openvpn nopass
./easyrsa sign-req server server-openvpn

Здесь всё-таки можно сделать важное замечание. Первой командой мы создаём файл запроса, который может быть передан в ЦС, если он находится на другом узле сети, на другом компьютере. В ЦС его нужно импортировать с помощью команды:
./easyrsa import-req open-server.req open-server
после этого так же подписать и отправить обратно файл сертификата, а файл ключа уже есть - он создаётся при запросе. Таким образом мы можем создавать запрос на создание сертификата на любом другом компьютере, далее передаём этот запрос в ЦС, где он будет подписан, а возращён обратно сертификат. Более детально с этим процессом можно ознакомиться в источниках, которые были использованы для подготовки данной статьи (см. в конце статьи).

Ещё одно важное замечание. Если не указать опцию nopass, при генерации приватного ключа будет запрошен пароль. Этот пароль обеспечивает защиту, если приватный ключ будет скомпрометирован (украден злоумышленником). Пароль приватного ключа OpenVPN будет запрашиваться с консоли каждый раз при загрузке сервера и запуске OpenVPN. Поэтому для автоматического запуска службы OpenVPN на сервере, мы используем опцию nopass.

В результате выполнения этих команд мы получаем три файла для сервера OpenVPN:

req:~/easy-rsa/pki/reqs/server-openvpn.req - запрос
key: ~/easy-rsa/pki/private/server-openvpn.key - ключ
Certificate: ~/easy-rsa/pki/issued/server-openvpn.crt - сертификат


Клиент

Подобным же образом генерируем ключ и сертификат для клиента:

./easyrsa gen-req client-vpn nopass
./easyrsa sign-req client client-vpn

Далее сгенерированные файлы ca.crt (сертификат ЦС) и файлы ключа и сертификата для сервера и клиента нужно передать на узлы сети - соответственно, на сервер и клинтский узел сети:
сервер: ca.crt, server-openvpn.crt, server-openvpn.key
клиент: ca.crt, client-vpn.crt, client-vpn.key

Генерация файла Диффи-Хелмана

cd ~/easy-rsa
./easyrsa gen-dh
(создаётся файл ~/easy-rsa/pki/dh.pem)

либо (как указано в комментариях в файле примере конфигурации сервера OpenVPN):

openssl dhparam -out dh.pem 2048
(создаётся файл dh.pem в текщем каталоге)

Генерация дополнительной подписи HMAC для усиления защищённости канала OpenVPN

sudo openvpn --genkey secret ta.key
(создаётся файл ta.key в текщем каталоге)

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

Файл конфигурации сервера должен находится в /etc/openvpn/server/server.conf

В качестве образца файла конфигурации я рекомендую использовать файл примера конфигурации сервера /usr/share/doc/openvpn/examples/samle-config-files/server.conf - скопируйте его в основной файл конфигурации /etc/openvpn/server/server.conf.

Я предпочитаю не сваливать все файлы в одну кучу, поэтому располагаю файлы ключей, сертификатов и дополнительных подписей в отдельном каталоге /etc/openvpn/server/certificates, который создал отдельно, в нём размещаются файлы ключей для сервера VPN, сертификатов и подписей сервера: ca.crt, server-openvpn.crt, server-openvpn.key, dh.pem, ta.key (их генерация и местонахождение в ЦС было описано выше). Эти файлы необходимо передать на узел сети, который будет выполнять роль сервера OpenVPN, используя другие каналы передачи данных - лучше всего на отдельном физическом носителе. Важно так же установить аттрибуты этих фалов для чтения только пользователю root.

Вносим некоторые правки в файл конфигурации server.conf:

# например: local 192.168.1.2 - это адрес, на котором будет организован
# канал VPN, но это НЕ адрес внутренней сети канала OpenVPN
local <ip-адрес сервера>

# указываем порт, на котором сервер будет принимать подключение к VPN
# порт, который будет использоваться для соединения клиентов к VPN-серверу
# должен быть указан одинаковый и на сервере, и на клиенте
port 1194

# указан относительный путь до каталога расположения ключей и сертификатов
ca    certificates/ca.crt
cert  certificates/server-openvpn.crt
key   certificates/server-openvpn.key # This file should be kept secret

dh certificates/dh.pem

# раскомментируем директиву:
topology subnet

# указываем адресное пространство сети VPN, сервер в ней будет иметь
# адрес .1, в нашем случае 10.8.0.1
server 10.8.0.0 255.255.255.0

# вместо
## tls-auth ta.key 0 # This file is secret - эту директиву надо закоменнтировать
# прописываем:
tls-crypt  certificates/ta.key
# этот параметр должен быть одинаковыми на стороне сервера и клиента
## основываясь на дополнительной информации:
## --tls-auth is recommended when you are running OpenVPN in a mode 
## where it is listening for packets from any IP address,
## such as when --remote is not specified, or --remote is specified with --float.
# так же заменяем строку
##cipher AES-256-CBC
# на:
cipher AES-256-GCM
auth SHA256
# эти параметры должны быть одинаковыми на стороне сервера и клиента

# для работы службы OpenVPN лучше всего использовать отдельного 
# пользователя и группу, обладающих минимальными привелегиями, часто это
# nobody и nogroup, но можно создать специально пользователя
# openvpnd и группу openvpnd
# adduser: adduser --system --no-create-home --home /nonexistent --disabled-login --disabled-password --group openvpnd
# соответственно, в файле конфигурации дополнительно прописываем:
user openvpnd
group openvpnd

status /var/log/openvpn/openvpn-status.log

# для отслеживаня корректности работы службы рекомендую открыть
# файлы логов и установить повышенный уровень отчётов:
log /var/log/openvpn/openvpn.log

# для обычной работы сервера необходимо вернуть прежнее значение 3 или более меньшее
## verb 3
verb 6

# ===
# man openvpn says:
# --disable-dco
# Disable data channel offload (DCO).
# On Linux don't use the ovpn-dco device driver, but rather rely on the legacy tun module.
# You may want to use this option if your server needs to allow clients older than version 2.4 to connect.
#
# By default, the Linux kernel does not support DCO
#
disable-dco

Конфигурация клиента OpenVPN

Файл конфигурации сервера должен находится в /etc/openvpn/client/client.conf

В качестве образца файла конфигурации я рекомендую использовать файл примера конфигурации сервера /usr/share/doc/openvpn/examples/samle-config-files/client.conf - скопируйте его в основной файл конфигурации /etc/openvpn/client/client.conf.

По аналогии с сервером, ключи и сертификаты хранятся в отдельном каталоге /etc/openvpn/client/certificates, в который копируем фалы сертификатов и ключей клиента: ca.crt, client-vpn.crt, client-vpn.key, ta.key. Способ передачи файлов и установленные атрибуты точно такие же, как и на сервере.

Вносим некоторые правки в файл конфигурации client.conf:

# те же параметры, что и в параметрах VPN-сервера:
# local <ip-адрес сервера>
# и
# port <port number>
remote <ip-адрес сервера> <port number>

# точно такие же рекомендации по поводу отдельного пользователя и группы, как и на сервере
# adduser: adduser --system --no-create-home --home /nonexistent --disabled-login --disabled-password --group openvpnc
# соответственно, в файле конфигурации дополнительно прописываем:
user openvpnc
group openvpnc

# сертификаты и ключи, так же в отдельном каталоге
ca     certificates/ca.crt
cert   certificates/client-vpn.crt
key    certificates/client-vpn.key

tls-crypt   certificates/ta.key

cipher AES-256-GCM
auth SHA256

remote-cert-tls server

## verb 3
verb 6

status /var/log/openvpn/openvpn-status.log
log  /var/log/openvpn/openvpn.log

disable-dco

 

Запуск сервера и клиента OpenVPN

systemctl <command> openvpn-server@<config-name>

выполняет операции с сервером OpenVPN, используя файл конфигурации /etc/openvpn/server/<config-name>.conf , например:
systemctl enable openvpn-server@sever
systemctl start openvpn-server@sever

запускает сервер OpenVPN, используя конфигурацию сервера из файла: /etc/openvpn/server/server.conf

по аналогии с сервером точно так же производятся операции и с клиентом OpenVPN:

systemctl <command> openvpn-client@<config-name>

 

Используемые источники по теме

community.openvpn.net
openvpn.net/community-resources/
openvpn.net/community-resources/how-to/
habr.com/ru/articles/233971/
habr.com/ru/articles/839418/
dtgp.ru/blog/ustanovka-i-nastrojka-openvpn-na-debian-12.html