WireGuard: неавторитетное руководство по установке и настройке WireGuard

1. Быстрый старт

Если вы хотите хорошо выполнять свою работу, вам сначала нужно заточить свои инструменты! Общий процесс выглядит следующим образом:

Подготовка

Проверьте текущую версию ядра

uname -r #4.18.0-348.2.1.el8_5.x86_64 uname -a #Linux mir4 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Вт ноя 16 14:42:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux cat /etc/redhat-release #CentOS Linux release 8.5.2111

Обновление ядра системы

обновление dnf -y

Установка репозитория EPEL на CentOS 8.x

EPEL расшифровывается как «Extra Packages for Enterprise Linux» (дополнительные пакеты для корпоративного Linux) и представляет собой бесплатный репозиторий с открытым исходным кодом, содержащий дополнительные пакеты для серверов CentOS и RHEL. Как следует из названия, репозиторий EPEL содержит дополнительные пакеты, недоступные в стандартных репозиториях CentOS 8 и RHEL 8.

официальный сайт epel:https://fedoraproject.org/wiki/EPEL/zh-cn

dnf search epel #epel-next-release.noarch: Дополнительные пакеты для Enterprise Linux Следующая конфигурация репозитория #epel-release.noarch: Дополнительные пакеты для Enterprise Linux Конфигурация репозитория #Проверьте версию epel-release в репозитории системного ПО dnf info epel-release #Установите исходный код epel из репозитория системного ПО dnf install epel-release #Установите исходный код epel с веб-сайта по URL-адресу dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm #Включите репозиторий PowerTools, так как пакеты EPEL могут зависеть от пакетов в этих репозиториях dnf config-manager --set-enabled powertools #После успешной установки проверьте количество пакетов в репозитории sudo dnf --disablerepo="*" --enablerepo="epel" список доступных | wc -l

Установка репозитория ELRepo на CentOS 8.x

Репозиторий ELRepo — это репозиторий, созданный сообществом для Linux корпоративного уровня, который обеспечивает поддержку Red Hat Enterprise (RHEL) и других дистрибутивов Linux на базе RHEL (CentOS, Scientific, Fedora и т. д.).
ELRepo фокусируется на пакетах программного обеспечения, связанных с оборудованием, включая драйверы файловых систем, графические драйверы, сетевые драйверы, драйверы звуковых карт и драйверы камер.

#Импортируйте открытый ключ репозитория ELRepo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org #Установите репозиторий ELRepo yum repository dnf install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm #Проверьте версию ядра dnf --disablerepo="*" --enablerepo="elrepo-kernel" list available

Перед установкой Wireguard на сервере должны быть установлены репозитории eple и ELRepo.

После установки источника программного обеспечения # очистите кэш dnf clean all # пересоздайте кэш репозитория yum makecache reboot

Установить

Официальная ссылка на установку:https://www.wireguard.com/install/

Ниже приведены методы установки для нескольких операционных систем, включая Centos8, Centos7, Ubuntu и MacOS.

#CentOS8 dnf install elrepo-release epel-release dnf config-manager --set-enabled powertools dnf copr enable jdoss/wireguard dnf install wireguard-dkms wireguard-tools #CentOS7 yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm yum install yum-plugin-elrepo yum install kmod-wireguard wireguard-tools #IЕсли вы используете нестандартное ядро, вам необходимо установить пакет DKMS yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm curl -o /etc/yum.repos.d/jdoss-wireguard-epel-7.repo https://copr.fedorainfracloud.org/coprs/jdoss/wireguard/repo/epel-7/jdoss-wireguard-epel-7.repo yum install wireguard-dkms wireguard-tools #Ubuntu≥18.04 apt install wireguard #Ubuntu≤16.04 add-apt-repository ppa:wireguard/wireguard apt-get update apt-get install wireguard #MacOS brew install wireguard-tools

Ссылка для загрузки клиента Windows:

  1. https://download.wireguard.com/windows-client/wireguard-amd64-0.1.1.msi
  2. https://download.wireguard.com/windows-client/wireguard-installer.exe

Для Android и iOS соответствующий клиент можно загрузить из магазина приложений:

https://www.wireguard.com/install/#installation

Включите переадресацию IP-адресов на сервере ретрансляции:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.proxy_arp = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf

Добавьте правила iptables, чтобы разрешить трансляцию NAT на этом компьютере:

iptables -A ВХОД -m conntrack --ctstate СВЯЗАННЫЕ, УСТАНОВЛЕННЫЕ -j ПРИНЯТЬ iptables -A ПЕРЕСЫЛКА -m conntrack --ctstate СВЯЗАННЫЕ, УСТАНОВЛЕННЫЕ -j ПРИНЯТЬ iptables -A ПЕРЕСЫЛКА -i wg0 -o wg0 -m conntrack --ctstate НОВЫЙ -j ПРИНЯТЬ iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o eth0 -j МАСКАРАД

Вам необходимо изменить eth0 на имя интерфейса сетевой карты, который вы фактически используете.

Написание файлов конфигурации

Файл конфигурации можно разместить в любом каталоге, но для него необходимо указать абсолютный путь. Путь по умолчанию — /etc/wireguard/wg0.conf.

# создайте файл конфигурации vi /etc/wireguard/wg0.conf

Сгенерировать ключ

Сгенерировать закрытый ключ

wg genkey > example.key

Сгенерировать открытый ключ

открытый ключ wg < пример.ключ > example.key.pub

Запуск и остановка

$ wg-quick up /full/path/to/wg0.conf
$ wg-quick down /full/path/to/wg0.conf

# Запуск/остановка сетевого интерфейса VPN
$ IP-соединение установлено wg0 вверх
$ IP-соединение установлено wg0 вниз

# Регистрация/отмена регистрации сетевого интерфейса VPN
$ ip link add dev wg0 type wireguard
$ ip link delete dev wg0

# Регистрация/отмена регистрации локального VPN-адреса
$ IP-адрес добавить dev wg0 192.0.2.3/32
$ IP-адрес удалить dev wg0 192.0.2.3/32

# Добавить/удалить маршруты VPN
$ ip route add 192.0.2.3/32 dev wg0
$ IP-маршрут удалить 192.0.2.3/32 dev wg0

Просмотреть информацию

интерфейс:

# Просмотр информации о системном VPN-интерфейсе
$ ip link show wg0

# Просмотреть сведения об интерфейсе VPN
$ wg показать все
$ wg show wg0

адрес:

# Просмотр адреса интерфейса VPN
$ IP-адрес показать wg0

маршрутизация

# Просмотр таблицы маршрутизации системы
$ IP Route Show Table Main
$ IP Route Show Table Local

# Получить маршрут к определенному IP-адресу
$ IP-маршрут получить 192.0.2.3

Установка в один клик

Для установки в один клик обратитесь к этому проекту: установщик WireGuard[3]

2. Подробности конфигурации

WireGuard использует INI[4] Формат файла конфигурации: /etc/wireguard/wg0.conf. Файл конфигурации может быть размещён в любом каталоге, но к нему должен быть указан абсолютный путь. Путь по умолчанию: /etc/wireguard/wg0.conf.

Файл конфигурации должен иметь имя ${имя интерфейса WireGuard}.conf. Обычно имена интерфейсов WireGuard начинаются с префикса «wg» и нумеруются, начиная с 0, но вы можете использовать другие имена, соответствующие регулярному выражению ^[a-zA-Z0-9_=+.-]{1,15}$.

Вы можете вручную настроить VPN с помощью команды wg, но обычно рекомендуется использовать wg-quick, который обеспечивает более мощный и удобный интерфейс настройки и позволяет управлять конфигурацией с помощью файлов конфигурации.

Ниже приведен пример файла конфигурации:

[Интерфейс]
# Имя = node1.example.tld
Адрес = 192.0.2.3/32
ListenPort = 51820
PrivateKey = localPrivateKeyAbcAbcAbc=
DNS = 1.1.1.1,8.8.8.8
Таблица = 12345
МТУ = 1500
PreUp = /bin/example arg1 arg2 %i
PostUp = /bin/example arg1 arg2 %i
PreDown = /bin/example arg1 arg2 %i
PostDown = /bin/example arg1 arg2 %i

[Вглядеться]
# Имя = node2-node.example.tld
Разрешенные IP-адреса = 192.0.2.1/24
Конечная точка = node1.example.tld:51820
PublicKey = remotePublicKeyAbcAbcAbc=
PersistentKeepalive = 25

[Интерфейс]

В этом разделе определяется локальная конфигурация VPN. Например:

  • Локальный узел — это клиент, который маршрутизирует только свой собственный трафик и предоставляет только один IP-адрес.
    [Интерфейс]
    # Имя = phone.example-vpn.dev
    Адрес = 192.0.2.5/32
    PrivateKey =
  • Локальный узел представляет собой ретрансляционный сервер, который пересылает трафик другим одноранговым узлам и предоставляет маршруты всей подсети VPN.
    [Интерфейс]
    # Имя = public-server1.example-vpn.tld
    Адрес = 192.0.2.1/24
    ListenPort = 51820
    PrivateKey =
    DNS = 1.1.1.1

① Имя #

Это стандартный комментарий в синтаксисе INI, используемый для указания узла, к которому принадлежит этот раздел конфигурации. WireGuard полностью игнорирует этот раздел конфигурации и не влияет на поведение VPN.

② Адрес

Определяет диапазон адресов, на который должен маршрутизироваться локальный узел. Если это обычный клиент, укажите собственный IP-адрес узла (с использованием нотации CIDR, например, 192.0.2.3/32); если это сервер-ретранслятор, укажите диапазон маршрутизируемых подсетей.

Например:

  • Обычный клиент, маршрутизирующий только свой трафик: Адрес = 192.0.2.3/32
  • Ретрансляционный сервер, который может пересылать трафик другим одноранговым узлам (пирам): Адрес = 192.0.2.1/24
  • Вы также можете указать несколько подсетей или подсетей IPv6: Адрес = 192.0.2.1/24,2001:DB8::/64

③ Прослушиваемый порт

Если локальный узел является сервером ретрансляции, этот параметр необходим для указания порта для прослушивания входящих VPN-подключений. Номер порта по умолчанию — 51820. Обычным клиентам этот параметр не нужен.

④ Закрытый ключ

Закрытый ключ локального узла должен быть установлен для всех узлов (включая ретрансляционные серверы). Он не может быть передан другим серверам.

Закрытый ключ можно сгенерировать с помощью команды wg genkey > example.key.

⑤ DNS

Объявите DNS-сервер клиенту через DHCP. Клиент будет использовать указанный здесь DNS-сервер для обработки DNS-запросов в VPN-подсети, но этот параметр также можно переопределить в системе. Например:

  • Если не настроено, используется системный DNS по умолчанию.
  • Вы можете указать один DNS: DNS = 1.1.1.1
  • Вы также можете указать несколько DNS: DNS = 1.1.1.1,8.8.8.8

⑥ Таблица

Определяет таблицу маршрутизации, используемую VPN-подсетью. По умолчанию настройки не требуются. У этого параметра есть два специальных значения, на которые следует обратить внимание:

  • Таблица = выкл. : Отключить создание маршрута
  • Таблица = авто (по умолчанию) : Добавить маршрут в системную таблицу по умолчанию и включить специальную обработку для маршрута по умолчанию.

Например: Таблица = 1234

⑦ МТУ

Определяет MTU (максимальный размер передаваемого блока) для подключения к одноранговому узлу. По умолчанию его не требуется настраивать, так как система обычно определяет его автоматически.

⑧ PreUp

Команда, которую необходимо выполнить перед запуском VPN-интерфейса. Этот параметр можно указать несколько раз, и он будет выполнен по порядку.

Например:

  • Добавьте маршрут: PreUp = ip rule add ipproto tcp dport 22 table 1234

⑨ ПостАп

Команда, которая будет запущена после запуска VPN-интерфейса. Этот параметр можно указать несколько раз, и он будет выполнен по порядку.

Например:

  • Прочитать значения конфигурации из файла или вывода команды:
    PostUp = wg set %i секретный ключ /etc/wireguard/wg0.key <(some command here)
  • Добавьте строку журнала в файл:
    PostUp = echo "$(дата +%s) WireGuard запущен" >> /var/log/wireguard.log
  • Вызов WebHook:
    PostUp = завиток https://events.example.dev/wireguard/started/?key=abcdefg
  • Добавить маршрут:
    PostUp = правило ip добавить ipproto tcp dport 22 таблица 1234
  • Добавьте правила iptables для включения пересылки пакетов:
    PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  • Заставьте WireGuard повторно разрешить IP-адрес доменного имени удаленного узла:
    PostUp = resolvectl domain %i "~."; resolvectl dns %i 192.0.2.1; resolvectl dnssec %i да

⑩ Предварительный запуск

Команда, которую необходимо выполнить перед остановкой VPN-интерфейса. Этот параметр можно указать несколько раз, и он будет выполнен по порядку.

Например:

⑪ PostDown

Команда, которая будет запущена после остановки VPN-интерфейса. Этот параметр можно указать несколько раз, и он будет выполнен по порядку.

Например:

  • Добавьте строку журнала в файл:
    PostDown = echo "$(date +%s) WireGuard отключается" >> /var/log/wireguard.log
  • Вызов WebHook:
    PostDown = curl https://events.example.dev/wireguard/stopping/?key=abcdefg
  • Удалите правила iptables и отключите пересылку пакетов:
    PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Вглядеться]

Настройка VPN, определяющая одноранговые узлы, которые могут маршрутизировать трафик для одного или нескольких адресов. Одноранговый узел может быть ретранслятором, пересылающим трафик другим одноранговым узлам, или клиентом, подключающимся напрямую к VPN через публичную или частную сеть.

Сервер ретрансляции должен определить всех клиентов как одноранговых. Другие клиенты, за исключением сервера ретрансляции, не могут определить узлы за NAT как одноранговые, поскольку они недоступны. Клиентам, которые маршрутизируют трафик только для себя, достаточно определить в качестве однорангового только сервер ретрансляции и любые другие узлы, к которым им необходим прямой доступ.

Например, в следующей конфигурации public-server1 действует как сервер ретрансляции, а другие клиенты либо подключены напрямую, либо находятся за NAT:

  • public-server1 (сервер-ретранслятор) [пир] : public-server2, домашний сервер, ноутбук, телефон
  • public-server2 (клиент, подключенный напрямую) [peer] : public-server1
  • домашний-сервер (клиент находится за NAT) [пир] : публичный-сервер1, публичный-сервер2
  • ноутбук (клиент за NAT) [пир] : public-server1, public-server2
  • телефон (клиент за NAT) [пир] : public-server1, public-server2

Пример конфигурации:

  • Пир — это маршрутизируемый клиент, который направляет трафик только для себя.
    [Вглядеться]
    # Имя = public-server2.example-vpn.dev
    Конечная точка = public-server2.example-vpn.dev:51820
    Открытый ключ =
    Разрешенные IP-адреса = 192.0.2.2/32
  • Пир — это клиент за NAT, который маршрутизирует трафик только для себя.
    [Вглядеться]
    # Имя = домашний-сервер.пример-vpn.dev
    Конечная точка = домашний-сервер.пример-vpn.dev:51820
    Открытый ключ =
    Разрешенные IP-адреса = 192.0.2.3/32
  • Одноранговый узел — это ретрансляционный сервер, который пересылает трафик другим одноранговым узлам.
    [Вглядеться]
    # Имя = public-server1.example-vpn.tld
    Конечная точка = public-server1.example-vpn.tld:51820
    Открытый ключ =
    # маршрутизирует трафик для всей подсети VPN
    Разрешенные IP-адреса = 192.0.2.1/24
    PersistentKeepalive = 25

① Конечная точка

Указывает публичный сетевой адрес удалённого узла. Если узел находится за NAT или не имеет постоянного публичного сетевого адреса, это поле игнорируется. Обычно используется толькоРелейный серверКонечно, можно указать и конечные точки — узлы со стабильным публичным IP-адресом. Например:

  • Укажите по IP:
    Конечная точка = 123.124.125.126:51820
  • Укажите по доменному имени:
    Конечная точка = public-server1.example-vpn.tld:51820

② Разрешенные IP-адреса

Диапазон адресов источника, разрешённый для VPN-трафика от этого однорангового узла. Это поле также служит диапазоном IP-адресов, привязанным к wg0 в локальной таблице маршрутизации. Если одноранговый узел — обычный клиент, укажите здесь единственный IP-адрес узла; если одноранговый узел — сервер-ретранслятор, укажите здесь диапазон маршрутизируемых подсетей. Несколько IP-адресов или диапазонов подсетей можно указать с помощью ,. Это поле также можно указать несколько раз.

При выборе маршрута для пакета система сначала ищет наиболее точный маршрут, и если он не совпадает, ищет более общий. Например, для пакета, предназначенного для 192.0.2.3, система сначала ищет одноранговый узел с адресом в диапазоне 192.0.2.3/32. Если и этот маршрут не совпадает, система ищет одноранговый узел с адресом в диапазоне 192.0.2.3/32 и так далее.

Например:

  • Пир — это обычный клиент, который маршрутизирует только свой собственный трафик:
    Разрешенные IP-адреса = 192.0.2.3/32
  • Одноранговый узел — это ретрансляционный сервер, который пересылает трафик другим одноранговым узлам:
    Разрешенные IP-адреса = 192.0.2.1/24
  • Узел-ретранслятор — это сервер-ретранслятор, который перенаправляет весь трафик, включая внешний и VPN-трафик. Вы знаете, для чего он может быть использован:
    Разрешенные IP-адреса = 0.0.0.0/0,::/0
  • Одноранговый узел — это ретрансляционный сервер, который маршрутизирует трафик между собой и другими одноранговыми узлами:
    Разрешенные IP-адреса = 192.0.2.3/32,192.0.2.4/32
  • Одноранговый узел — это ретрансляционный сервер, который маршрутизирует свой собственный трафик и трафик интрасети, в которой он находится:
    Разрешенные IP-адреса = 192.0.2.3/32,192.168.1.1/24

③ Открытый ключ

Открытый ключ однорангового узла. Все узлы (включая ретрансляторы) должны его установить. Этот же открытый ключ можно использовать совместно с другими одноранговыми узлами.

Открытый ключ можно получить командой wg pubkey < пример.ключ > example.key.pub , где example.key — это закрытый ключ, сгенерированный выше.

Например: PublicKey = somePublicKeyAbcdAbcdAbcdAbcd=

④ Постоянный Keepalive

Если соединение установлено от однорангового узла за NAT к одноранговому узлу, доступному в публичной сети, одноранговый узел за NAT должен периодически отправлять исходящий ping-пакет для проверки соединения и автоматического обновления конечной точки при изменении IP-адреса.

Например:

  • Локальный узел напрямую подключен к одноранговому узлу: это поле не нужно указывать, поскольку проверка соединения не требуется.
  • Узел находится за NAT: это поле указывать не нужно, так как поддержание соединения является обязанностью клиента (инициатора соединения).
  • Локальный узел находится за NAT, а одноранговый узел доступен в публичной сети: Вам необходимо указать поле PersistentKeepalive = 25, что означает, что ping будет отправляться каждые 25 секунд для проверки соединения.

3. Расширенные функции

IPv6

Хотя в предыдущих примерах в основном использовался IPv4, WireGuard также поддерживает IPv6. Например:

[Интерфейс]
AllowedIps = 192.0.2.3/24, 2001:DB8::/64

[Вглядеться]
...
Разрешенные IP-адреса = 0.0.0.0/0, ::/0

Переадресация всего трафика

Если вы хотите перенаправить весь трафик через VPN, включая трафик подсети VPN и публичной сети, вам необходимо добавить 0.0.0.0/0, ::/0 к AllowedIPs [Peer].

Даже если вы перенаправляете только трафик IPv4, вам следует указать сегмент сети IPv6, чтобы избежать утечки пакетов IPv6 за пределы VPN. Подробнее см. на сайте: reddit.com/r/WireGuard/comments/b0m5g2/ipv6_leaks_psa_for_anyone_here_using_wireguard_to.[5]

Например:

[Интерфейс]
# Имя = phone.example-vpn.dev
Адрес = 192.0.2.3/32
PrivateKey =

[Вглядеться]
# Имя = public-server1.example-vpn.dev
Открытый ключ =
Конечная точка = public-server1.example-vpn.dev:51820
Разрешенные IP-адреса = 0.0.0.0/0, ::/0

Как правило, переадресация всего трафика требуется только при использовании VPN в качестве лестницы на Удан. На этом я, пожалуй, остановлюсь.

Соединения NAT-NAT

Если два одноранговых узла находятся за NAT и хотят подключиться напрямую, без использования сервера ретрансляции, вам необходимо убедиться, что по крайней мере один из одноранговых узлов имеет стабильный выход в публичную сеть, используя либо статический публичный IP-адрес, либо динамически обновляя полное доменное имя через DDNS.

Протокол WebRTC может динамически настраивать соединения между двумя NAT, используя сигнальный сервер для определения комбинации IP-адреса и порта каждого хоста. WireGuard, с другой стороны, лишен этой возможности. В нём нет сигнального сервера для динамического поиска других хостов, и вместо этого он использует жёстко заданные параметры Endpoint+ListenPort и постоянные пакеты keepalive для поддержания соединений.

Подведем итог предварительным условиям для соединений NAT-NAT:

  • По крайней мере один одноранговый узел имеет фиксированный публичный IP-адрес. Если ни у одного из них нет фиксированного публичного IP-адреса, вы также можете использовать DDNS для поддержания стабильного доменного имени.
  • По крайней мере один одноранговый узел указывает UDP ListenPort, и его NAT-маршрутизатор не может выполнять рандомизацию исходного порта UDP, в противном случае ответный пакет будет отправлен на ранее указанный ListenPort и отброшен маршрутизатором и не будет отправлен на вновь назначенный случайный порт.
  • Все одноранговые узлы должны включить PersistentKeepalive на других одноранговых узлах в конфигурации [Peer], чтобы соединения могли сохраняться.

Для обеих сторон в общении, при условии, чтоСерверЕсли маршрутизатор NAT не указывает правила пересылки на одноранговый узел за NAT, требуется пробивка UDP-пакетов.

Принцип пробивки отверстий УДП:

  1. Узел Peer1 отправляет UDP-пакет данных узлу Peer2, но NAT-маршрутизатор узла Peer2 не знает, кому отправить этот пакет, и сразу его отбрасывает. Но это неважно. Цель этого шага — позволить NAT-маршрутизатору узла Peer1 получить UDP-ответ и позже переслать его узлу Peer1.
  2. Peer2 отправляет UDP-пакет данных Peer1. Благодаря предыдущему шагу NAT-маршрутизатор Peer1 установил временное правило пересылки и может принимать UDP-ответы. Следовательно, он может получить пакет данных и переслать его Peer1.
  3. Узел 1 отправляет UDP-ответ узлу 2. Благодаря предыдущему шагу NAT-маршрутизатор узла 2 уже может принимать UDP-ответы, поэтому он может принять пакет данных и переслать его узлу 2.

Этот процесс отправки начального пакета, его отклонения и последующего использования установленных правил пересылки маршрутизатора для получения ответа называется «прокалыванием UDP».

При отправке UDP-пакета маршрутизатор обычно создаёт временное сопоставление между адресом/портом источника и адресом/портом назначения, и наоборот. UDP-пакеты, возвращаемые с адреса и порта назначения, пересылаются обратно на исходный адрес и порт источника. Именно так работают большинство UDP-приложений (например, BitTorrent и Skype) за NAT. Действие этого временного сопоставления прекращается через определённое время, поэтому клиенты за NAT должны периодически отправлять пакеты PersistentKeepalive для поддержания постоянного соединения.

Когда два одноранговых узла находятся за NAT, для работы функции UDP-дырока необходимо, чтобы два узла отправляли друг другу пакеты примерно в одно и то же время. Это означает, что обе стороны должны заранее знать публичный сетевой адрес и номер порта друг друга, которые можно указать в файле wg0.conf.

Ограничения перфорации UDP

С 2019 года многие устаревшие методы пробивания отверстий больше не эффективны.[6] Новый метод дырокола, впервые разработанный NAT, позволяет организовать P2P-соединение в NAT без необходимости использования прокси-серверов, сторонних серверов, UPnP, DMZ, защиты и преобразования DNS. Принцип его работы также очень прост:

Эта проблема решается тем, что клиент имитирует случайный ICMP-трафик в Интернете, позволяя серверу получить его IP-адрес. Команда traceroute также использует этот метод для обнаружения переходов в Интернете.

В частности, когда сервер запускается, он начинает отправлять фиксированные Пакет эхо-запроса ICMP(пакеты эхо-запросов ICMP). Очевидно, мы не можем получить ответ от 3.3.3.3. Эхо-пакеты ICMP(Эхо-пакеты ICMP). Однако 3.3.3.3 — это не хост, к которому мы можем получить доступ, и мы не собираемся выдавать себя за него для отправки эхо-пакетов ICMP. Принцип технологии pwnat заключается в том, что когда наш клиент хочет подключиться к серверу, он (зная IP-адрес сервера) отправляет серверу эхо-пакет ICMP. Пакеты ICMP с превышением времени(пакет ICMP Time Exceeded). Этот пакет ICMP содержит исходный фиксированный Пакет эхо-запроса ICMP.

Зачем это делать? Ну, мы притворяемся ICMP-трафиком в Интернете и вежливо сообщаем серверу, что изначально Пакет эхо-запроса ICMPНевозможно перейти на 3.3.3.3. А ваш NAT — умное устройство, оно заметит. Пакеты ICMP с превышением времениПакеты данных на сервере отправляются Пакет эхо-запроса ICMPТогда это будет Пакеты ICMP с превышением времениПересылается обратно на сервер за NAT, включая полный заголовок IP-пакета от клиента, чтобы сервер знал IP-адрес клиента!

В настоящее время этот метод перфорации UDP-отверстий имеет множество ограничений. Подробнее см.Предыдущая статьяПомимо пробоя UDP, мы также можем использовать жёстко заданные методы для указания публичных сетевых адресов и номеров портов двух одноранговых узлов. Этот метод эффективен для большинства сетей NAT.

Рандомизация исходного порта

Если все одноранговые узлы находятся за NAT со строгой рандомизацией исходного порта UDP (как в большинстве сотовых сетей), соединения NAT-NAT невозможны. Поскольку ни одна из сторон не может согласовать ListenPort и гарантировать, что её NAT получит трафик, предназначенный для этого порта, после отправки ping-пакета, инициирование дырок в сети невозможно, что приводит к сбою соединения. Следовательно, p2p-соединение, как правило, недоступно в сетях LTE/3G.

Использование сигнального сервера

Как упоминалось в предыдущем разделе, если все одноранговые узлы находятся за NAT со строгой рандомизацией исходных портов UDP, прямые соединения NAT-NAT невозможны. Однако это возможно с помощью стороннего сервера сигнализации. Сервер сигнализации действует как ретранслятор, предоставляя каждой стороне информацию об IP-адресе и порте другой стороны. Вот несколько проектов, на которые вы можете ссылаться:

  • Такутакахаси / wg-connect[7]
  • git.zx2c4.com/wireguard-tools/tree/contrib/nat-hole-punching[8]

Динамический IP-адрес

WireGuard разрешает доменные имена только при запуске. Если вы используете DDNS для динамического обновления разрешения доменных имён, вам потребуется перезапускать WireGuard при каждом изменении IP-адреса. В настоящее время рекомендуемое решение — использовать хук PostUp для перезапуска WireGuard каждые несколько минут или часов для принудительного разрешения доменных имён.

В целом, соединения NAT-NAT крайне нестабильны и имеют множество других ограничений, поэтому рекомендуется осуществлять связь через сервер-ретранслятор.

Пример конфигурации NAT-to-NAT:

Узел1:

[Интерфейс]
...
ListenPort = 12000

[Вглядеться]
...
Конечная точка = peer2.example-vpn.dev:12000
PersistentKeepalive = 25

Peer2:

[Интерфейс]
...
ListenPort = 12000

[Вглядеться]
...
Конечная точка = peer1.example-vpn.dev:12000
PersistentKeepalive = 25

Дополнительная информация:

  • samyk/pwnat[9]
  • en.wikipedia.org/wiki/UDP_hole_punching[10]
  • stackoverflow.com/questions/8892142/udp-hole-punching-algorithm[11]
  • stackoverflow.com/questions/12359502/udp-hole-punching-not-going-through-on-3g[12]
  • stackoverflow.com/questions/11819349/udp-hole-punching-not-possible-with-mobile-provider[13]
  • WireGuard/WireGuard@владелец/contrib/examples/nat-hole-punching[14]
  • staaldraad.github.io/2017/04/17/nat-to-nat-with-wireguard[15]
  • golb.hplar.ch/2019/01/expose-server-vpn.html[16]

Динамически выделять IP-адрес подсети

Это относится к динамическому распределению IP-адресов подсети VPN одноранговых узлов, аналогично DHCP, а не конечной точке.

WireGuard официально разрабатывает функцию динамического выделения IP-адресов подсетей. Конкретную реализацию можно увидеть здесь: WireGuard/wg-dynamic.[17]

Конечно, вы также можете использовать PostUp для чтения значения IP-адреса из файла во время выполнения, чтобы реализовать систему динамического распределения IP-адресов, аналогичную плагину Kubernetes CNI. Например:

[Интерфейс]
...
PostUp = wg set %i allowed-ips /etc/wireguard/wg0.key <(some command)

Практические советы

Поделитесь файлом peers.conf

Мы добавили секретную функцию, упрощающую настройку WireGuard. Если открытый ключ пира совпадает с закрытым ключом локального интерфейса, WireGuard проигнорирует этот пир. Эта функция позволяет использовать общий список пиров для всех узлов, поэтому каждому узлу достаточно указать отдельный [Interface]. Даже если узел есть в списке, он будет проигнорирован. Вот как это сделать:

  • Каждый одноранговый узел имеет отдельный файл /etc/wireguard/wg0.conf, содержащий только конфигурацию раздела [Interface].
  • Каждый одноранговый узел (пир) использует один и тот же файл /etc/wireguard/peers.conf, который содержит информацию обо всех одноранговых узлах.
  • Хук PostUp необходимо настроить в файле Wg0.conf с содержимым PostUp = wg addconf /etc/wireguard/peers.conf.

Существует множество способов поделиться файлом peers.conf. Вы можете распространять его с помощью таких инструментов, как Ansible, синхронизировать с помощью сетевого диска, например Dropbox, или монтировать на разных узлах, используя распределённую файловую систему, например Ceph.

Чтение конфигурации из файла или вывод команды

WireGuard также может считывать содержимое выходных данных любой команды или файла для изменения значения конфигурации. Эту функцию можно использовать для упрощения управления ключами. Например, ключи можно считывать из сторонних сервисов, таких как Kubernetes Secrets или AWS KMS, во время выполнения.

Контейнеризация

WireGuard также можно запустить в контейнере. Проще всего использовать параметры --privileged и --cap-add=all, чтобы разрешить контейнеру загружать модули ядра.

Вы можете запустить WireGuard в контейнере и предоставить сетевой интерфейс хосту; вы также можете запустить WireGuard на хосте и предоставить интерфейс определенному контейнеру.

В следующем примере показан контейнер vpn_test, который направляет весь трафик через сервер-ретранслятор WireGuard. Конфигурация контейнера, показанная в этом примере, представлена в формате файла конфигурации Docker Compose.

Конфигурация контейнера сервера ретрансляции:

версия: '3'

услуги:
защитная решетка:
изображение: linuxserver/wireguard
порты:
- 51820:51820/udp
cap_add:
-NET_ADMIN
-SYS_MODULE
тома:
- /lib/modules:/lib/modules
- ./wg0.conf:/config/wg0.conf:ro

Конфигурация WireGuard сервера ретрансляции wg0.conf:

[Интерфейс]
# Имя = relay1.wg.example.com
Адрес = 192.0.2.1/24
ListenPort = 51820
PrivateKey = oJpRt2Oq27vIB5/UVb7BRqCwad2YMReQgH5tlxz8YmI=
DNS = 1.1.1.1,8.8.8.8
PostUp = iptables -A ПЕРЕНАПРАВЛЕНИЕ -i wg0 -j ПРИНЯТЬ; iptables -t nat -A ПОСТРОУТИНГ -o eth0 -j МАСКАРАД; ip6tables -A ПЕРЕНАПРАВЛЕНИЕ -i wg0 -j ПРИНЯТЬ; ip6tables -t nat -A ПОСТРОУТИНГ -o eth0 -j МАСКАРАД
PostDown = iptables -D ПЕРЕНАПРАВЛЕНИЕ -i wg0 -j ПРИНЯТЬ; iptables -t nat -D ПОСТРОУТИНГ -o eth0 -j МАСКАРАД; ip6tables -D ПЕРЕНАПРАВЛЕНИЕ -i wg0 -j ПРИНЯТЬ; ip6tables -t nat -D ПОСТРОУТИНГ -o eth0 -j МАСКАРАД

[Вглядеться]
Имя # = peer1.wg.example.com
PublicKey = I+hXRAJOG/UE2IQvIHsou2zTgkUyPve2pzvHTnd/2Gg=
Разрешенные IP-адреса = 192.0.2.2/32

Конфигурация клиентского контейнера:

версия: '3'

услуги:
защитная решетка:
изображение: linuxserver/wireguard
cap_add:
-NET_ADMIN
-SYS_MODULE
тома:
- /lib/modules:/lib/modules
- ./wg0.conf:/config/wg0.conf:ro

vpn_test:
изображение: curlimages/curl
точка входа: curl -s http://whatismyip.akamai.com/
сетевой_режим: 'service:wireguard'

Конфигурация WireGuard на стороне клиента wg0.conf:

[Интерфейс]
Имя # = peer1.wg.example.com
Адрес = 192.0.2.2/32
PrivateKey = YCW76edD4W7nZrPbWZxPZhcs32CsBLIi1sEhsV/sgk8=
DNS = 1.1.1.1,8.8.8.8

[Вглядеться]
# Имя = relay1.wg.example.com
Конечная точка = relay1.wg.example.com:51820
PublicKey = zJNKewtL3gcHdG62V3GaBkErFtapJWsAx+2um0c0B1s=
Разрешенные IP-адреса = 192.0.2.1/24,0.0.0.0/0
PersistentKeepalive = 21

счет

Ответить

Ваш адрес электронной почты не будет опубликован. Обязательные поля помечены *