linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • Симулятор
  • База знаний
  • Собеседование
Index
Categories
All entries
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
home/linux/kb/Протоколы/wireguard

kb/protocols ── Протоколы ── intermediate

WireGuard - современный UDP-VPN

WireGuard - UDP-VPN в ядре Linux. Пара ключей Curve25519, peers с AllowedIPs (это и ACL, и routing-table). ~4000 строк кода против миллионов у OpenVPN/IPsec. Конфиг плоский, без TLS и сертификатов.

view as markdownaka: wg, wireguard-vpn, wg-quick

Зачем WireGuard

Появился в 2016, в mainline kernel с 5.6 (2020). Цель: VPN без гипер-сложности [[ipsec-ike|IPsec]] и без оверхеда [[openvpn|OpenVPN]]. Что получилось:

  • Один тип пакета (UDP), один cipher-suite (ChaCha20-Poly1305 + Curve25519), без negotiation. Если будущие primitives устареют выйдет WireGuard 2.
  • Stateless с точки зрения админа: пара ключей на каждой стороне, публичный ключ peer'а, единственный identifier.
  • AllowedIPs, одновременно ACL (что peer может слать) и routing-table (куда заворачивать пакеты на этот peer).
  • Roaming: peer может менять IP/порт без переподключения, потому что аутентификация по ключу, не по 5-tuple.

Базовый конфиг

Серверная сторона /etc/wireguard/wg0.conf:

ini
[Interface]
PrivateKey = <server-private-key>
Address = 10.10.0.1/24
ListenPort = 51820
PostUp   = iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
[Peer]
PublicKey  = <client-public-key>
AllowedIPs = 10.10.0.2/32

Клиент wg0.conf:

ini
[Interface]
PrivateKey = <client-private-key>
Address = 10.10.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey  = <server-public-key>
Endpoint   = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0           # full-tunnel; для split-tunnel - конкретные подсети
PersistentKeepalive = 25                # за NAT'ом, держит conntrack-запись

Запуск:

bash
wg-quick up wg0
systemctl enable wg-quick@wg0          # автостарт

Генерация ключей

bash
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Приватный ключ никогда не покидает машину. Конфиг хранит его открытым текстом, поэтому права 600 на /etc/wireguard/. Секретный ключ всегда генерируется на peer'е, не на сервере.

PSK (опционально, для quantum-resistance):

bash
wg genpsk > preshared.key

и в [Peer]: PresharedKey = <psk>.

AllowedIPs, самое важное поле

AllowedIPs = 10.10.0.2/32                  # один host
AllowedIPs = 10.10.0.0/24, 192.168.5.0/24  # несколько подсетей
AllowedIPs = 0.0.0.0/0, ::/0               # ВСЁ - full-tunnel
  • Входящий пакет от peer'а: src должен попадать в AllowedIPs, иначе drop. Это и есть аутентификация trust-границы.
  • Исходящий пакет: если dst попадает в AllowedIPs какого-то peer'а, wg0 направляет на него. Аналогично routing.

Поэтому одна и та же подсеть 10.10.0.0/24 не может быть в AllowedIPs у двух peer'ов одновременно, конфликт routing.

Роли: hub-and-spoke vs full-mesh

WireGuard на L3 не различает "сервер" и "клиент", оба peers равны. Topology, это просто кто кому что прописал в [Peer]:

  • Hub: один peer со всеми peer-блоками; AllowedIPs у каждого клиента, узкая. Простая модель, классический "VPN-сервер".
  • Mesh: каждый знает каждого. Сложнее провижионить, но трафик напрямую без хопа через hub.
  • Tailscale/Headscale автоматизируют mesh поверх WireGuard.

NAT и keepalive

За NAT'ом запись в conntrack умирает за 30-180 секунд если нет трафика. WireGuard про это знает, PersistentKeepalive = 25 шлёт пустой keepalive каждые 25 секунд, чтобы дыра в NAT'е жила.

Hub за статическим IP PersistentKeepalive не нужен. Клиент за CGNAT (мобильный оператор), нужен.

Диагностика

bash
wg show                                  # все интерфейсы и peers
wg show wg0                              # детали одного
wg show wg0 dump                         # машинно-читаемый формат
wg show wg0 latest-handshakes            # когда последний handshake
wg show wg0 transfer                     # rx/tx bytes на peer

Главный индикатор живой связи, latest handshake должен обновляться раз в ~2 минуты. Если показывает "30 minutes ago" peer недостижим.

WireGuard vs OpenVPN vs IPsec

ПризнакWireGuardopenvpnipsec-ike
Кодовая база~4 KLOC~600 KLOCмлн (strongSwan)
Где живётв ядреuserspaceв ядре + IKE userspace
Конфигплоский ininested + certsswanctl.conf + сертификаты
CipherChaCha20-Poly1305 (фиксирован)TLS suiteIKEv2-negotiated
UDPдада или TCPда (ESP)
Roamingнативнонетмoblike-расширение
Performanceзаметно быстреемедленнее (userspace)сравнимо с WG
Production-зрелость2020+2002+1995+
Сертификаты / PKIнетдада

Когда не WireGuard:

  • Нужен PKI (corp с CRL/OCSP) → IPsec/OpenVPN
  • Нужен TCP fallback (port 443 как маскировка) → OpenVPN
  • Per-user-аутентификация с RADIUS/LDAP → OpenVPN
  • Стандарт для interop с Cisco/Juniper → IPsec

Когда что-то пошло не так

  • No such device wg0, модуль не загружен. На kernel 5.6+ встроен; на старых нужен wireguard-dkms. modprobe wireguard.
  • Handshake не происходит, UDP 51820 закрыт по пути. Проверь nc -u -z -v server 51820, фаервол на хосте, NAT.
  • Handshake есть, трафик не ходит, ip route не имеет route'а на VPN-подсеть; либо ip-forwarding выключен на сервере; либо нет MASQUERADE.
  • Слишком жирный пакет дропается, MTU. WG-overhead 60 байт (UDP + headers); ставь MTU = 1420 явно если канал имеет MTU 1500.
  • Address already in use при wg-quick up, IP уже занят на другом интерфейсе (старый wg0 не выключен). wg-quick down wg0.
  • AllowedIPs пересекаются у двух peers, последний выигрывает, остальные становятся unreachable. Не пересекай подсети.
  • PersistentKeepalive слишком частый, лишний батарея на мобильных клиентах. 25 сек, компромисс с NAT (60s typical).

§ команды

bash
wg genkey | tee privatekey | wg pubkey > publickey

Сгенерировать пару ключей одной строкой - private + public

bash
wg-quick up wg0

Поднять интерфейс с конфигом /etc/wireguard/wg0.conf

bash
wg show wg0 latest-handshakes

Когда последний handshake с каждым peer'ом - живая ли связь

bash
wg show wg0 transfer

Сколько rx/tx байт ушло-пришло через peer - индикатор активности

bash
wg syncconf wg0 <(wg-quick strip wg0)

Подхватить изменения в конфиге без перезапуска интерфейса

bash
ip -d link show wg0

Параметры интерфейса - MTU, статистика, тип

bash
tcpdump -i any -nn 'udp port 51820' -c 5

Видны ли WireGuard-пакеты на проводе - первое что смотреть при no-handshake

§ см. также

  • openvpnOpenVPN - TLS-based VPNOpenVPN - userspace TLS-VPN на сертификатах X.509. Режимы: tun (L3, default) или tap (L2). Поддерживает UDP/TCP, push routes, per-user-аутентификацию, TCP-443 как маскировку. Жирнее [[wireguard|WG]].
  • ipsec-ikeIPsec и IKEv2 - стандарт корпоративных VPNIPsec - L3-VPN-стандарт. ESP инкапсулирует и шифрует, IKEv2 обменивается ключами. Tunnel-mode даёт новый IP-заголовок для site-to-site; transport-mode - host-to-host. На Linux это strongSwan.
  • udp-basicsUDP - User Datagram ProtocolUDP - простой протокол доставки датаграмм без установки соединения, без ретрансмитов, без гарантии порядка. Заголовок 8 байт. Применение: DNS, DHCP, QUIC, VoIP, любой случай когда задержка важнее надёжности.
  • natNAT и masqueradeNAT - переписывание src/dst адресов пакета на роутере. Masquerade - частный случай: src-IP заменяется на свой исходящий, для исходящих из приватной сети в публичную.
  • cmd-nftnft - современный файрвол (nftables)`nft` - единый CLI для современного netfilter. Заменяет iptables/ip6tables/ arptables/ebtables. Структура: tables → chains → rules.
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки