Задача: Поднимаю OpenVPNсервис, создаю ключ для клиента, импортирую ключ клиента на другую систему и получаю связь между хостом в интернет и другим хостом. Цель всего это — это опираясь на данную заметку связать домашнюю сеть и хост в интернете (как почтовый домен для почтового сервера в локальной сети). Дальше на Хосте делаю проброс портов до локальной системы, на которой поднимаю iRedMail — в итоге получаю полнофункциональный почтовый сервис для доменного имени ekzorchik.com

И отказываюсь от использования почтового сервера Yandex в пользу своего собственного.

Сейчас вся задумка разбита на первый этап, разбор как поднять OpenVPN сервер на Ubuntu 20.04 Server от и до, дабы после перенести работающие шаги на боевое.

Шаг №1: Обновляем систему по пакетам в рамках Ubuntu 20.04 Server:

ekzorchik@srv-vpn:~$ sudo rm -Rf /var/lib/apt/lists
ekzorchik@srv-vpn:~$ nano /etc/update-manager/release-upgrades
[DEFAULT]
Prompt=never
ekzorchik@srv-vpn:~$ sudo apt-get update && sudo apt-get upgrade -y
ekzorchik@srv-vpn:~$ uname -a && lsb_release -a
Linux srv-vpn 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04 LTS
Release:	20.04
Codename:	focal
ekzorchik@srv-vpn:~$

Шаг №2: Чтобы управлять доступом к сети OpenVPN и самому серверу через надстройку над iptables - firewalld следуют сперва его установить, а уже потом развернуть OpenVPN сервер:

sudo ufw disable
sudo apt-get install -y firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld
sudo firewall-cmd --state
ip r | awk '{print $5}' | head -n1
ens18
sudo firewall-cmd --zone public --change-interface=ens18 --permanent
sudo firewall-cmd --reload
ekzorchik@srv-vpn:~$ sudo firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens18
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

Шаг №3: Скачиваем инсталляционный скрипт OpenVPN: openvpn-ubuntu-install

ekzorchik@srv-vpn:~$ wget https://git.io/vpn -O openvpn-ubuntu-install.sh

Шаг №4: Присваиваем скрипту атрибуты исполнения:

ekzorchik@srv-vpn:~$ chmod -v +x openvpn-ubuntu-install.sh 
mode of 'openvpn-ubuntu-install.sh' changed from 0664 (rw-rw-r--) to 0775 (rwxrwxr-x)
ekzorchik@srv-vpn:~$

Шаг №5: Изменяю в установочном скрипте сеть OpenVPN с дефолтной 10.8.0.0/24 на 10.9.0.0/24:

Search (to replace) [10.8.0.0]: 10.8.0.0

Replace with: 10.9.0.0

Replace this instance? A (All)

Replaced 21 occurrences

ekzorchik@srv-vpn:~$ nano openvpn-ubuntu-install.sh

Шаг №6: Запускаем скрипт и отвечая на вопросы мастера установки:

ekzorchik@srv-vpn:~$ sudo ./openvpn-ubuntu-install.sh
Welcome to this OpenVPN road warrior installer!
Which protocol should OpenVPN use?
   1) UDP (recommended)
   2) TCP
Protocol [1]: нажимаю клавишу 1
What port should OpenVPN listen to?
Port [1194]: меняю порт на 1195 и нажимаю клавишу Enter
Select a DNS server for the clients:
   1) Current system resolvers
   2) Google
   3) 1.1.1.1
   4) OpenDNS
   5) Quad9
   6) AdGuard
DNS server [1]: нажимаю клавишу 2
Enter a name for the first client:
Name [client]: указываю имя первого клиента client1
OpenVPN installation is ready to begin.
Press any key to continue... нажимаю клавишу Enter
Hit:1 http://ru.archive.ubuntu.com/ubuntu focal InRelease
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/server/easy-rsa/pki
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating RSA private key, 2048 bit long modulus (2 primes)
.......+++++
.........+++++
e is 65537 (0x010001)
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating a RSA private key
.......+++++
......+++++
writing new private key to '/etc/openvpn/server/easy-rsa/pki/easy-rsa-1916.n2Wyjp/tmp.1Jky7j'
-----
Using configuration from /etc/openvpn/server/easy-rsa/pki/easy-rsa-1916.n2Wyjp/tmp.wvgBWr
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Jan 21 09:21:18 2032 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated

Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating a RSA private key
...........................................................+++++
................+++++
writing new private key to '/etc/openvpn/server/easy-rsa/pki/easy-rsa-1991.j1MakZ/tmp.matBsT'
-----
Using configuration from /etc/openvpn/server/easy-rsa/pki/easy-rsa-1991.j1MakZ/tmp.X1mOwn
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client1'
Certificate is to be certified until Jan 21 09:21:18 2032 GMT (3650 days)
Write out database with 1 new entries
Data Base Updated
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Using configuration from /etc/openvpn/server/easy-rsa/pki/easy-rsa-2047.agXe9f/tmp.9HKIss

An updated CRL has been created.
CRL file: /etc/openvpn/server/easy-rsa/pki/crl.pem
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-iptables.service → /etc/systemd/system/openvpn-iptables.service.
Created symlink /etc/systemd/system/multi-user.target.wants/openvpn-server@server.service → /lib/systemd/system/openvpn-server@.service.
Finished!
The client configuration is available in: /root/client1.ovpn
New clients can be added by running this script again.
ekzorchik@srv-vpn:~$

ekzorchik@srv-vpn:~$ sudo ss -tulpn | grep -i openvpn
udp    UNCONN  0       0              172.33.33.134:1195          0.0.0.0:*      users:(("openvpn",pid=2942,fd=6))                                              
ekzorchik@srv-vpn:~$

Шаг №7: Произвожу некоторые настройки с системой для работы с OpenVPN:

ekzorchik@srv-vpn:~$ sudo nano /etc/sysctl.d/1000-force-openvpn-bind.conf
net.ipv4.ip_nonlocal_bind=1
ekzorchik@srv-vpn:~$ sudo sysctl -p /etc/sysctl.d/1000-force-openvpn-bind.conf
ekzorchik@srv-vpn:~$ sudo nano /etc/sysctl.d/99-openvpn-forward.conf 
net.ipv4.ip_forward=1
ekzorchik@srv-vpn:~$ sudo systemctl -p /etc/sysctl.d/99-openvpn-forward.conf 
ekzorchik@srv-vpn:~$

Шаг №8: Проверяю, что сервис OpenVPN работает:

ekzorchik@srv-vpn:~$ sudo systemctl status openvpn-server@server.service 
● openvpn-server@server.service - OpenVPN service for server
     Loaded: loaded (/lib/systemd/system/openvpn-server@.service; enabled; vend>
     Active: active (running) since Mon 2022-01-31 22:18:06 MSK; 3min 37s ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 2942 (openvpn)
     Status: "Initialization Sequence Completed"
      Tasks: 1 (limit: 4612)
     Memory: 1.1M
     CGroup: /system.slice/system-openvpn\x2dserver.slice/openvpn-server@server>
             └─2942 /usr/sbin/openvpn --status /run/openvpn-server/status-serve>

Jan 31 22:18:06 srv-vpn openvpn[2942]: Could not determine IPv4/IPv6 protocol. >
Jan 31 22:18:06 srv-vpn openvpn[2942]: Socket Buffers: R=[212992->212992] S=[21>
Jan 31 22:18:06 srv-vpn openvpn[2942]: UDPv4 link local (bound): [AF_INET]172.3>
Jan 31 22:18:06 srv-vpn openvpn[2942]: UDPv4 link remote: [AF_UNSPEC]
Jan 31 22:18:06 srv-vpn openvpn[2942]: GID set to nogroup
Jan 31 22:18:06 srv-vpn openvpn[2942]: UID set to nobody
Jan 31 22:18:06 srv-vpn openvpn[2942]: MULTI: multi_init called, r=256 v=256
Jan 31 22:18:06 srv-vpn openvpn[2942]: IFCONFIG POOL: base=10.9.0.2 size=252, i>
Jan 31 22:18:06 srv-vpn openvpn[2942]: IFCONFIG POOL LIST
Jan 31 22:18:06 srv-vpn openvpn[2942]: Initialization Sequence Completed
ekzorchik@srv-vpn:~$

Шаг №9: Т.к. клиента я уже создал, то копирую файл ovpn на другую систему (172.33.33.126) и проверяю, что запустив сервис OpenVPN-клиент с конфигурационным сервисом, VPN-туннель поднимется:

ekzorchik@srv-vpn:~$ sudo bash -c "cat /root/client1.ovpn"
client
dev tun
proto udp
remote 172.33.33.134 1195
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
ignore-unknown-option block-outside-dns
block-outside-dns
verb 3
<ca>
</ca>
<cert>
</cert>
<key>
</key>
<tls-crypt>
</tls-crypt>

и далее внутри него содержимое сертификатов ca, cert, key, tls. Можно конечно их вынести как отдельные файлы и указать путь до них в конфигурационном файле клиента.

ekzorchik@srv-vpn:~$ sudo visudo
ekzorchik ALL=(ALL) NOPASSWD:ALL
ekzorchik@srv-vpn:~$ sudo scp /root/client1.ovpn ekzorchik@172.33.33.126:/home/ekzorchik/client1.ovpn
The authenticity of host '172.33.33.126 (172.33.33.126)' can't be established.
ECDSA key fingerprint is SHA256:yeLsDB1BFORfSGNUwc/yVC+hzN1U2cQXARkYwKlpdGY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.33.33.126' (ECDSA) to the list of known hosts.
ekzorchik@172.33.33.126's password: 
client1.ovpn                                  100% 4993     7.1MB/s   00:00    
ekzorchik@srv-vpn:~$ 
на клиентской системе:
ekzorchik@srv-bionic:~$ apt-cache show openvpn | grep Version | head -n1
Version: 2.4.4-2ubuntu1.6
ekzorchik@srv-bionic:~$
ekzorchik@srv-bionic:~$ sudo apt-get install openvpn -y
ekzorchik@srv-bionic:~$ sudo cp client1.ovpn /etc/openvpn/client.conf

Проверяю соединение с VPN:

ekzorchik@srv-bionic:~$ sudo openvpn --client --config /etc/openvpn/client.conf
Mon Jan 31 22:38:36 2022 Unrecognized option or missing or extra parameter(s) in /etc/openvpn/client.conf:13: block-outside-dns (2.4.4)
Mon Jan 31 22:38:36 2022 OpenVPN 2.4.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on Jul 19 2021
Mon Jan 31 22:38:36 2022 library versions: OpenSSL 1.1.1  11 Sep 2018, LZO 2.08
Mon Jan 31 22:38:36 2022 Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Mon Jan 31 22:38:36 2022 Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
Mon Jan 31 22:38:36 2022 Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Mon Jan 31 22:38:36 2022 Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
Mon Jan 31 22:38:36 2022 TCP/UDP: Preserving recently used remote address: [AF_INET]172.33.33.134:1195
Mon Jan 31 22:38:36 2022 Socket Buffers: R=[212992->212992] S=[212992->212992]
Mon Jan 31 22:38:36 2022 UDP link local: (not bound)
Mon Jan 31 22:38:36 2022 UDP link remote: [AF_INET]172.33.33.134:1195
Mon Jan 31 22:38:36 2022 TLS: Initial packet from [AF_INET]172.33.33.134:1195, sid=e04e9cb1 41355b63
Mon Jan 31 22:38:36 2022 VERIFY OK: depth=1, CN=ChangeMe
Mon Jan 31 22:38:36 2022 VERIFY KU OK
Mon Jan 31 22:38:36 2022 Validating certificate extended key usage
Mon Jan 31 22:38:36 2022 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
Mon Jan 31 22:38:36 2022 VERIFY EKU OK
Mon Jan 31 22:38:36 2022 VERIFY OK: depth=0, CN=server
Mon Jan 31 22:38:36 2022 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, 2048 bit RSA
Mon Jan 31 22:38:36 2022 [server] Peer Connection Initiated with [AF_INET]172.33.33.134:1195
Mon Jan 31 22:38:38 2022 SENT CONTROL [server]: 'PUSH_REQUEST' (status=1)
Mon Jan 31 22:38:38 2022 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 8.8.8.8,dhcp-option DNS 8.8.4.4,route-gateway 10.9.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.9.0.2 255.255.255.0,peer-id 0,cipher AES-256-GCM'
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: timers and/or timeouts modified
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: --ifconfig/up options modified
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: route options modified
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: route-related options modified
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: --ip-win32 and/or --dhcp-option options modified
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: peer-id set
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: adjusting link_mtu to 1624
Mon Jan 31 22:38:38 2022 OPTIONS IMPORT: data channel crypto options modified
Mon Jan 31 22:38:38 2022 Data Channel: using negotiated cipher 'AES-256-GCM'
Mon Jan 31 22:38:38 2022 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Mon Jan 31 22:38:38 2022 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key
Mon Jan 31 22:38:38 2022 ROUTE_GATEWAY 172.33.33.100/255.255.255.0 IFACE=ens18 HWADDR=96:32:31:05:39:07
Mon Jan 31 22:38:38 2022 TUN/TAP device tun0 opened
Mon Jan 31 22:38:38 2022 TUN/TAP TX queue length set to 100
Mon Jan 31 22:38:38 2022 do_ifconfig, tt->did_ifconfig_ipv6_setup=0
Mon Jan 31 22:38:38 2022 /sbin/ip link set dev tun0 up mtu 1500
Mon Jan 31 22:38:38 2022 /sbin/ip addr add dev tun0 10.9.0.2/24 broadcast 10.9.0.255
Mon Jan 31 22:38:38 2022 /sbin/ip route add 172.33.33.134/32 dev ens18
Mon Jan 31 22:38:38 2022 /sbin/ip route add 0.0.0.0/1 via 10.9.0.1
Mon Jan 31 22:38:38 2022 /sbin/ip route add 128.0.0.0/1 via 10.9.0.1
Mon Jan 31 22:38:38 2022 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
Mon Jan 31 22:38:38 2022 Initialization Sequence Completed

если открыть еще одну сессию на узле 172.33.33.126 и попробовать пропинговать 10.9.0.1 — если пакеты пойдут значит VPN-сеть поднялась:

ekzorchik@srv-bionic:~$ ip r
0.0.0.0/1 via 10.9.0.1 dev tun0 
default via 172.33.33.100 dev ens18 proto dhcp src 172.33.33.126 metric 100 
10.9.0.0/24 dev tun0 proto kernel scope link src 10.9.0.2 
128.0.0.0/1 via 10.9.0.1 dev tun0 
172.33.33.0/24 dev ens18 proto kernel scope link src 172.33.33.126 
172.33.33.100 dev ens18 proto dhcp scope link src 172.33.33.126 metric 100 
172.33.33.134 dev ens18 scope link 
ekzorchik@srv-bionic:~$ ping 10.9.0.1
PING 10.9.0.1 (10.9.0.1) 56(84) bytes of data.
64 bytes from 10.9.0.1: icmp_seq=1 ttl=64 time=0.522 ms
^C
--- 10.9.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.522/0.522/0.522/0.000 ms
ekzorchik@srv-bionic:~$

Шаг №10: Отлично, теперь запускаю OpenVPN сервис на клиенте, где client это /etc/openvpn/client.conf:

ekzorchik@srv-bionic:~$ sudo nano /etc/default/openvpn
AUTOSTART="client"
ekzorchik@srv-bionic:~$ sudo reboot
ekzorchik@srv-bionic:~$ sudo systemctl status openvpn | head -n5
[sudo] password for ekzorchik: 
● openvpn.service - OpenVPN service
   Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2022-01-31 22:41:32 MSK; 21s ago
  Process: 548 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
 Main PID: 548 (code=exited, status=0/SUCCESS)
ekzorchik@srv-bionic:~$

Клиентская часть успешно подключается после перезагрузки системы.

Шаг №11: Логи работы OpenVPN сервиса можно смотреть так:

ekzorchik@srv-bionic:~$ sudo journalctl --identifier openvpn

Итого я успешно поднял OpenVPN сервер на Ubuntu 20.04 Server, что собственно мне и требовалось. На этом заметка завершена, с уважением автор блога Олло Александр aka ekzorchik.