VPN_Linux
Настройка VPN в Linux
VPN (Virtual Private Network) создаёт защищённый туннель поверх другой сети. Он применяется для удалённого доступа, объединения площадок и направления трафика через защищённый шлюз.
Основные режимы:
- remote access — клиенты подключаются к серверу;
- site-to-site — объединяются две локальные сети;
- full tunnel — весь трафик клиента идёт через VPN;
- split tunnel — через VPN идут только заданные сети.
Перед изменением сети удалённого сервера подготовьте резервный доступ через консоль. Имена пакетов, служб и пути могут различаться между дистрибутивами.
Выбор технологии
| Технология | Особенности | Применение |
|---|---|---|
| WireGuard | Простая конфигурация, высокая производительность, ключи peer-to-peer | Новые VPN, remote access, site-to-site |
| OpenVPN | TLS/PKI, UDP или TCP, широкая совместимость | Сложные и устаревшие инфраструктуры |
| IPsec/IKEv2 | Стандартный стек, поддержка многими ОС | Корпоративный доступ, мобильные клиенты, site-to-site |
| L2TP/IPsec | L2TP внутри IPsec, обычно IKEv1 и общий PSK | Совместимость с существующими системами |
L2TP без IPsec не обеспечивает надёжной защиты. Для новых установок обычно выбирают WireGuard или IKEv2.
Общая подготовка
Проверка интерфейсов, маршрутов и портов:
ip -brief address
ip route
ip -6 route
ss -lntup
ip route get 1.1.1.1VPN-подсети не должны пересекаться с сетями клиентов и площадок. Пример:
VPN: 10.20.0.0/24
Офисная сеть: 10.30.0.0/24
Удалённая сеть: 10.40.0.0/24Включение IPv4 forwarding:
sudo sysctl -w net.ipv4.ip_forward=1Постоянная настройка /etc/sysctl.d/99-vpn.conf:
net.ipv4.ip_forward = 1Применение:
sudo sysctl --systemДля маршрутизации IPv6 при необходимости:
net.ipv6.conf.all.forwarding = 1Если клиенты выходят в интернет через VPN-сервер, обычно нужны forwarding и NAT. Пример для VPN-сети 10.20.0.0/24, интерфейсов wg0 и eth0:
sudo iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wg0 \
-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A POSTROUTING \
-s 10.20.0.0/24 -o eth0 -j MASQUERADEНе управляйте одними правилами одновременно через iptables, nftables, ufw и firewalld.
WireGuard
WireGuard создаёт виртуальный интерфейс. Узлы идентифицируются открытыми ключами, а AllowedIPs одновременно участвует в маршрутизации и проверке адресов peer.
Установка
# Debian/Ubuntu
sudo apt update && sudo apt install wireguard
# Fedora/RHEL-подобные
sudo dnf install wireguard-tools
# Arch Linux
sudo pacman -S wireguard-toolsКлючи
На сервере:
sudo install -d -m 700 /etc/wireguard
umask 077
wg genkey | sudo tee /etc/wireguard/server.key | \
wg pubkey | sudo tee /etc/wireguard/server.pub >/dev/nullНа клиенте:
umask 077
wg genkey | tee client.key | wg pubkey > client.pubЗакрытые ключи нельзя публиковать и помещать в Git.
Сервер
/etc/wireguard/wg0.conf:
[Interface]
Address = 10.20.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
[Peer]
# laptop
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.20.0.2/32sudo chmod 600 /etc/wireguard/wg0.conf
sudo systemctl enable --now wg-quick@wg0
sudo wg showОткрытие порта:
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPTКлиент
[Interface]
Address = 10.20.0.2/32
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 10.20.0.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 250.0.0.0/0, ::/0 создаёт full tunnel. Для split tunnel:
AllowedIPs = 10.20.0.0/24, 10.30.0.0/24Управление:
sudo wg-quick up wg0
sudo wg-quick down wg0
sudo systemctl restart wg-quick@wg0PersistentKeepalive = 25 полезен клиенту за NAT. Каждому клиенту на сервере назначают уникальный /32; пересекающиеся AllowedIPs приводят к неправильному выбору peer.
Site-to-site
На площадке A, где удалённая сеть B — 10.40.0.0/24:
[Peer]
PublicKey = SITE_B_PUBLIC_KEY
Endpoint = site-b.example.com:51820
AllowedIPs = 10.20.0.2/32, 10.40.0.0/24
PersistentKeepalive = 25На B, где сеть A — 10.30.0.0/24:
[Peer]
PublicKey = SITE_A_PUBLIC_KEY
Endpoint = site-a.example.com:51820
AllowedIPs = 10.20.0.1/32, 10.30.0.0/24
PersistentKeepalive = 25На обоих шлюзах нужны forwarding, firewall и обратные маршруты. NAT между площадками обычно не нужен.
NetworkManager
sudo nmcli connection import type wireguard file ./wg0.conf
sudo nmcli connection up wg0
sudo nmcli connection down wg0OpenVPN
OpenVPN использует TLS и PKI. Обычно применяется tun. UDP предпочтителен; TCP полезен в ограниченных сетях, но VPN поверх TCP может снижать производительность.
Установка
# Debian/Ubuntu
sudo apt install openvpn easy-rsa
# Fedora/RHEL-подобные
sudo dnf install openvpn easy-rsa
# Arch Linux
sudo pacman -S openvpn easy-rsaСоздание PKI
make-cadir ~/openvpn-ca
cd ~/openvpn-ca
./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
./easyrsa gen-crl
openvpn --genkey secret tls-crypt.keyЗакрытый ключ CA желательно хранить отдельно от публичного VPN-сервера. Каждый клиент должен иметь отдельный сертификат.
Сервер
Пример /etc/openvpn/server/server.conf:
port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
crl-verify /etc/openvpn/server/crl.pem
tls-crypt /etc/openvpn/server/tls-crypt.key
server 10.21.0.0 255.255.255.0
topology subnet
push "route 10.30.0.0 255.255.255.0"
push "dhcp-option DNS 10.20.0.1"
keepalive 10 120
persist-key
persist-tun
user nobody
group nogroup
verb 3
explicit-exit-notify 1Запуск и проверка:
sudo systemctl enable --now openvpn-server@server
systemctl status openvpn-server@server
journalctl -u openvpn-server@server
ip address show tun0Имя systemd-юнита может отличаться:
systemctl list-unit-files | grep -i openvpnКлиент
client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verb 3
<ca>
...
</ca>
<cert>
...
</cert>
<key>
...
</key>
<tls-crypt>
...
</tls-crypt>sudo openvpn --config client1.ovpn
sudo nmcli connection import type openvpn file ./client1.ovpnFull tunnel:
push "redirect-gateway def1"Split tunnel:
push "route 10.30.0.0 255.255.255.0"
push "route 10.40.0.0 255.255.255.0"Отзыв клиента:
./easyrsa revoke client1
./easyrsa gen-crlПосле этого новый crl.pem необходимо установить на сервер.
IPsec/IKEv2
IPsec защищает IP-трафик, а IKEv2 согласует параметры, выполняет аутентификацию и управляет ключами. В Linux часто применяется strongSwan.
Порты и протоколы:
- UDP
500— IKE; - UDP
4500— NAT Traversal; - IP protocol
50— ESP без NAT-T.
Установка strongSwan
# Debian/Ubuntu
sudo apt install strongswan strongswan-pki
# Fedora/RHEL-подобные
sudo dnf install strongswan
# Arch Linux
sudo pacman -S strongswanСовременный интерфейс strongSwan — swanctl; традиционный — ipsec.conf. Сертификат сервера должен содержать DNS-имя, например vpn.example.com, в SAN. CA должна быть доверенной клиентом.
Пример IKEv2 remote access
/etc/swanctl/swanctl.conf:
connections {
ikev2-eap {
version = 2
send_cert = always
proposals = aes256gcm16-prfsha384-ecp384,aes256-sha256-modp2048
pools = vpn-pool
local {
auth = pubkey
certs = server-cert.pem
id = vpn.example.com
}
remote {
auth = eap-mschapv2
eap_id = %any
}
children {
net {
local_ts = 0.0.0.0/0
esp_proposals = aes256gcm16-ecp384,aes256-sha256
}
}
}
}
pools {
vpn-pool {
addrs = 10.22.0.0/24
dns = 10.20.0.1
}
}
secrets {
eap-user1 {
id = user1
secret = "REPLACE_WITH_A_STRONG_PASSWORD"
}
}Каталоги swanctl:
/etc/swanctl/x509/ сертификаты узлов
/etc/swanctl/x509ca/ сертификаты CA
/etc/swanctl/private/ закрытые ключиsudo swanctl --load-all
sudo swanctl --list-conns
sudo swanctl --list-certs
sudo swanctl --list-sasНужные EAP-плагины и имя службы зависят от пакета:
systemctl list-unit-files | grep -E 'strongswan|charon'Firewall:
sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT
sudo iptables -A INPUT -p esp -j ACCEPTДля клиентов также настраиваются forwarding и при необходимости NAT.
Site-to-site
connections {
site-b {
version = 2
remote_addrs = 203.0.113.20
local {
auth = pubkey
certs = site-a.pem
id = site-a.example.com
}
remote {
auth = pubkey
id = site-b.example.com
}
children {
lan-to-lan {
local_ts = 10.30.0.0/24
remote_ts = 10.40.0.0/24
start_action = start
close_action = restart
dpd_action = restart
}
}
}
}На второй стороне локальные и удалённые параметры меняются местами.
L2TP/IPsec
L2TP создаёт туннель, а IPsec защищает его. В Linux часто используются strongSwan, xl2tpd и PPP.
Порты: UDP 500, 4500, 1701 и ESP. UDP 1701 не следует открывать в интернет без ограничения политикой IPsec.
# Debian/Ubuntu
sudo apt install strongswan xl2tpd pppПример /etc/ipsec.conf:
config setup
uniqueids=no
conn l2tp-psk
type=transport
keyexchange=ikev1
authby=psk
left=%defaultroute
leftprotoport=17/1701
right=%any
rightprotoport=17/%any
auto=add/etc/ipsec.secrets:
: PSK "REPLACE_WITH_A_LONG_RANDOM_SECRET"sudo chmod 600 /etc/ipsec.secrets/etc/xl2tpd/xl2tpd.conf:
[global]
port = 1701
[lns default]
ip range = 10.23.0.10-10.23.0.200
local ip = 10.23.0.1
require authentication = yes
require chap = yes
refuse pap = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes/etc/ppp/options.xl2tpd:
name l2tp-server
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
proxyarp
mtu 1280
mru 1280
lock
hide-password/etc/ppp/chap-secrets:
user1 l2tp-server REPLACE_WITH_A_STRONG_PASSWORD *sudo chmod 600 /etc/ppp/chap-secrets
systemctl list-unit-files | grep -E 'strongswan|ipsec|xl2tpd'PSK является общим секретом IPsec и не заменяет учётные данные PPP. Общий PSK неудобен для индивидуального отзыва, поэтому L2TP/IPsec обычно оставляют для совместимости.
DNS, маршруты и MTU
VPN может направлять весь DNS через туннель или применять split DNS только для внутренних доменов.
resolvectl status
resolvectl query internal.example
dig @10.20.0.1 internal.exampleЕсли доступ по IP работает, а по имени — нет, проверьте DNS-адрес, маршрут, UDP/TCP 53, разрешённые подсети на DNS-сервере и интеграцию клиента с NetworkManager или systemd-resolved.
Для доступа к внутренней сети нужен обратный маршрут к VPN-подсети. Альтернатива — SNAT/MASQUERADE, но тогда внутренние узлы не видят реальные адреса клиентов.
Инкапсуляция уменьшает MTU. Признаки проблемы: небольшие пакеты проходят, большие соединения зависают.
ping -M do -s 1372 1.1.1.1
tracepath 1.1.1.1Для WireGuard часто используется MTU около 1420, но значение зависит от нижележащей сети.
Диагностика
ip -brief address
ip route
ip rule
ip route get 10.30.0.10
sysctl net.ipv4.ip_forward
sudo nft list ruleset
sudo iptables -L -n -v
sudo iptables -t nat -L -n -vЗахват внешнего трафика:
sudo tcpdump -ni any udp port 51820
sudo tcpdump -ni any udp port 1194
sudo tcpdump -ni any 'udp port 500 or udp port 4500'WireGuard:
sudo wg showЕсли latest handshake отсутствует, проверяются ключи, Endpoint, порт и firewall. Если handshake есть, но трафика нет, проверяются AllowedIPs, маршруты, forwarding и NAT.
OpenVPN:
journalctl -u openvpn-server@server --since today
sudo openvpn --config client1.ovpn --verb 4strongSwan:
sudo swanctl --list-sas
sudo ipsec statusall
ip xfrm state
ip xfrm policyПроверка внутри туннеля:
sudo tcpdump -ni wg0
sudo tcpdump -ni tun0Если пакет виден внутри VPN, но не выходит наружу, причина обычно в forwarding, firewall, NAT или обратном маршруте.
Безопасность и типичные ошибки
- Используйте отдельный ключ или сертификат для каждого клиента.
- Отзывайте доступ потерянных устройств и бывших пользователей.
- Ограничивайте маршруты и firewall минимально необходимыми сетями.
- Защищайте закрытые ключи правами
600, каталоги —700. - Не храните ключи, PSK и пароли в Git и общих журналах.
- Контролируйте срок действия и отзыв сертификатов.
- При full tunnel учитывайте IPv4, IPv6 и DNS, иначе возможен обход туннеля.
- Избегайте пересечения VPN-подсети с домашними и офисными сетями.
- Проверяйте системное время при ошибках сертификатов:
timedatectl status
openssl x509 -in server.crt -noout -subject -issuer -dates -ext subjectAltNameЕсли туннель поднят, но сеть недоступна, последовательно проверяйте маршрут клиента, ip_forward, FORWARD, NAT и обратный маршрут.
Краткая памятка
# WireGuard
sudo systemctl enable --now wg-quick@wg0
sudo wg show
# OpenVPN
sudo openvpn --config client.ovpn
sudo journalctl -u openvpn-server@server
# strongSwan
sudo swanctl --load-all
sudo swanctl --list-sas
sudo ipsec statusall
# Сеть
ip -brief address
ip route
sysctl net.ipv4.ip_forward
sudo nft list rulesetРекомендуемый порядок внедрения: выбрать протокол и подсеть, настроить DNS-имя и время, создать ключи или сертификаты, подключить одного тестового клиента, открыть нужные порты, включить forwarding, добавить маршруты или NAT, проверить DNS и MTU, затем настроить автозапуск, отзыв доступа, резервное копирование и мониторинг.