Найти тему
Сисадмин Михалыч

OpenVPN внутри SSH-тоннеля

Порядок действий

На сервере:

Репозитории debian 12 на случай если их не будет:

deb http://deb.debian.org/debian/ bookworm main non-free-firmware non-free
deb http://security.debian.org/debian-security bookworm-security main non-free-firmware non-free
deb http://deb.debian.org/debian/ bookworm-updates main non-free-firmware non-free

Все действия от root

apt update && apt install openvpn mc easy-rsa iptables
mkdir /etc/openvpn/easy-rsa
chown root /etc/openvpn/easy-rsa
chmod 700 /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa/
cp /usr/share/easy-rsa/vars.example vars
mcedit /etc/openvpn/easy-rsa/vars

Установить значения переменных:

set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_ALGO "rsa"
set_var EASYRSA_DIGEST "sha256"
set_var EASYRSA_CERT_EXPIRE 3650

CRL - Настраивать не будем, если нужно есть в ролике:

/etc/openvpn/easy-rsa/ - будет рабочая директория с программой easyrsa

Создадим симлинк на программу в нашу рабочую директорию:

ln -s /usr/share/easy-rsa/easyrsa easyrsa

Инициализируем PKI:

./easyrsa init-pki

Сгенерируем пароль закрытого ключа корневого сертификата (пароль запомнить и сохранить в надежном месте):

./easyrsa build-ca

Сгенерируем закрытый ключ и сертификат на VPN-сервер:

./easyrsa build-server-full deb12vpn nopass

Создаём конфиг сервера и приводим к виду:

mcedit /etc/openvpn/server/deb12vpn.conf

local 127.0.0.1
port 1194
proto tcp4
dev tun
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/deb12vpn.crt
key /etc/openvpn/easy-rsa/pki/private/deb12vpn.key
dh none
server 172.16.35.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway"
keepalive 10 120
auth sha256
compress lz4-v2
cipher AES-256-GCM
tun-mtu 1500
persist-key
persist-tun
sndbuf 524288
rcvbuf 524288
push "sndbuf 524288"
push "rcvbuf 524288"
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
log-append /var/log/openvpn/openvpn.log
verb 3
mute 20
topology subnet

Копируем готовый шаблон службы vpn-сервера (deb12vpn это имя конфиг файла в директории /etc/openvpn/server/)

cp /lib/systemd/system/openvpn-server@.service /lib/systemd/system/openvpn-server@deb12vpn.service

После создания/изменения/удаления файлов описания сервисов, необходимо systemd перечитать изменения:

systemctl daemon-reload

Стартуем сервис и смотрим его состояние, а так де наличие прослушиваемого tcp/1194 порта:

systemctl start openvpn-server@deb12vpn.service
systemctl status openvpn-server@deb12vpn.service
ss -nlpt | grep 1194

Если всё успешно, добавляем в автозагрузку при необходимости:

systemctl enable openvpn-server@deb12vpn.service

Выключим ipv6, затюнингуем сетевые параметры и разрешим трафик между сетевыми интерфейсами:

mcedit /etc/sysctl.d/99-sysctl.conf

# Network
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.core.rmem_max = 1073741824
net.core.wmem_max = 1073741824
net.ipv4.tcp_rmem = 1048576 16777216 1073741824
net.ipv4.tcp_wmem = 1048576 16777216 1073741824
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_reordering = 20
net.ipv4.tcp_mem = 1048576 16770216 1073741824
net.ipv4.ip_forward = 1

Создадим правила iptables и добавим в автозапуск через cron:

mkdir /etc/iptables/
mcedit /etc/iptables/rules.ipt

Здесь enp1s0 это интерфейс смотрящий в интернет

*nat
:PREROUTING ACCEPT
:OUTPUT ACCEPT
:POSTROUTING ACCEPT
-A POSTROUTING -o enp1s0 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i enp1s0 -p tcp --dport 22 -j ACCEPT
-A INPUT -i tun0 -j ACCEPT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A FORWARD -i enp1s0 -o tun0 -j ACCEPT
-A FORWARD -i tun0 -o enp1s0 -j ACCEPT
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

mkdir /root/scripts
mcedit /root/scripts/iptables-reload.sh

Привести к виду:

#!/bin/bash
/usr/sbin/iptables-restore < /etc/iptables/rules.ipt

chmod +x /root/scripts/iptables-reload.sh
crontab -e

Добавляем строку:

@reboot /root/scripts/iptables-reload.sh

Включаем в sshd нужный алгоритм для повышения быстродействия:

mcedit /etc/ssh/sshd_config

Находим и изменяем или добавляем строку:

Ciphers aes256-gcm@openssh.com

Перезапускаем сервис:

systemctl restart sshd

Создаем закрытый ключ и сертификат клиента ovpn-client1 (при подписании необходимо ввести пароль закрытого ключа корневого сертификата):

./easyrsa gen-req ovpn-client1 nopass
./easyrsa sign-req client ovpn-client1

На клиента:

В моём случае это:

HW: Repka Pi3

OS: ALT Linux 10.2

OpenVPN 2.6.12

Подробная настройка клиента на ОС armbian в ролике:

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

mcedit /etc/openvpn/client/prov.conf

client
remote 127.0.0.1
port 1194
proto tcp4
dev tun
persist-key
persist-tun
verb 3
mssfix 1452
auth-nocache
auth sha256
compress lz4-v2
cipher AES-256-GCM
<ca>
Заполняем выполнив на сервере:
cat /etc/openvpn/easy-rsa/pki/ca.crt
</ca>
<cert>
Заполняем выполнив на сервере:
cat /etc/openvpn/easy-rsa/pki/issued/ovpn-client1.crt
</cert>
<key>
Заполняем выполнив на сервере:
cat /etc/openvpn/easy-rsa/pki/private/ovpn-client1.key
</key>

Копируем готовый шаблон службы vpn-сервера (prov это имя конфиг файла в директории /etc/openvpn/client/)

cp /lib/systemd/system/openvpn-client@.service /lib/systemd/system/openvpn-client@prov.service

После создания/изменения/удаления файлов описания сервисов, необходимо systemd перечитать изменения:

systemctl daemon-reload

Скрипты запуска и останова:

Если в системе не установлена программа autossh, то установить.

Данная программа будет выполнять роль трубы соединяющей порты openvpn сервера и клиента.

mkdir /root/scripts/
mcedit /root/scripts/start-vpn.sh

#!/bin/bash
if systemctl is-active --quiet openvpn-client@prov.service; then
echo "VPN работает!"
curl ifconfig.me && echo
else
autossh -M 0 -f -N -L 1194:127.0.0.1:1194 root@IP-VPN-сервера
sleep 1
systemctl start openvpn-client@prov.service
sleep 1
if systemctl is-active --quiet openvpn-client@prov.service; then
ip route add IP-VPN-сервера via IP-default-шлюза
ip route del default
ip route add default via 172.16.35.1
echo "VPN запущен!"
curl ifconfig.me && echo
fi
fi

Где IP-default-шлюза это адрес шлюза провайдера или роутера через который осуществляется доступ в интернет. Узнать его можно выполнив команду: ip roure

mcedit /root/scripts/stop-vpn.sh

#!/bin/bash
if systemctl is-active --quiet openvpn-client@prov.service; then
systemctl stop openvpn-client@prov.service
sleep 1
kill $(pgrep -f "1194:127.0.0.1:1194")
if ! systemctl is-active --quiet openvpn-client@prov.service; then
ip r add default via IP-default-шлюза
ip route del IP-VPN-сервера via IP-default-шлюза
echo "VPN остановлен!"
curl ifconfig.me && echo
fi
else
echo "VPN не запущен!"
curl ifconfig.me && echo
fi

Даём права на исполнение:

chmod +x /root/scripts/start-vpn.sh
chmod +x /root/scripts/stop-vpn.sh

Генерируем и добавляем открытый ключ ssh на сервер:

ssh-keygen
ssh-copy-id root@IP-VPN-сервера

Стартуем:

/root/scripts/start-vpn.sh

При необходимости можно добавить в cron для автозапуска:

crontab -e

Добавить строку:

@reboot /root/scripts/start-vpn.sh