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

17.07.2020

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

Пусть у нас есть локальная сеть компании и локальная сеть филиала. Маршрутизатор gateway1 обеспечивает выход в интернет для компьютеров сети 192.168.150.0/24, а маршрутизатор gateway2 — для компьютеров сети 192.168.250.0/24. И нам надо как-то обеспечить связь между этими локальными сетями.

Настройка сети для gateway1

Сначала нужно посмотреть, как называются сетевые интерфейсы в системе:

$ ls /sys/class/net
enp0s3  enp0s8  lo

Теперь редактируем файл /etc/netplan/01-netcfg.yaml:

$ sudo nano /etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: no
      addresses: [111.111.111.111/24]
      gateway4: 111.111.111.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
    enp0s8:
      dhcp4: no
      addresses: [192.168.150.1/24]
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

Применяем настройки и смотрим сетевые интерфейсы:

$ sudo netplan apply # применить настройки из YAML-файла к работающей системе
$ sudo netplan generate # сохранить текущие настройки в файл конфигурации networkd
$ 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:71:2e:a5 brd ff:ff:ff:ff:ff:ff
    inet 111.111.111.111/24 brd 111.111.111.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::1612:c37b:b6f9:64ff/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:49:10:2a brd ff:ff:ff:ff:ff:ff
    inet 192.168.150.1/24 brd 192.168.150.255 scope global enp0s8
       valid_lft forever preferred_lft forever

Настройка сети для pc1 и pc2

Сначала для компьютера pc1. Смотрим, как называются сетевые интерфейсы в системе:

$ ls /sys/class/net
enp0s3  lo

Открываем на редактирование файл /etc/netplan/01-network-manager-all.yaml:

$ sudo nano /etc/netplan/01-network-manager-all.yaml
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    enp0s3:
      dhcp4: no
      addresses: [192.168.150.2/24]
      gateway4: 192.168.150.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

Применяем настройки и смотрим сетевые интерфейсы:

$ sudo netplan apply # применить настройки из YAML-файла к работающей системе
$ sudo netplan generate # сохранить текущие настройки в файл конфигурации NetworkManager
$ 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:83:c0:ad brd ff:ff:ff:ff:ff:ff
    inet 192.168.150.2/24 brd 192.168.150.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe83:c0ad/64 scope link 
       valid_lft forever preferred_lft forever

Для компьютера pc2 все будет аналогично, так что не буду описывать подробно:

$ 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:69:17:a1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.150.3/24 brd 192.168.150.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe69:17a1/64 scope link 
       valid_lft forever preferred_lft forever

Настройка сети для gateway2

Сначала нужно посмотреть, как называются сетевые интерфейсы в системе:

$ ls /sys/class/net
enp0s3  enp0s8  lo

Теперь редактируем файл /etc/netplan/01-netcfg.yaml:

$ sudo nano /etc/netplan/01-netcfg.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: no
      addresses: [222.222.222.222/24]
      gateway4: 222.222.222.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]
    enp0s8:
      dhcp4: no
      addresses: [192.168.250.1/24]
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

Применяем настройки и смотрим сетевые интерфейсы:

$ sudo netplan apply # применить настройки из YAML-файла к работающей системе
$ sudo netplan generate # сохранить текущие настройки в файл конфигурации networkd
$ 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:f0:55:58 brd ff:ff:ff:ff:ff:ff
    inet 222.222.222.222/24 brd 222.222.222.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fef0:5558/64 scope link 
       valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:93:00:47 brd ff:ff:ff:ff:ff:ff
    inet 192.168.250.1/24 brd 192.168.250.255 scope global noprefixroute enp0s8
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe93:47/64 scope link 
       valid_lft forever preferred_lft forever

Настройка сети для pc3 и pc4

Сначала для компьютера pc3. Смотрим, как называются сетевые интерфейсы в системе:

$ ls /sys/class/net
enp0s3  lo

Открываем на редактирование файл /etc/netplan/01-network-manager-all.yaml:

$ sudo nano /etc/netplan/01-network-manager-all.yaml
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    enp0s3:
      dhcp4: no
      addresses: [192.168.250.2/24]
      gateway4: 192.168.250.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

Применяем настройки и смотрим сетевые интерфейсы:

$ sudo netplan apply # применить настройки из YAML-файла к работающей системе
$ sudo netplan generate # сохранить текущие настройки в файл конфигурации NetworkManager
$ 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:59:1e:a8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.250.2/24 brd 192.168.250.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe59:1ea8/64 scope link 
       valid_lft forever preferred_lft forever

Для компьютера pc4 все будет аналогично, так что не буду описывать подробно:

$ 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:09:ce:9c brd ff:ff:ff:ff:ff:ff
    inet 192.168.250.3/24 brd 192.168.250.255 scope global noprefixroute enp0s3
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe09:ce9c/64 scope link 
       valid_lft forever preferred_lft forever

Настройка интернет-шлюза gateway1

Сервер gateway1 должен обеспечивать выход в интернет для всех компьютеров из локальной сети 192.168.150.0/24. По умолчанию транзитный трафик отключен, так что редактируем файл /etc/sysctl.conf:

$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Чтобы внесенные изменения вступили в силу, выполняем команду:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

После этого настраиваем netfilter с помощью утилиты iptables:

$ sudo iptables -P FORWARD DROP
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.150.0/24 -j ACCEPT # enp0s3 -> enp0s8
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.150.0/24 -j ACCEPT # enp0s8 -> enp0s3

И смотрим, что получилось:

$ sudo iptables -L -v --line-numbers
Chain INPUT (policy ACCEPT 4 packets, 366 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination
1        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere            192.168.150.0/24
2       34    2130   ACCEPT   all    --    enp0s8   enp0s3   192.168.150.0/24    anywhere

Chain OUTPUT (policy ACCEPT 1 packets, 32 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination 

Мы разрешили ходить транзитным пакетам для нашего диапазона ip-адресов, а всё остальное запретили. Теперь настроим SNAT (подмена адреса источника), что позволит всем компьютерам сети выходить в интернет, используя единственный ip-адрес 111.111.111.111.

$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Созданные нами правила пропадут при перезагрузке gateway1. Так что их нужно сохранить и восстанавливать при перезагрузке. В этом нам поможет пакет iptables-persistent:

$ sudo apt install iptables-persistent

При установке пакета будет предложено сохранить текущие правила iptables:

  • в файл /etc/iptables/rules.v4 для протокола IPv4
  • в файл /etc/iptables/rules.v6 для протокола IPv6

Теперь проверяем наличие интернета на компьютерах pc1 и pc2:

$ ping -c3 ya.ru
PING ya.ru (87.250.250.242) 56(84) bytes of data.
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=49 time=10.9 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=2 ttl=49 time=9.68 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=3 ttl=49 time=9.12 ms

--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 9.124/9.927/10.968/0.771 ms

Настройка интернет-шлюза gateway2

Сервер gateway2 должен обеспечивать выход в интернет для всех компьютеров из локальной сети 192.168.250.0/24.

$ sudo nano /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

Чтобы внесенные изменения вступили в силу, выполняем команду:

$ sudo sysctl -p
net.ipv4.ip_forward = 1

После этого настраиваем netfilter с помощью утилиты iptables:

$ sudo iptables -P FORWARD DROP
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.250.0/24 -j ACCEPT # enp0s3 -> enp0s8
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.250.0/24 -j ACCEPT # enp0s8 -> enp0s3

И смотрим, что получилось:

$ sudo iptables -L -v --line-numbers
Chain INPUT (policy ACCEPT 136 packets, 29789 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination
1        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere            192.168.250.0/24
2        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.250.0/24    anywhere

Chain OUTPUT (policy ACCEPT 29 packets, 2353 bytes)
num   pkts   bytes   target   prot   opt   in       out      source              destination

Теперь настроим SNAT, что позволит всем компьютерам сети выходить в интернет, используя единственный ip-адрес 222.222.222.222.

$ sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE

Созданные нами правила пропадут при перезагрузке gateway2. Так что их нужно сохранить и восстанавливать при перезагрузке.

$ sudo apt install iptables-persistent

Теперь проверяем наличие интернета на компьютерах pc3 и pc4:

$ ping -c3 ya.ru
PING ya.ru (87.250.250.242) 56(84) bytes of data.
64 bytes from ya.ru (87.250.250.242): icmp_seq=1 ttl=53 time=7.96 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=2 ttl=53 time=7.83 ms
64 bytes from ya.ru (87.250.250.242): icmp_seq=3 ttl=53 time=8.07 ms

--- ya.ru ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 7.837/7.959/8.073/0.120 ms

Настройка OpenVPN-сервера

Маршрутизаторы настроили, компьютеры двух сетей могут выходить в интернет. Теперь приступим к установке и настройке OpenVPN-сервера. Сначала на маршрутизаторе gateway1 (который будет VPN-сервером) устанавливаем пакет openvpn:

$ sudo apt install openvpn

1. Создание центра сертификации

Центр сертификации будет на gateway1, хотя это и неправильно (ЦС должен быть на отдельном сервере):

$ cd ~
$ mkdir easy-rsa
$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.7/EasyRSA-3.0.7.tgz
$ tar xvf EasyRSA-3.0.7.tgz
$ cp -r EasyRSA-3.0.7/* easy-rsa/

Создаем копию файла vars.example — это пример конфигурации. Ничего в нем изменять не будем, в этом случае EASYRSA_DN имеет значение по умолчанию cn_only (Common Name Only), требующий ввода только универсального имени (подробности здесь).

$ cd ~/easy-rsa/
$ cp vars.example vars

Запускаем скрипт easyrsa с опцией init-pki для инициализации инфраструктуры:

$ ./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /home/evgeniy/easy-rsa/pki

Создаем корневой сертификат удостоверяющего центра:

$ ./easyrsa build-ca nopass
..........
Common Name (eg: your user, host, or server name) [Easy-RSA CA]: Some Company Auth Center
..........
Your new CA certificate file for publishing is at:
/home/evgeniy/easy-rsa/pki/ca.crt

Корневой сертификат — это файл pki/ca.crt, а приватный ключ — это файл pki/private/ca.key.

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

Создаем закрытый ключ и запрос на подпись сертификата для VPN-сервера:

$ ./easyrsa gen-req vpn-server-center-office nopass
..........
Common Name (eg: your user, host, or server name) [vpn-server-center-office]: Enter

Keypair and certificate request completed. Your files are:
req: /home/evgeniy/easy-rsa/pki/reqs/vpn-server-center-office.req
key: /home/evgeniy/easy-rsa/pki/private/vpn-server-center-office.key

Подписываем сертификат VPN-сервера:

$ ./easyrsa sign-req server vpn-server-center-office
..........
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
..........
Certificate created at: /home/evgeniy/easy-rsa/pki/issued/vpn-server-center-office.crt

Теперь создаем ключ Диффи-Хеллмана:

$ ./easyrsa gen-dh
..........
DH parameters of size 2048 created at /home/evgeniy/easy-rsa/pki/dh.pem

Это может занять несколько минут. Наконец, создаем ключ TLS:

$ openvpn --genkey --secret ta.key

Копируем ключи и сертификаты в директорию /etc/openvpn/keys/:

$ sudo mkdir /etc/openvpn/keys/ # создаем директорию для ключей и сертификатов
$ sudo cp /home/evgeniy/easy-rsa/pki/ca.crt /etc/openvpn/keys/ # корневой сертификат
$ sudo cp /home/evgeniy/easy-rsa/pki/private/vpn-server-center-office.key /etc/openvpn/keys/ # закрытый ключ сервера
$ sudo cp /home/evgeniy/easy-rsa/pki/issued/vpn-server-center-office.crt /etc/openvpn/keys/ # открытый ключ сервера
$ sudo cp /home/evgeniy/easy-rsa/pki/dh.pem /etc/openvpn/keys/ # ключ Диффи-Хеллмана
$ sudo cp /home/evgeniy/easy-rsa/ta.key /etc/openvpn/keys/ # ключ Transport Layer Security

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

Как его создавать, мы уже знаем, так что без подробностей:

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

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

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

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

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

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

# может быть подключен только один клиент
max-clients 1

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

# файл для хранения ip-адресов клиентов
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# читать файлы конфигураций клиентов в этой директории
client-config-dir /etc/openvpn/ccd

# клиент может подключиться, если существует файл конфигурации для него
# в директории client-config-dir, пусть даже этот файл будет пустым
ccd-exclusive

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

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

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

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

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

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

# уровень детализации лога от 0 до 11; если 0 — тогда только фатальные ошибки;
# при настройке установить значение 4-11, при эксплуатации — 0 или 1
verb 3

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

Мы указываем в файле конфигурации, что может быть подключен только один клиент. Кроме того, с помощью директивы client-config-dir указываем серверу использовать файл конфигурации vpn-client-branch-office. Директива ccd-exclusive говорит о том, что файл vpn-client-branch-office должен обязательно существовать.

Файл конфигурации в директории client-config-dir считывается сервером в момент подключения клиента, когда сервер уже переключился в nobody и nogroup. Поэтому важно правильно выставить права на этот файл конфигурации, чтобы nobody и nogroup могли прочитать его.

$ sudo mkdir /etc/openvpn/ccd/
$ sudo touch /etc/openvpn/ccd/vpn-client-branch-office
$ sudo chmod o+r /etc/openvpn/ccd/vpn-client-branch-office

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

$ sudo systemctl start openvpn-server@config.service

Добавим запуск сервера в автозагрузку:

$ sudo systemctl enable openvpn-server@config.service

Настройка OpenVPN-клиента

Сначала на маршрутизаторе gateway2 (который будет VPN-клиентом) устанавливаем пакет openvpn:

$ sudo apt install openvpn

Создаем в центре сертификации (который у нас на gateway1) закрытый ключ и запрос на подпись сертификата для VPN-клиента:

$ ./easyrsa gen-req vpn-client-branch-office nopass
..........
Common Name (eg: your user, host, or server name) [vpn-client-branch-office]: Enter

Keypair and certificate request completed. Your files are:
req: /home/evgeniy/easy-rsa/pki/reqs/vpn-client-branch-office.req
key: /home/evgeniy/easy-rsa/pki/private/vpn-client-branch-office.key
Обратите внимание, что в качестве Common Name мы используем предложенное значение vpn-client-branch-office. Для клиента лучше использовать именно такие имена, потому что может потребоваться использовать директиву файла конфигурации client-config-dir. В этом случае Common Name будет использовано в качестве имени файла — а на имена файлов налагаются некоторые ограничения.

Подписываем сертификат VPN-клиента:

$ ./easyrsa sign-req client vpn-client-branch-office
..........
Type the word 'yes' to continue, or any other input to abort.
  Confirm request details: yes
..........
Certificate created at: /home/evgeniy/easy-rsa/pki/issued/vpn-client-branch-office.crt

Переходим на gateway2 и копируем с gateway1 следующие файлы:

$ sudo mkdir /etc/openvpn/keys/ # создаем директорию для ключей и сертификатов
$ sudo scp evgeniy@111.111.111.111:/home/evgeniy/easy-rsa/pki/ca.crt /etc/openvpn/keys/
$ sudo scp evgeniy@111.111.111.111:/home/evgeniy/easy-rsa/pki/private/vpn-client-branch-office.key /etc/openvpn/keys/
$ sudo scp evgeniy@111.111.111.111:/home/evgeniy/easy-rsa/pki/issued/vpn-client-branch-office.crt /etc/openvpn/keys/
$ sudo scp evgeniy@111.111.111.111:/home/evgeniy/easy-rsa/ta.key /etc/openvpn/keys/

Создаем файл конфигурации клиента:

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

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

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

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

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

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

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

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

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

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

# уровень детализации лога от 0 до 11; если 0 — тогда только фатальные ошибки;
# при настройке установить значение 4-11, при эксплуатации — 0 или 1
verb 3

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

$ sudo systemctl start openvpn-client@config.service

Добавим запуск клиента в автозагрузку:

$ sudo systemctl enable openvpn-client@config.service

Проверяем, как все работает

С маршрутизатора gateway1 пингуем маршрутизатор gateway2:

$ ping -c3 10.8.0.2
PING 10.8.0.2 (10.8.0.2) 56(84) bytes of data.
64 bytes from 10.8.0.2: icmp_seq=1 ttl=64 time=6.61 ms
64 bytes from 10.8.0.2: icmp_seq=2 ttl=64 time=7.37 ms
64 bytes from 10.8.0.2: icmp_seq=3 ttl=64 time=7.31 ms

--- 10.8.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 6.619/7.102/7.376/0.342 ms

С маршрутизатора gateway2 пингуем маршрутизатор gateway1:

$ 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=7.11 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=7.96 ms
64 bytes from 10.8.0.1: icmp_seq=3 ttl=64 time=7.88 ms

--- 10.8.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 7.110/7.654/7.969/0.399 ms

Связь между двумя сетями

Для этого изменим правила netfilter на маршрутизаторах gateway1 и gateway2. И отредактируем файл конфигурации VPN-сервера + файл конфигурации клиента в директории /etc/openvpn/ccd.

1. Правила netfilter для gateway2

Удалим правила, которые мы добавили ранее для таблицы filter и вместо них создадим новые, которые будут учитывать наличие еще одного сетевого интерфейса:

$ sudo iptables -D FORWARD 2
$ sudo iptables -D FORWARD 1
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.250.0/24 ! -d 192.168.150.0/24 -j ACCEPT # enp0s8 -> enp0s3
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.250.0/24 -j ACCEPT # enp0s3 -> enp0s8
$ sudo iptables -A FORWARD -i enp0s8 -o tun0 -s 192.168.250.0/24 -d 192.168.150.0/24 -j ACCEPT # enp0s8 -> tun0
$ sudo iptables -A FORWARD -i tun0 -o enp0s8 -s 192.168.150.0/24 -d 192.168.250.0/24 -j ACCEPT # tun0 -> enp0s8

Смотрим, что у нас получилось в итоге выполнения этих команд:

Chain INPUT (policy ACCEPT 207 packets, 21382 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination
1        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.250.0/24  !192.168.150.0/24
2        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere           192.168.250.0/24
3        0       0   ACCEPT   all    --    enp0s8   tun0     192.168.250.0/24   192.168.150.0/24
4        0       0   ACCEPT   all    --    tun0     enp0s8   192.168.150.0/24   192.168.250.0/24

Chain OUTPUT (policy ACCEPT 183 packets, 18656 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination 

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

$ sudo iptables-save > /etc/iptables/rules.v4

2. Правила netfilter для gateway1

Удалим правила, которые мы добавили ранее для таблицы filter и вместо них создадим новые, которые будут учитывать наличие еще одного сетевого интерфейса:

$ sudo iptables -D FORWARD 2
$ sudo iptables -D FORWARD 1
$ sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.150.0/24 ! -d 192.168.250.0/24 -j ACCEPT # enp0s8 -> enp0s3
$ sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -d 192.168.150.0/24 -j ACCEPT # enp0s3 -> enp0s8
$ sudo iptables -A FORWARD -i enp0s8 -o tun0 -s 192.168.150.0/24 -d 192.168.250.0/24 -j ACCEPT # enp0s8 -> tun0
$ sudo iptables -A FORWARD -i tun0 -o enp0s8 -s 192.168.250.0/24 -d 192.168.150.0/24 -j ACCEPT # tun0 -> enp0s8

Смотрим, что у нас получилось в итоге выполнения этих команд

$ sudo iptables -L -v --line-numbers 
Chain INPUT (policy ACCEPT 2071 packets, 6957K bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination
1        0       0   ACCEPT   all    --    enp0s8   enp0s3   192.168.150.0/24  !192.168.250.0/24
2        0       0   ACCEPT   all    --    enp0s3   enp0s8   anywhere           192.168.150.0/24
3        0       0   ACCEPT   all    --    enp0s8   tun0     192.168.150.0/24   192.168.250.0/24
4        0       0   ACCEPT   all    --    tun0     enp0s8   192.168.250.0/24   192.168.150.0/24

Chain OUTPUT (policy ACCEPT 1571 packets, 174K bytes)
num   pkts   bytes   target   prot   opt   in       out      source             destination

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

$ sudo iptables-save > /etc/iptables/rules.v4

3. Добавляем маршруты до сетей

Но этого мало, маршрутизатор gateway1 должен знать, куда оправлять пакеты, предназначенные для сети 192.168.250.0/24. А маршрутизатор gateway2 должен знать, куда оправлять пакеты, предназначенные для сети 192.168.150.0/24. Другими словами, надо добавить маршруты:

$ sudo ip route add 192.168.250.0/24 via 10.8.0.2 dev tun0 # добавить на gateway1
$ sudo ip route add 192.168.150.0/24 via 10.8.0.1 dev tun0 # добавить на gateway2

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

$ sudo nano /etc/openvpn/server/config.conf
# эта директива используется совместно с директивой route и задает шлюз
# по умолчанию для VPN-сети (которым должен быть VPN-сервер); директива
# route имеет вид: «route network/ip-addr [netmask] [gateway] [metric]»
# и может получать значение gateway из директивы route-gateway
route-gateway 10.8.0.1

# маршрут до сети за клиентом, чтобы сервер добавил себе этот маршрут и
# направлял в туннель все пакеты, которые предназначены для этой сети
route 192.168.250.0 255.255.255.0

# маршрут до сети за сервером, чтобы клиент добавил себе этот маршрут и
# направлял в туннель все пакеты, которые предназначены для этой сети
push "route 192.168.150.0 255.255.255.0"

Но этого мало, нужно еще отредактировать файл vpn-client-branch-office в директории /etc/openvpn/ccd/:

$ sudo nano /etc/openvpn/ccd/vpn-client-branch-office
iroute 192.168.250.0 255.255.255.0

Эта директива создает внутренний маршрут в VPN-сети, направляя пакеты, предназначенные сети 192.168.250.0/24, на внутренний адрес данного клиента. В таблице маршрутов ОС данный маршрут не отображается, но без него маршрутизация в VPN-сети правильно работать не будет.

Причина, по которой необходимы два маршрута, заключается в том, что директива route направляет пакет от ядра к OpenVPN. Оказавшись в OpenVPN, директива iroute направляет пакет к конкретному клиенту.

Проверяем, как все работает

С компьютера pc1 пингуем компьютер pc3:

$ ping -c3 192.168.250.2
PING 192.168.250.2 (192.168.250.2) 56(84) bytes of data.
64 bytes from 192.168.250.2: icmp_seq=1 ttl=62 time=7.23 ms
64 bytes from 192.168.250.2: icmp_seq=2 ttl=62 time=8.29 ms
64 bytes from 192.168.250.2: icmp_seq=3 ttl=62 time=8.01 ms

--- 192.168.250.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 7.237/7.846/8.291/0.457 ms

С компьютера pc3 пингуем компьютер pc1:

$ ping -c3 192.168.150.2
PING 192.168.150.2 (192.168.150.2) 56(84) bytes of data.
64 bytes from 192.168.150.2: icmp_seq=1 ttl=62 time=15.0 ms
64 bytes from 192.168.150.2: icmp_seq=2 ttl=62 time=8.09 ms
64 bytes from 192.168.150.2: icmp_seq=3 ttl=62 time=8.37 ms

--- 192.168.150.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 8.099/10.512/15.065/3.221 ms

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

Поиск: 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.