Установка OpenVPN на Ubuntu 18.04 LTS. Часть 2 из 12

01.07.2020

Теги: LinuxSSLUbuntuVPNКлиентКлючКонфигурацияНастройкаСерверУстановка

Файл конфигурации сервера

По умолчанию в директории /etc/openvpn/ конфигурационных файлов нет, но есть две директории для них — server и client. Файл конфигурации нужно создать самостоятельно и поместить в директорию server (для сервера) или client (для клиента). Образец файла конфигурации OpenVPN можно взять из документации:

$ cd /etc/openvpn/server/
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/server/config.conf.gz
$ sudo gunzip config.conf.gz

Приведем файл конфигурации к следующему виду:

$ sudo nano /etc/openvpn/server/config.conf
# порт, на котором работает сервер
port 1194
# работа по протоколу UDP (для TCP нужно указать tcp-server)
proto udp
# сетевой интерфейс TUN (другое возможное значение — TAP)
dev tun

# корневой сертификат
ca /etc/openvpn/keys/ca.crt
# сертификат сервера
cert /etc/openvpn/keys/vpn-server.crt
# приватный ключ сервера
key /etc/openvpn/keys/vpn-server.key

# добавляет дополнительную подпись HMAC ко всем пакетам handshake для
# проверки целостности; любой пакет, не имеющий правильной HMAC-подписи,
# будет отброшен без дальнейшей обработки; это для доп.безопасности
tls-auth /etc/openvpn/keys/ta.key
# для сервера направление ключа TLS — 0, для клиента — 1
key-direction 0

# ключ Диффи-Хеллмана
dh /etc/openvpn/keys/dh.pem

# использовать алгоритм AES-256-GCM шифрования пакетов канала данных;
# на данный момент это самый безопасный и быстрый алгоритм шифрования
cipher AES-256-GCM
# алгоритм хеширования — для проверки целостности передаваемых пакетов;
# добавляет дополнительную подпись HMAC ко всем пакетам канала данных и
# (если включено tls-auth) пакетов канала управления
auth SHA256

# три варианта: net30, p2p, subnet
topology subnet

# локальная сеть сервер-клиенты
server 10.8.0.0 255.255.255.0

# шлюз по умолчанию для VPN-сети (которым должен быть VPN-сервер)
route-gateway 10.8.0.1

# максимальное количество одновременно подключенных клиентов
max-clients 10

# новый механизм компрессии; директива будет автоматически отправлена на клиент
compress lz4-v2
push "compress lz4-v2"

# для старых версий клиентов (ниже 2.4) отключаем две директивы выше и включаем
# директиву ниже; также потребуется добавить в конфигурационные файлы клиентов
#comp-lzo

# пользователь и группа с минимальными правами — для большей безопасности
user nobody
group nogroup

# каждые 10 секунд отправлять ping-запрос на удаленный узел; если нет
# ответа 60*2=120 секунд — перезапускать туннель
keepalive 10 60

# не перечитывать файлы ключей при восстановлении после разрыва соединения
persist-key
# оставлять без изменения устройства tun или tap при перезапуске службы
persist-tun

# файл статуса, содержит текущие соединения; перезаписывается каждую минуту
status /var/log/openvpn/openvpn-status.log

# по умолчанию логи идут в syslog; использование одной из директив ниже
# предписывает вести отдельный лог; первая — перезаписывать файл лога,
# вторая — дополнять файл лога; можно использовать только одну директиву
#log         /var/log/openvpn/openvpn.log
#log-append  /var/log/openvpn/openvpn.log

# уровень детализации лога от 0 до 11; если 0 — тогда только фатальные ошибки;
# при настройке установить значение 3 или 4, при эксплуатации — 0 или 1; уровень
# 5 показывает 'RrWw' символы в консоли для каждого пакета, отправленного и
# принятого по tcp/udp (upper case) или tun/tap (lower case); уровни 6-11 — это
# отладочная информация, повышающая детализацию лога
verb 3

# предупреждать клиентов, что сервер перезапускается, чтобы клиенты могли
# автоматически переподключиться (только при работе по протоколу UDP)
explicit-exit-notify 1

Директива server является макрокомандой и имеет синтаксис:

server network netmask ['nopool']

Она будет преобразована по следующему алгортиму:

mode server
tls-server
push "topology [topology]"

if dev tun AND (topology == net30 OR topology == p2p):
  ifconfig 10.8.0.1 10.8.0.2
  if !nopool:
    ifconfig-pool 10.8.0.4 10.8.0.251
  route 10.8.0.0 255.255.255.0
  if client-to-client:
    push "route 10.8.0.0 255.255.255.0"
  else if topology == net30:
    push "route 10.8.0.1"

if dev tap OR (dev tun AND topology == subnet):
  ifconfig 10.8.0.1 255.255.255.0
  if !nopool:
    ifconfig-pool 10.8.0.2 10.8.0.253 255.255.255.0
  push "route-gateway 10.8.0.1"
  if route-gateway unset:
    route-gateway 10.8.0.2

Директива route-gateway используется совместно с директивой route и задает шлюз по умолчанию для VPN-сети. Если параметр gateway директивы route не задан — он будет получен из директивы route-gateway.

route network/ip-addr [netmask] [gateway] [metric]

Директива topology приобретает смысл совместно с dev tun и предусматривает три варианта: net30, p2p, subnet.

Универсальным решением для VPN-сервера является net30 — это значение по умолчанию. Сервер будет работать со всеми версиями Windows, Linux, Mikrotik. Недостатком топологии является избыточное расходование адресного пространства — четыре ip-адреса на каждого VPN-клиента. Топология net30 фактически «устарела» и сохраняется исключительно для поддержки старых Windows клиентов.

Значение subnet рекомендуется для VPN-сервера, клиентами которого являются Linux и Windows 8.2 и выше. Устройство tun настроено на использование ip-адреса и маски сети как «традиционная» широковещательная сеть. Сетевой и широковещательный ip-адреса не должны использоваться — хотя tun не имеет понятия о широковещании, клиенты Windows не смогут правильно использовать эти адреса. Все остальные ip-адреса в сети доступны для использования.

Значение p2p не может использоваться в системах Windows и не подходит, если сервер или любой клиент может быть Windows. В этой топологии все узлы настроены как настоящие двухточечные ссылки — каждый ip-адрес может использоваться, включая первый и последний. Другими словами, в сети 10.8.0.0/24 в топологии p2p можно использовать все 256 ip-адресов. Но Windows считает первый и последний ip-адреса сетевым и широковещательным адресами.

Директивы persist-key и persist-tun обеспечивают правильную работу после понижения прав, т.е. при использовании nobody и nogroup.

Директива keepalive является макрокомандой и будет преобразована в директивы ping и ping-restart

# отсылать ping на удаленный конец тунеля после 10 секунд,
# если по туннелю не передавался никакой трафик 
ping 10
# если за 120 секунд не было получено ни одного пакета с
# удаленной стороны, то перезапускать туннель
ping-restart 120

Кроме того, эта макрокоманда отправит две директивы на клиент (так что в файле конфигурации клиента они не нужны)

ping 10
# клиент перезапустит туннель раньше сервера
ping-restart 60

Все готово, можно запускать VPN-сервер (подробности здесь):

$ sudo systemctl start openvpn-server@config.service

Здесь config — это имя файла конфигурации в директории server, но без расширения .conf. Чтобы VPN-сервер запускался при загрузке системы:

$ sudo systemctl enable openvpn-server@config.service

Смотрим статус запущенной службы:

$ sudo systemctl status openvpn-server@config.service
● openvpn-server@config.service - OpenVPN service for config
   Loaded: loaded (/lib/systemd/system/openvpn-server@.service; indirect; vendor preset: enabled)
   Active: active (running) since Wed 2020-07-01 10:26:34 MSK; 21s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
 Main PID: 464 (openvpn)
   Status: "Initialization Sequence Completed"
    Tasks: 1 (limit: 1129)
   CGroup: /system.slice/system-openvpn\x2dserver.slice/openvpn-server@config.service
           └─464 /usr/sbin/openvpn --status /run/openvpn-server/status-config.log --status-version 2 --suppress-timestamps --config config.conf

июл 01 10:26:34 openvpn-server openvpn[464]: /sbin/ip addr add dev tun0 10.8.0.1/24 broadcast 10.8.0.255
июл 01 10:26:34 openvpn-server openvpn[464]: Could not determine IPv4/IPv6 protocol. Using AF_INET
июл 01 10:26:34 openvpn-server openvpn[464]: Socket Buffers: R=[212992->212992] S=[212992->212992]
июл 01 10:26:34 openvpn-server openvpn[464]: UDPv4 link local (bound): [AF_INET][undef]:1194
июл 01 10:26:34 openvpn-server openvpn[464]: UDPv4 link remote: [AF_UNSPEC]
июл 01 10:26:34 openvpn-server openvpn[464]: GID set to nogroup
июл 01 10:26:34 openvpn-server openvpn[464]: UID set to nobody
июл 01 10:26:34 openvpn-server openvpn[464]: MULTI: multi_init called, r=256 v=256
июл 01 10:26:34 openvpn-server openvpn[464]: IFCONFIG POOL: base=10.8.0.2 size=252, ipv6=0
июл 01 10:26:34 openvpn-server openvpn[464]: Initialization Sequence Completed

Смотрим наличие сетевого интерфейса tun0:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 4a:61:03:c8:18:60 brd ff:ff:ff:ff:ff:ff
    inet 123.123.123.123/24 brd 123.123.123.255 scope global dynamic ens3
       valid_lft 85949sec preferred_lft 85949sec
    inet6 fe80::4861:3ff:fec8:1860/64 scope link 
       valid_lft forever preferred_lft forever
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.1/24 brd 10.8.0.255 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::f72c:913c:8bba:69da/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever

Файл конфигурации клиента

Первым делом нужно установить пакет OpenVPN:

$ sudo apt install openvpn

Создаем директорию keys и копируем ключи:

$ cd /etc/openvpn/
$ sudo mkdir keys
$ cd /etc/openvpn/keys/
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/pki/ca.crt /etc/openvpn/keys/
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/pki/private/sergey-ivanov.key /etc/openvpn/keys/
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/pki/issued/sergey-ivanov.crt /etc/openvpn/keys/
$ sudo scp evgeniy@123.123.123.123:/home/evgeniy/easy-rsa/ta.key /etc/openvpn/keys/

Копируем образец файла конфигурации клиента:

$ cd /etc/openvpn/client/
$ sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client/config.conf

Приведем файл конфигурации к следующему виду:

$ sudo nano /etc/openvpn/client/config.conf
# это клиент, а не сервер
client
# работа по протоколу UDP (для TCP нужно указать tcp-client)
proto udp
# сетевой интерфейс TUN (другое возможное значение — TAP)
dev tun

# ip-адрес и порт сервера
remote 123.123.123.123 1194

# если не удалось получить ip-адрес сервера от DNS, то через указанное
# количество секунд попытаться снова; infinite — повторять бесконечно
resolv-retry infinite

# использовать динамический порт для подключения к серверу (клиенту не
# требуется привязка к определенному порту); актуально только для UDP
nobind

# корневой сертификат
ca /etc/openvpn/keys/ca.crt
# сертификат клиента
cert /etc/openvpn/keys/sergey-ivanov.crt
# приватный ключ клиента
key /etc/openvpn/keys/sergey-ivanov.key

# для защиты от атаки «человек посередине», когда авторизованный клиент
# пытается подключиться к другому клиенту, выдавая себя за сервер; при
# указании этой директивы проверяется, что сертификат именно серверный
remote-cert-tls server

# добавляет дополнительную подпись HMAC ко всем пакетам handshake для
# проверки целостности; любой пакет, не имеющий правильной HMAC-подписи,
# будет отброшен без дальнейшей обработки; это для доп.безопасности
tls-auth /etc/openvpn/keys/ta.key
# для сервера направление ключа TLS — 0, для клиента — 1
key-direction 1

# использовать алгоритм AES-256-GCM шифрования пакетов канала данных;
# на данный момент это самый безопасный и быстрый алгоритм шифрования
cipher AES-256-GCM
# алгоритм хеширования — для проверки целостности передаваемых пакетов
# канала данных и (если включено tls-auth) пакетов канала управления
auth SHA256

# пользователь и группа с минимальными правами — для большей безопасности
user nobody
group nogroup

# по умолчанию логи идут в syslog; использование одной из директив ниже
# предписывает вести отдельный лог; первая — перезаписывать файл лога,
# вторая — дополнять файл лога; можно использовать только одну директиву
#log         /var/log/openvpn/openvpn.log
#log-append  /var/log/openvpn/openvpn.log

# уровень детализации лога от 0 до 11; если 0 — тогда только фатальные ошибки;
# при настройке установить значение 3 или 4, при эксплуатации — 0 или 1; уровень
# 5 показывает 'RrWw' символы в консоли для каждого пакета, отправленного и
# принятого по tcp/udp (upper case) или tun/tap (lower case); уровни 6-11 — это
# отладочная информация, повышающая детализацию лога
verb 3

Все готово, можно запускать VPN-клиент (подробности здесь):

$ sudo systemctl start openvpn-client@config.service

Здесь config — это имя файла конфигурации в директории client, но без расширения .conf. Чтобы VPN-клиент запускался при загрузке системы:

$ sudo systemctl enable openvpn-client@config.service

Смотрим статус запущенной службы:

$ sudo systemctl status openvpn-client@config.service
● openvpn-client@config.service - OpenVPN tunnel for config
   Loaded: loaded (/lib/systemd/system/openvpn-client@.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2020-07-01 10:58:43 MSK; 8s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
 Main PID: 4523 (openvpn)
   Status: "Initialization Sequence Completed"
    Tasks: 1 (limit: 4666)
   CGroup: /system.slice/system-openvpn\x2dclient.slice/openvpn-client@config.service
           └─4523 /usr/sbin/openvpn --suppress-timestamps --nobind --config config.conf

июл 01 10:58:44 openvpn-client openvpn[4523]: Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
июл 01 10:58:44 openvpn-client openvpn[4523]: TUN/TAP device tun0 opened
июл 01 10:58:44 openvpn-client openvpn[4523]: TUN/TAP TX queue length set to 100
июл 01 10:58:44 openvpn-client openvpn[4523]: do_ifconfig, tt->did_ifconfig_ipv6_setup=0
июл 01 10:58:44 openvpn-client openvpn[4523]: /sbin/ip link set dev tun0 up mtu 1500
июл 01 10:58:44 openvpn-client openvpn[4523]: /sbin/ip addr add dev tun0 10.8.0.2/24 broadcast 10.8.0.255
июл 01 10:58:44 openvpn-client openvpn[4523]: GID set to nogroup
июл 01 10:58:44 openvpn-client openvpn[4523]: UID set to nobody
июл 01 10:58:44 openvpn-client openvpn[4523]: WARNING: this configuration may cache passwords in memory -- use the auth-nocache 
июл 01 10:58:44 openvpn-client openvpn[4523]: Initialization Sequence Completed

Смотрим наличие сетевого интерфейса tun0:

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:90:71:b7 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp0s3
       valid_lft 82961sec preferred_lft 82961sec
    inet6 fe80::5190:12a3:de0a:a1d4/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.2/24 brd 10.8.0.255 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::891b:c05f:4a26:5c3a/64 scope link stable-privacy 
       valid_lft forever preferred_lft forever

Пингуем сервер по адресу 10.8.0.1:

$ ping -c3 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=13.3 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=14.5 ms
64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=14.1 ms

--- 10.8.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 13.338/14.025/14.592/0.536 ms

Дополнительные настройки сервера

1 Если нужно использовать VPN-туннель для маршрутизации всего трафика клиентов, добавляем в файл конфигурации еще три строки.

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Теперь клиенты будут использовать туннель VPN в качестве шлюза по умолчанию и DNS-сервера 208.67.222.222 и 208.67.220.220. В этом случае надо внести изменения и в файл конфигурации клиента. Какие изменения — зависит от того, используется systemd-resolved или нет.

# для обновления DNS на клиенте при подключении и отключении
# (если на клиенте не используется служба systemd-resolved)
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
# для обновления DNS на клиенте при подключении и отключении
# (если на клиенте используется служба systemd-resolved)
script-security 2
up /etc/openvpn/update-systemd-resolved
up-restart
down /etc/openvpn/update-systemd-resolved
down-pre
dhcp-option DOMAIN-ROUTE .

При подключении к серверу сетевые настройки клиента будут изменяться, а при отключении от сервера — настройки будут возвращаться в нормальное состояние, как было до подключения. Скрипт update-resolv-conf доступен сразу после установки пакета openvpn, чтобы получить скрипт update-systemd-resolved — надо установить пакет openvpn-systemd-resolved.

2 По умолчанию сервер OpenVPN использует порт 1194 и протокол UDP — но это всегда можно изменить.

# номер порта сервера
port 443
# работа по протоколу TCP
proto tcp-server

При переключении протокола на TCP, нужно изменить значение директивы explicit-exit-notify с 1 на 0, так как эта директива используется только для UDP. Иначе, при использовании TCP, эта директива вызовет ошибки при запуске службы.

explicit-exit-notify 0

Кроме того, при изменении протокола и порта сервера в файле конфигурации сервера, надо внести изменения в файл конфигурации клиента — указать тот же порт и протокол.

# работа по протоколу TCP
proto tcp-client
# ip-адрес и порт сервера
remote 123.123.123.123 443

3 По умолчанию клиенты сети VPN могут «общаться» только с сервером OpenVPN. Для того, чтобы клиенты могли взаимодействовать друг с другом через сеть VPN необходимо в конфигурационном файле раскомментировать соответствующую директиву:

client-to-client

4 Сервер динамически выдает клиентам свободные ip-адреса из заданного диапазона. Наличие директивы ifconfig-pool-persist указывает, что перед тем как выдать клиенту свободный адрес из пула, сервер должен свериться с файлом ipp.txt, в котором прописывается привязка Common Name сертификата к ip-адресу.

ifconfig-pool-persist /var/log/openvpn/ipp.txt

5 Директива client-config-dir предписывает читать файлы конфигураций клиентов в указанной директории. Имена файлов конфигурации в этой директории совпадают с Common Name сертификатов клиентов. Директивы из каждого файла конфигурации применяются только для конкретного клиента.

client-config-dir /etc/openvpn/ccd

6 Директива ccd-exclusive — VPN-клиент, имеющий сертификат с Common Name «sergey-ivanov», может подключиться к VPN-серверу, только если существует файл с именем sergey-ivanov в директории client-config-dir. Этот файл может быть даже пустым — но он должен существовать.

ccd-exclusive

7 Директива duplicate-cn разрешает одновременное подключение нескольких клиентов с одинаковым Common Name. В отсутствие этой директивы сервер отключит экземпляр клиента при подключении нового клиента с таким же Common Name.

Чтобы избежать ошибки Could not determine IPv4/IPv6 protocol. Using AF_INET при запуске VPN-сервера, нужно явно указать версию протокола:

proto udp4

Дополнительно

Поиск: Linux • SSL • Ubuntu • VPN • Клиент • Ключ • Конфигурация • Настройка • Сервер • Сертификат • EasyRSA • Установка • Локальная сеть

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.