Установка OpenVPN на Ubuntu 20.04
Организация частных виртуальных сетей может быть очень полезной не только в организациях, но и для обмена данными между двумя вашими компьютерами или для повышения безопасности в сети.
Обновляем пакеты сервера
sudo apt-get update
sudo apt upgrade
Устанавливаем софт
sudo apt install openvpn easy-rsa iptables-persistent
При установке пакета iptables-persistent
потребется пара подтверждений создания файлов для правил сетей IPv4 и IPv6. Можем отвечать везде yes
.
Настраиваем центр сертификации
В OpenVPN открытый ключ называется сертификатом и имеет расширение .crt, а закрытый ключ так и называется ключом, его расширение - .key. Обслуживать всё это дело будут скрипты Easy-RSA.
Для того чтобы после обновления системы все сертификаты и настройки не были стёрты, скопируем набор скриптов из каталога /usr/share/easy-rsa куда-нибудь, например, в /etc/openvpn/:
sudo mkdir /etc/openvpn/easy-rsa
sudo cp -R /usr/share/easy-rsa /etc/openvpn/
Создадим центр сертификации в этой папке. Для этого сначала перейдем в неё:
cd /etc/openvpn/easy-rsa/
Сконфигурируем переменные окружения, предварительно скопировав файл примеров в новый:
sudo cp vars.example vars
Отредактируем файл:
sudo nano vars
Ниже показаны лишь измененные фрагменты. Для начала редактируем поля создаваемого сертификата:
set_var EASYRSA_REQ_COUNTRY "RU"
set_var EASYRSA_REQ_PROVINCE "Krasnoyarsk krai"
set_var EASYRSA_REQ_CITY "Krasnoyarsk"
set_var EASYRSA_REQ_ORG "Daniil V. Savenkov Blog"
set_var EASYRSA_REQ_EMAIL "nobody@savenkoff.com"
set_var EASYRSA_REQ_OU "Private VPN"
А так-же параметры шифрования:
set_var EASYRSA_ALGO ec
set_var EASYRSA_DIGEST "sha512"
Создаём каталог pki и необходимые файлы для генерации сертификатов:
sudo ./easyrsa init-pki
Создаём ключ центра сертификации, для него понадобится придумать пароль и указать наименование субъекта (владельца) сертификата (можно указать hostname сервера):
sudo ./easyrsa build-ca
Создаём ключи Диффи-Хафмана, которые используются при обмене ключами между клиентом и сервером:
sudo ./easyrsa gen-dh
Команда создаст файл /etc/openvpn/easy-rsa/pki/dh.pem. Если есть необходимость использовать TLS авторизацию, понадобится ключ Hash-based Message Authentication Code (HMAC). Он используется для предотвращения DoS атаки при использовании протокола UDP. Создаём:
sudo openvpn --genkey --secret /etc/openvpn/easy-rsa/pki/ta.key
Для отзыва уже подписанных сертификатов понадобится сертификат отзыва. Создаём:
sudo ./easyrsa gen-crl
Создание сертификатов сервера
sudo ./easyrsa build-server-full [server] nopass
, где [server] - это имя сервера (заменить на свой, квадратные скобки убрать), а опция nopass отключает использование пароля.
Копируем все полученные ключи надо в папку /etc/openvpn:
cp ./pki/ca.crt /etc/openvpn/ca.crt
cp ./pki/dh.pem /etc/openvpn/dh.pem
cp ./pki/crl.pem /etc/openvpn/crl.pem
cp ./pki/ta.key /etc/openvpn/ta.key
cp ./pki/issued/[server].crt /etc/openvpn/[server].crt
cp ./pki/private/[server].key /etc/openvpn/[server].key
не забываем про то, что [server] - это имя сервера (заменить на свой, квадратные скобки убрать).
Конфигурация сервера
По умолчанию, конфигурационных файлов OpenVPN нет. Их нужно создать самостоятельно в зависимости от того, что планируется настраивать, сервер или клиент. Нужный файл конфигурации OpenVPN можно найти по адресу /usr/share/doc/openvpn/examples/sample-config-files/. Создаём конфигурационный файл для сервера:
zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
Редактируем файл конфигурации сервера. Основные параметры port и proto - порт и протокол, по которым будет работать сервер:
port 1194
proto udp
Все созданные ключи нужно прописать в конфигурационном файле. Хоть и наши ключи хранятся по адресу /etc/openvpn, в самой папке с конфигурационным файлом, прописываем к ним полный путь (без указания пути может возникнуть ошибка Options error: --ca fails with 'ca.crt': No such file or directory (errno=2)):
ca ca /etc/openvpn/ca.crt
cert /etc/openvpn/[server].crt
key /etc/openvpn/[server].key # This file should be kept secret
# Немного ниже меняем имя для сертификата Диффи-Хафмана
dh /etc/openvpn/dh.pem
tls-auth /etc/openvpn/ta.key 0 # This file is secret
Настраиваем диапазон адресов для виртуальной сети, наш сервер будет доступен по первому из них - 10.8.0.1:
server 10.8.0.0 255.255.255.0
Редактируем DNS сервера для клиентов VPN, раздаваемые по DHCP. Ниже приведена настройка для использования DNS Google и Cloudflare:
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 1.1.1.1"
Если есть необходимость пробрасывать весь трафик через VPN, необходимо раскомментировать строку:
push "redirect-gateway def1 bypass-dhcp"
Раскомментируем запись логов в отдельные файлы (по-умолчанию лог пишется в syslog):
log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log
Основная конфигурация завершена, сохраняем.
Пробуем вручную запустить OpenVPN с указанием адреса конфигурационного файла, если ничего не произошло (визуально), то читаем логи.
sudo openvpn /etc/openvpn/server.conf
При успешном запуске мы консоль как-бы зависнет, без визуальных оповещений, остановить текущий процесс можно с помощью комбинации клавиш Ctrl + C. Проверяем логи и убеждаемся, что ошибок запуска нет, увидев заветное Initialization Sequence Completed. Теперь можно запустить сервер демоном:
sudo systemctl start openvpn@server
и сразу добавляем его в автозагрузку:
sudo systemctl enable openvpn@server
Настройка форвардинга пакетов
Для включения проброса пакетов можно отредактировать файл /etc/sysctl.conf, раскомментировав строку:
net.ipv4.ip_forward=1
, либо с помощью команды:
sysctl -w net.ipv4.ip_forward=1
Настройка брандмауэра
Теперь надо разрешить прохождение пакетов в брандмауэре. Будем использовать iptables. Узнаем сетевой интерфейс, который используется для доступа к внешней сети с помощью команды:
ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 111.222.333.113/24 fe80::c8Xx:ff:feXx:13Xx/64
tun0 UNKNOWN 10.8.0.1 peer 10.8.0.2/32 fe80::83Xx:d9Xx:14Xx:e9Xx/64
В данном случае сетевым интерфейсом является eth0, интерфейсом OpenVPN - tun0. На основе этих данных можно сформировать правила для iptables и прописать их:
sudo iptables -I FORWARD -i tun0 -o eth0 -j ACCEPT
sudo iptables -I FORWARD -i eth0 -o tun0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Сохраняем правила, чтобы они сработали после перезагрузки сервера:
sudo iptables-save > /etc/iptables/rules.v4
Создание сертификата клиента
Создание сертификатов будет происходить на сервере. Переходим в директорию /etc/openvpn/easy-rsa/ и выполним команду:
cd /etc/openvpn/easy-rsa/
sudo ./easyrsa build-client-full [client1] nopass
, где [client1] - уникальное имя клиента OpenVPN (квадратные скобки убрать), а опция nopass отключает использование пароля. При выполнении команды понадобится ввести пароль, указанный ранее при формировании CA-сертификата.
Конфигурация клиента
Создаём папку /etc/openvpn/clients, куда будем складывать все ключи и конфигурационные файлы клиентов (под каждого клиента удобнее будет создать отдельную папку):
sudo mkdir /etc/openvpn/clients
sudo mkdir /etc/openvpn/clients/[client1]
Переносим ранее созданные ключи клиента в его директорию с переименованием в client.cer и client.key соответственно:
sudo cp /etc/openvpn/easy-rsa/pki/issued/[client1].crt /etc/openvpn/clients/[client1]/client.crt
sudo cp /etc/openvpn/easy-rsa/pki/private/[client1].key /etc/openvpn/clients/[client1]/client.key
Создаём конфигурационный файл клиента, его тоже можно скопировать из директории с примерами и открываем его на редактирование:
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/clients/client.conf
sudo nano /etc/openvpn/clients/client.conf
Основной параметр remote - сервер и порт, по которым будет присоединяться клиент (можно использовать ID или FQDN):
remote 111.222.333.113 1194
Так как мы будем для клиента собирать ovpn файл конфигурации, необходимо заккоментировать строки конфигурации, указывающие на файлы сертификатов, иначе, даже если их содержимое включить в файл, конфигурации будут требоваться файлы сертификатов, в ней указанные.
;ca ca.crt
;cert client.crt
;key client.key
;tls-auth ta.key 1
Создаём ovpn файл конфигурации для отправки клиенту. На Stack Exchange был найден скрипт для создания конфигурации в формате ovpn, отредактирован под текущее окружение. Скопируйте код ниже, сохраните в файл под именем MakeOvpnConfig.sh, загрузите файл в директорию /etc/openvpn/clients/ и выдайте права на выполнение скрипта.
#!/bin/bash
# Default Variable Declarations
DEFAULT="client.conf"
FILEEXT=".ovpn"
CRT="client.crt"
KEY="client.key"
CA="ca.crt"
TA="ta.key"
kRootPath="/etc/openvpn/"
#Ask for a Client name
echo "Please enter an existing Client Name folder:"
read NAME
#1st Verify that client's Public Key Exists
if [ ! -f ./$NAME/$CRT ]; then
echo "[ERROR]: Client Public Key Certificate not found: ./$NAME/$CRT"
exit
fi
echo "Client's cert found: ./$NAME/$CRT"
#Then, verify that there is a private key for that client
if [ ! -f ./$NAME/$KEY ]; then
echo "[ERROR]: Client 3des Private Key not found: ./$NAME/$KEY"
exit
fi
echo "Client's Private Key found: ./$NAME/$KEY"
#Confirm the CA public key exists
if [ ! -f $kRootPath$CA ]; then
echo "[ERROR]: CA Public Key not found: $kRootPath$CA"
exit
fi
echo "CA public Key found: $kRootPath$CA"
#Confirm the tls-auth ta key file exists
if [ ! -f $kRootPath$TA ]; then
echo "[ERROR]: tls-auth Key not found: $kRootPath$TA"
exit
fi
echo "tls-auth Private Key found: $kRootPath$TA"
#Ready to make a new .opvn file - Start by populating with the
cat $DEFAULT > $NAME$FILEEXT
#Now, append the CA Public Cert
echo "<ca>" >> $NAME$FILEEXT
cat $kRootPath$CA | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</ca>" >> $NAME$FILEEXT
#Next append the client Public Cert
echo "<cert>" >> $NAME$FILEEXT
cat ./$NAME/$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</cert>" >> $NAME$FILEEXT
#Then, append the client Private Key
echo "<key>" >> $NAME$FILEEXT
cat ./$NAME/$KEY >> $NAME$FILEEXT
echo "</key>" >> $NAME$FILEEXT
#Finally, append the TA Private Key
echo "key-direction 1" >> $NAME$FILEEXT
echo "<tls-auth>" >> $NAME$FILEEXT
cat $kRootPath$TA >> $NAME$FILEEXT
echo "</tls-auth>" >> $NAME$FILEEXT
echo "Done! $NAME$FILEEXT Successfully Created."
#Script written by Eric Jodoin
#Update by Eric Maasdorp 2017-12-16
#Update by Daniil V. Savenkov 2024-02-13
При запуске скрипт попросит указать имя директории клиента, для которого создаётся ovpn файл, листинг запуска получается примерно следующий:
./MakeOvpnConfig.sh
Please enter an existing Client Name folder:
client1
Client's cert found: ./client1/client.crt
Client's Private Key found: ./client1/client.key
CA public Key found: /etc/openvpn/ca.crt
tls-auth Private Key found: /etc/openvpn/ta.key
Done! client1.ovpn Successfully Created.
Скачать полученный файл с сервера можно любым удобным способом, через FTP, или используя mobaXterm.
Проверка подключения на Windows
На клиенте устанавливается клиент OpenVPN соответствующей разрядности. В нашем случае была установлена версия openvpn-connect-3.4.4.3412 и предварительно получен файл клиента в формате ovpn. Открываем интерфейс клиента, переходим на вкладку UploadFile, выбираем полученную конфигурацию и загружаем её в клиента.
Можем нажать Connect и проверить соединение с сервером. При успешном соединении приложение покажет статус Connected:
Используемые материалы
Для создания заметки использованы материалы следующих статей: Настройка OpenVPN в Ubuntu 20.04, Как настроить OpenVPN Server на Ubuntu 20.04, Настройка OpenVPN сервера на Ubuntu 20.04, OpenVPN Client Export Package. Представленная конфигурация проверена и работоспособна на момент публикации заметки.