Для организации удалённого доступа к вашей локальной сети с рабочих станций, расположенных в недоверенных сетях, широко применяется технология виртуальной частной сети VPN. Одним из решений для реализации VPN-канала является программное обеспечение с открытым исходным кодом OpenVPN. Данное руководство – о том, как установить и настроить сервер OpenVPN на CentOS Stream. Для выполнения работ по теме настоящего мануала вам понадобится два сервера: первый будет выступать в качестве сервера OpenVPN, на втором мы развернём центр сертификации (в руководстве он будет фигурировать как сервер ЦС). Сервер ЦС можно развернуть на том же VPS, на котором установлен сервер OpenVPN. Но в этом случае ваш VPN-канал становится уязвимым по целому ряду причин. Поэтому в данном мануале мы будем разворачивать сервер ЦС на VPS, отличном от VPS сервера OpenVPN, с установленной ОС CentOS Stream.
Установка OpenVPN и создание PKI
На первом шаге необходимо произвести установку OpenVPN, а также, программного обеспечения для управления инфраструктурой открытых ключей PKI. Эти работы нужно будет произвести как на сервере OpenVPN, так и на сервере ЦС.
В CentOS Stream и OpenVPN, и Easy-RSA не установлены как приложения по умолчанию. Для инсталляции этих пакетов вам нужно будет задействовать репозиторий EPEL (Extra Packages for Enterprise Linux). Этот репозиторий сейчас является самым популярным неофициальным репозиторием CentOS. В данном репозитории находится большое количество пакетов для CentOS в формате RPM.
Инсталляция этих пакетов запускается следующим образом:
- Сначала необходимо установить репозиторий EPEL:
$ sudo dnf install epel-release
- И только после этого, запустите установку интересующих нас пакетов:
$ sudo dnf install openvpn easy-rsa
По окончании установки в домашнем каталоге своего пользователя необходимо создать папку /easy-rsa
/:
$ cd ~
$ sudo mkdir easy-rsa
И далее, создайте симлинк при помощи easyrsa
:
$ sudo ln -s /usr/share/easy-rsa/3/* ~/easy-rsa/
В данном случае мы используем символьную ссылку для того, чтобы любая корректировка пакета easy-rsa
немедленно отражалась бы в скриптах PKI.
Теперь нужно будет на сервере OpenVPN произвести настройку PKI, структуры, которая будет управлять сертификатами клиентов вашего канала VPN. Для чего, необходимо подключиться к серверу OpenVPN, перейти в папку /easy-rsa/
и там создать файл vars
, например, с помощью редактора vi:
$ cd ~/easy-rsa
$ sudo vi vars
Следующие строки необходимо скопировать в этот файл:
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"
Для вставки блока текста в файл с использованием редактора vi, нажмите клавишу i
(включится режим “insert”). После этого, если вы подключены к серверу по SSH, для вставки из буфера обмена нажмите правую клавишу мыши и нажмите ESC
(выключится режим “insert”). Затем, для сохранения изменений и выхода из файла, нажмите :
(двоеточие), наберите wq
и нажмите Enter
.
Смысл скопированных строк заключается в том, что при работе с сертификатами будет применяться криптосистема на эллиптических кривых ECC, то есть, для установки канала клиент-сервер будут использоваться алгоритмы эллиптической кривой.
Далее, необходимо при помощи easyrsa
создать директорию PKI:
$ cd ~/easy-rsa
$ sudo ./easyrsa init-pki
Вывод работы скрипта выглядит примерно так:
Настройка PKI на сервере ЦС
Далее, похожую настройку PKI необходимо сделать на сервере ЦС. Сначала, нужно так же инициировать PKI в папке /easy-rsa/
. Для запуска необходимо набрать:
$ cd ~/easy-rsa
$ sudo ./easyrsa init-pki
В директории /easy-rsa/
нужно создать файл vars
:
$ cd ~/easy-rsa
$ sudo vi vars
В созданный файл vars
скопируйте следующие строки и отредактируйте их в соответствии с информацией, относящейся к закрытой сети вашей организации, но не оставляйте их пустыми:
set_var EASYRSA_REQ_COUNTRY "RUS"
set_var EASYRSA_REQ_PROVINCE "Tambov"
set_var EASYRSA_REQ_CITY "City of Tambov"
set_var EASYRSA_REQ_ORG "Your Organisation Name"
set_var EASYRSA_REQ_EMAIL "mail@your-organisation.org"
set_var EASYRSA_REQ_OU "LLC"
set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"
Закройте файл сохранив изменения и запустите скрипт easyrsa
с использованием параметра build-ca
, для чего наберите:
$ sudo ./easyrsa build-ca
Здесь система просит вас придумать и набрать парольную фразу для создаваемых ключей. Эту парольную фразу необходимо будет вводить каждый раз, когда вы будете взаимодействовать с центром сертификации, например, при создании или отзыве сертификата. Также, необходимо придумать и ввести Common Name (CN), которое будет обозначать ваш ЦС, или, нажав Enter
, принять имя предлагаемое по умолчанию.
И теперь, у вас есть два файла – ~/easy-rsa/pki/ca.crt
и ~/easy-rsa/pki/private/ca.key
. Эти файлы – открытый и секретный ключ вашего ЦС.
Открытый ключ будет использоваться клиентами вашего VPN для того, чтобы они были уверены, что являются частью единой сети, и каждый из них будет иметь копию этого файла. Секретный ключ нужен будет для подписания сертификатов клиентов вашей сети; он будет находиться исключительно на сервере ЦС, в связи в чем, сервер ЦС желательно вывести в оффлайн, чтобы не допустить утечки секретного ключа в результате атаки злоумышленника.
Теперь, когда настройка сервера ЦС завершена, необходимо добавить созданный открытый ключ ЦС на сервер OpenVPN. Другими словами, на сервере OpenVPN нужно создать копию файла ca.crt
. Для этого подключитесь к серверу ЦС, перейдите в директорию с созданным открытым ключом и выведите на экран содержимое ca.crt
:
$ cd ~/easy-rsa/pki
$ cat ca.crt
Вывод команды выглядит примерно так:
Содержимое этого файла, то есть, то что выведено на экран, нужно полностью скопировать в буфер обмена. После чего, переключитесь на сервер OpenVPN, перейдите в каталог /etc/pki/ca-trust/source/anchors/
и там создайте файл ca.crt
:
$ cd /etc/pki/ca-trust/source/anchors
$ sudo vi ca.crt
Вставьте в открытый файл скопированный блок текста и закройте файл с сохранением внесённых изменений.
Затем запустите команду:
$ sudo update-ca-trust
Этой командой импорт созданного сертификата в хранилище операционной системы сервера OpenVPN. Таким образом, теперь подписанные сервером ЦС сертификаты будут иметь доверенные отношения с сервером OpenVPN.
Создание и подписание запроса сертификата
Теперь всё готово к следующему этапу настройки, а именно, к созданию секретного ключа и запроса подписи сертификата. После их создания на сервере OpenVPN, нужно будет передать запрос на сервер ЦС для подписания, после чего, установить подписанный сертификат на сервере OpenVPN.
Подключитесь к серверу OpenVPN, перейдите в папку ~/easy-rsa/
:
$ cd ~/easy-rsa
Далее, нужно будет запустить скрипт easyrsa
с опцией gen-req
, после которого нужно будет указать запоминающееся имя для компьютера. В данном мануале это будет server
, вы же можете использовать своё. Для создания запроса без защиты паролем, к команде добавьте nopass
.
$ sudo ./easyrsa gen-req server nopass
Итогом работы скрипта будет генерация секретного ключа и файла запроса server.req
. Файл ключа нужно будет скопировать в /etc/openvpn/server/
:
$ sudo cp ~/easy-rsa/pki/private/server.key /etc/openvpn/server/
Далее, для передачи запроса на сервер ЦС, необходимо запустить следующую инструкцию, где adm-user
– имя вашего пользователя на сервере ЦС, который имеет привилегированные права, а X.X.X.X
– IP-адрес сервера ЦС:
$ sudo scp ~/easy-rsa/pki/reqs/server.req adm-user@X.X.X.X:/tmp
Ту же команду можно применить используя доменное имя сервера вместо IP-адреса:
$ sudo scp ~/easy-rsa/pki/reqs/server.req adm-user@ca-server.host:/tmp
Для идентификации сервера по имени, это имя должно быть прикреплено к вашему VPS в качестве домена на закладке “Домены” сайта RUVDS:
При выполнении команды система попросит вас набрать пароль учётной записи сервера ЦС (в данном случае это – adm-user
). Вывод исполнения инструкции будет выглядеть примерно так:
The authenticity of host 'my-server.space (192.168.215.32)' can't be established.
ECDSA key fingerprint is SHA256:10Vf8pKCjm117MogonbaHFJw6pL+y4dnByZGYi6o6Aw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'my-server.space,192.168.215.32' (ECDSA) to the list of known hosts.
adm-user@my-server.space's password:
server.req
Теперь необходимо подключиться к серверу ЦС и запустить импорт запроса сертификата при помощи easyrsa
:
$ cd ~/easy-rsa
$ sudo ./easyrsa import-req /tmp/server.req server
Далее, с помощью того же скрипта easyrsa
, но уже с параметром sign-req
, запустите подписание запроса. С параметром sign-req
необходимо указать тип запроса: server
или client
. В нашем случае тип запроса будет server
, так как мы подписываем запрос сертификата сервера OpenVPN:
$ sudo ./easyrsa sign-req server server
Чтобы подтвердить надёжность источника запроса, нужно ввести Yes
, после чего нажать Enter
.
Таким образом, в результате подписания запроса сертификата сервера OpenVPN секретным ключом сервера ЦС вы получили файл server.crt
. Этот файл, а также, файл, который содержит собственный доверенный сертификат, ca.crt
, необходимо скопировать на сервер OpenVPN (здесь – adm-user
– имя вашего пользователя на сервере OpenVPN, который имеет привилегированные права, а X.X.X.X
– IP-адрес сервера OpenVPN):
$ sudo scp ~/easy-rsa/pki/issued/server.crt adm-user@X.X.X.X:/tmp
$ sudo scp ~/easy-rsa/pki/ca.crt adm-user@X.X.X.X:/tmp
При подключении к серверу OpenVPN, вы также, как и на шаге передачи запроса сертификата на сервер ЦС, вместо IP-адреса можете использовать доменное имя сервера принимающей стороны. Имя домена, при этом, также должно быть привязано к VPS во вкладке “Домены”.
После завершения передачи файлов, подключитесь к серверу OpenVPN и скопируйте server.crt
и ca.crt
из папки /tmp/
в папку /etc/openvpn/server/
:
$ sudo cp /tmp/server.crt /etc/openvpn/server
$ sudo cp /tmp/ca.crt /etc/openvpn/server
Далее, для сервера OpenVPN и всех его клиентов необходимо добавить общий закрытый ключ. Эту процедуру будем производить при помощи специальной директивы OpenVPN – tls-crypt
. Данная опция позволит повысить уровень безопасности канала VPN в части выявления сетевого трафика OpenVPN, возможности сервера OpenVPN управлять недоверенным трафиком и сканированием портов, связывающим ресурсы сервера.
Для получения ключа нужно перейти в каталог ~/easy-rsa/
:
$ cd ~/easy-rsa
И запустить:
$ sudo openvpn --genkey --secret ta.key
Полученный при этом файл ta.key
необходимо скопировать в /etc/openvpn/server/
:
$ sudo cp ta.key /etc/openvpn/server
Завершив эти действия, вы готовы к генерации сертификатов клиентов и ключей пользователей для подключения к каналу VPN.
Генерация ключей и сертификатов
Здесь мы создадим скрипт на сервере OpenVPN, с помощью которого будем генерировать конфигурационные файлы для клиентов со всеми необходимыми сертификатами и ключами в автоматическом режиме, благодаря чему отпадёт необходимость передавать сертификаты, ключи и конфигурационные файлы в клиентские системы.
Далее, мы сгенерируем пару сертификат-ключ для первого клиента, уникальным именем которого будет 1st_Client. Для каждого последующего клиента описанную последовательность действий необходимо будет повторить.
Начнём с создания директории, где будут храниться файлы ключей и сертификаты клиентов вашего VPN. С нашем случае директория будет называться /vpn-clients/
:
$ mkdir -p ~/vpn-clients/keys
$ chmod -R 700 ~/vpn-clients
Далее, из папки /easy-rsa/
запустите скрипт easyrsa
, применив опции gen-req
и nopass
и уникальное имя клиента:
$ cd ~/easy-rsa
$ sudo ./easyrsa gen-req 1st_Client nopass
Скопируйте 1st_Client.key
в ~/vpn-clients/keys/
:
$ cp ~/easy-rsa/pki/private/1st_Client.key ~/vpn-clients/keys/
После чего, используя scp
, необходимо передать файл 1st_Client.req
на сервер ЦС, используя его IP-адрес, либо доменное имя:
$ sudo scp ~/easy-rsa/pki/reqs/1st_Client.req adm-user@X.X.X.X:/tmp
Затем подключитесь к серверу ЦС, перейдите в папкуг /easy-rsa/
и запустите импорт запроса сертификата:
$ cd ~/easy-rsa
$ sudo ./easyrsa import-req /tmp/1st_Client.req 1st_Client
После чего подпишите запрос, указав тип запроса client
:
$ sudo ./easyrsa sign-req client 1st_Client
Результатом подписания будет создание файла сертификата 1st_Client.crt
. Этот файл нужно снова передать на сервер OpenVPN, также, с использованием его IP-адреса, либо доменного имени:
$ sudo scp ~/easy-rsa/pki/issued/client1.crt adm-user@X.X.X.X:/tmp
После этого снова подключитесь к серверу OpenVPN и скопируйте файл 1st_Client.crt в папку ~/vpn-clients/keys/
:
$ cp /tmp/1st_Client.crt ~/vpn-clients/keys/
Файлы ca.crt
и ta.key
необходимо скопировать в каталог ~/vpn-clients/keys/
с предоставлением им соответствующих прав:
$ cp ~/easy-rsa/ta.key ~/vpn-clients/keys/
$ sudo cp /etc/openvpn/server/ca.crt ~/vpn-clients/keys/
$ sudo chown adm-user.adm-user ~/vpn-clients/keys/*
Таким образом, вы создали файлы сертификатов и ключей для сервера и первого клиента, разместив их в соответствующих каталогах сервера OpenVPN.
Настройка OpenVPN
На данном этапе необходимо произвести некоторые настройки конфигурации сервера OpenVPN.
Во первых, файл server.conf
необходимо скопировать в папку OpenVPN:
$ sudo cp /usr/share/doc/openvpn/sample/sample-config-files/server.conf /etc/openvpn/server/
Этот файл нужно будет открыть для редактирования:
$ sudo vi /etc/openvpn/server/server.conf
В разделе HMAC
файла server.conf
необходмио найти и закомментировать строку tls-auth
, поставив знак ;
перед этой строкой, а после неё нужно добавить строку tls-crypt ta.key
:
Далее, в этом же файле необходимо найти строку cipher AES-256-CBC
, и так же закомментировать её. После чего вставьте в файл строки cipher AES-256-GCM
и auth SHA256
:
Затем найдите фрагмент текста, содержащий dh dh2048.pem
или dh dh.pem
и закомментируйте эту строку, так как в данном случае отсутствует необходимость использовать файл Диффи-Хеллмана. Следующей строкой добавьте текст dh none
:
А для того, чтобы OpenVPN мог запускаться без привилегий, необходимо снять комментарий перед строками user nobody
и group nogroup
:
После завершения редактирования закройте файл, сохранив изменения.
Конфигурация сети на сервере OpenVPN
На следующем этапе необходимо внести изменения в настройки сети, которые будем делать на сервере OpenVPN. Корректировка данных параметров обеспечит правильную маршрутизацию трафика. Для начала откройте для редактирования конфигурационный файл /etc/sysctl.conf
:
$ sudo vi /etc/sysctl.conf
И вставьте в него строку:
net.ipv4.ip_forward = 1
Закройте файл, сохранив изменения. Чтобы новая настройка применилась, наберите:
$ sudo sysctl -p
Настройка сетевого экрана
На этом шаге необходимо произвести настройку брандмауэра для того, чтобы сервер знал, как он должен обрабатывать клиентский трафик. В качестве сетевого экрана на CentOS Stream установлен firewalld
.
Сначала необходимо узнать активную зону firewalld
:
$ sudo firewall-cmd --get-active-zones
Теперь добавьте службу OpenVPN в список разрешенных сервисов firewalld
:
$ sudo firewall-cmd --get-active-zones
После этого сервис OpenVPN необходимо добавить в список разрешённых сервисов брандмауэра:
$ sudo firewall-cmd --permanent --add-service openvpn
$ sudo firewall-cmd --permanent --zone=trusted --add-service openvpn
Перезапустите firewalld
:
$ sudo firewall-cmd --reload
Чтобы убедиться, что настройка применилась, нужно вывести список разрешённых брандмауэром служб, для чего наберите:
$ sudo firewall-cmd --list-services --zone=trusted
Теперь, необходимо в firewalld
добавить правило подмены, которое позволит серверу преобразовывать адреса клиентов в открытый адрес сервера, после чего, сервер выполняет обратное преобразование трафика, который уходит обратно клиенту:
$ sudo firewall-cmd --add-masquerade
$ sudo firewall-cmd --add-masquerade --permanent
Проверить корректность добавления подмены можно набрав:
$ sudo firewall-cmd --query-masquerade
Теперь нужно создать правило подмены для вашей подсети. Чтобы добавить правило маршрутизации, будем использовать переменную, назовём её SHELLVAR
, присвоив ей значение первичного сетевого интерфейса:
$ SHELLVAR=(ip route awk /default via/ print 5)
$ sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o $SHELLVAR -j MASQUERADE
После чего перезапустите firewalld
:
$ sudo firewall-cmd --reload
Запуск сервиса OpenVPN
На данном шаге произведите запуск службы OpenVPN при помощи systemctl c включением его в автозагрузку:
$ sudo systemctl -f enable openvpn-server@server.service
$ sudo systemctl start openvpn-server@server.service
Далее, запустите проверку статуса сервиса:
$ sudo systemctl status openvpn-server@server.service
Корректный статус службы должен выглядеть примерно так:
Конфигурация клиентов
На этом этапе мы создадим скрипт, с помощью которого можно будет генерировать уникальные файлы клиентов, их ключи и сертификаты. Для этого мы будем использовать базовую инфраструктуру конфигурации.
Данная операция сможет оптимизировать работу с точки зрения автоматизации ваших действий при организации доступа к VPN-каналу для каждого из клиентов.
Для этого создайте директорию, где будут сохраняться данные ваших клиентов:
$ mkdir -p ~/vpn-clients/files
Образец конфигурации клиента скопируйте в папку /vpn-clients/
:
$ cp /usr/share/doc/openvpn/sample/sample-config-files/client.conf ~/vpn-clients/base.conf
Откройте для редактирования файл base.conf
:
$ sudo vi ~/vpn-clients/base.conf
В строке, начинающейся со слова, remote
нужно будет заменить номер порта 1194 на необходимый вам, если ранее вы его меняли. Этот порт прослушивает сервер OpenVPN:
remote X.X.X.X 1194
Проверьте корректность протокола, указанного в строке:
proto udp
Со следующих строк необходимо снять комментарий:
user nobody
group nobody
Следующие строки, наоборот, закомментируйте (на вашем сервере уже произведена настройка на использование tls-crypt
вместо tls-auth
):
;ca ca.crt
;cert client.crt
;key client.key
;tls-auth ta.key 1
Значения переменных в следующих строках должны соответствовать переменным, прописанными в файле /etc/openvpn/server.conf
. Таким образом, в файле должны присутствовать следующие строки:
cipher AES-256-GCM
auth SHA256
Далее, вставьте строку:
key-direction 1
И в довершение добавьте строки, с которых нужно будет снять комментарий только для Linux-клиентов:
; script-security 2
; up /etc/openvpn/update-resolv-conf
; down /etc/openvpn/update-resolv-conf
Теперь можно выйти из файла, сохранив изменения:
Далее, необходимо создать скрипт make_config.sh
. Этот исполняемый файл будет создавать базовую конфигурацию клиента в папке ~/vpn-clients/files/
:
$ sudo vi ~/vpn-clients/make_config.sh
Содержимое скрипта:
#!/bin/bash
# First argument: Client identifier
KEY_DIR=~/vpn-clients/keys
OUTPUT_DIR=~/vpn-clients/files
BASE_CONFIG=~/vpn-clients/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-crypt>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-crypt>') \
> ${OUTPUT_DIR}/${1}.ovpn
Закройте файл с сохранением изменений.
Также, необходимо дать этому файлу привилегии исполняемого:
$ chmod 700 ~/vpn-clients/make_config.sh
Создание клиента
Ранее, вы создали файлы сертификата и ключа 1st_Client.crt
и 1st_Client.key
. Конфигурационный файл для этого клиента можно сгенерировать, запустив созданный скрипт из директории /vpn-clients/
:
$ cd ~/vpn-clients
$ sudo ./make_config.sh 1st_Client
Результатом работы скрипта будет создание файла 1st_Client.ovpn
в каталоге ~/vpn-clients/files/
.
Созданный файл предназначен для передачи клиенту, который, в свою очередь, должен установить его на своё устройство. Это устройство клиент будет использовать для работы в вашей закрытой сети через настроенный вами сервер OpenVPN. На том же клиентском устройстве (смартфон, ноутбук, десктоп) должно быть установлено ПО OpenVPN. Именно к этому ПО клиент подключает полученнный от вас файл с расширением ovpn
. К примеру, в случае, если компьютер клиента работает под управлением операционной системы семейства Windows, то необходимо будет с сайта OpenVPN скачать для установки Windows-дистрибутив, установить его на рабочую станцию и скопировать файл сертификата в одну из директорий, которую приложение укажет при первом своём запуске. При помощи этого ПО клиент сможет осуществлять работу с ресурсами извне, несмотря на то, что используемые им ресурсы будут расположены внутри вашей сети. При этом, вам не нужно будет вносить изменения в настройки вашего брандмауэра, тем самым понижая уровень защищённости сети.