WireGuard, настройка нескольких клиентов за NAT и причем здесь STUN?

от автора

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

Сначала, о преимуществах WireGuard и обратной стороне медали, о сложностях, которые возникают вместе с преимуществами. WireGuard достаточно молодая реализация туннеля между двумя точками, как протокол передачи используется UDP. Именно поэтому и еще потому, что сама реализация в Linux выполнена в виде модуля ядра, тесты показывают порядочное преимущество в скорости, по отношению к конкурентам. Пиринговой сетью это считать нельзя, хотя конечные узлы и называются Peer. Суть пиринговой сети не только в том, что бы можно было соединить два произвольных узла. Конечно же на данном инструментарии, можно построить весьма замысловатую сетевую инфраструктуру, но у меня такой цели не стоит. Мы рассмотрим подключение к серверному узлу и выход посредством него в интернет.

Очевидно, что если два узла, сервер и один клиент имеют белые IP, в этом случае не должно возникать никаких сложностей в настройке. Но часто клиенты находятся за NAT и в этом случае при настройке сервера необходимо указывать совсем не тот IP адрес, который выдан/прописан на устройстве. В этом отношении, может помочь STUN протокол. Этот протокол, часто используется при работе VoIP, особенно, когда оба клиента находятся за NAT. Но в нашем случае он тоже поможет. Судя из информации в википедии, STUN работает не со всеми типами NAT, в одном из 4 типов NAT (симметричный) клиент может иметь другой IP, чем тот, что может быть определен снаружи с помощью STUN клиента.

Клиенты STUN, существуют на всех популярных операционных системах, кроме iOS. Под эту операционную систему, STUN клиент мне найти не удалось. Пример я приведу для macOS. Для начала, необходимо установить сам STUN клиент.

$ brew install stunman

В интернете существует масса STUN серверов и не сложно в поиске найти любой сервер для теста. Я буду использовать stun.ekiga.net. Для теста необходимо будет использовать локальный порт, тот который мы будем использовать для настройки:

$ stunclient --localport 51820 stun.ekiga.net

При удачном тесте мы получим, примерно такой вывод:

Binding test: success Local address: 192.168.88.23:51820 Mapped address: 82.207.27.3:51820

Mapped address это именно тот IP, который необходимо будет использовать при настройке сервера. На самом деле, это тот IP адрес, который в моем случае выдаст любой сервис по определению внешнего IP. Поэтому можно воспользоваться вашим любимым сервисом по определению IP, но конечно, стоит учитывать, что этот тест будет косвенным и гарантии никакой нет, что все будет работать так как задумывалось.

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

На Linux, это можно сделать из командной строки, на macOS — через UI официального клиента.

$ wg genkey | tee privatekey | wg pubkey > publickey

В данном случае по месту вызова приватный ключ будет создан в файле privatekey, публичный в в publickey соответственно.

Первым рассмотрим клиентский конфиг:

# В начале секция описывающая локальный интерфейс [Interface]  # Приватный ключ должен оставаться в секрете PrivateKey = YPuKo2QXndQ2Vc3S/y90oKT7AJ0Swhq/HWKiF7GwS04=  # Порт нужно согласовать и использовать на стороне сервера ListenPort = 51820  # Это IP адрес локальной сети, по которому сервер вас будет идентифицировать и  # выпускать в сеть Address = 10.8.0.2/24  # DNS может быть несколько, их можно перечислить через запятую DNS = 8.8.8.8   # Далее информация о сервере [Peer]  # Это публичный ключ, который получен от сервера PublicKey = nFjDIkgsAh1RMZuaCJ+AKs7JmbMxxthhZ0POjUSTvkc=  # Следующая опция может вызвать споры, так как условно верным является указание # IP адреса сервера, но так как кроме всего прочего эта настройка автоматически  # клиентом прописывается в таблицу маршрутизации, то это самый простой способ  # перенаправить весь трафик в WireGuard интерфейс. IP может быть несколько,  # перечисляются через запятую. AllowedIPs = 0.0.0.0/0  # Это IP и порт сервера Endpoint = 46.101.122.130:51820  # Существуют 2 подхода. Первый - быть как можно тише, тогда эту настройку нужно убрать, # но тогда и AllowedIPs в текущем варианте настройки нужно изменить и вручную # настраивать таблицу маршрутизации. Второй - посылать пакеты для поддержания  # соединения, в документации рекомендуется - каждые 25 секунд. PersistentKeepalive = 25 

Теперь пришло время серверного конфига:

# В начале секция описывающая локальный интерфейс [Interface]  # IP адрес сервера в локальной сети Address = 10.8.0.1/24  # Порт со стороны сервера ListenPort = 51820  # Приватный ключ, должен сохраняться в строжайшем секрете PrivateKey = MNnxOy79xtXtSQ3UySWtdlOMbG7ff9dXGjeSTPEByn8=  # Далее 2 обработчика, в момент поднятия и опускания wg0 интерфейса PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE   # Далее секция описывающая клиента [Peer]  # Это публичный ключ, полученный от клиента PublicKey = TdRtYd6XXI+ynPDXU6FF5TT3L5t/YlQVZswr2xsou34=  # Далее согласованный IP клиента, если он не будет совпадать,  # туннель не будет функционировать AllowedIPs = 10.8.0.2/32  # Внешний IP клиента, как раз тот, что мы получили через STUN клиент EndPoint = 82.207.27.3:51820

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

Для настройки я пользовался следующими ресурсами: официальным сайтом, ArchWiki и вот этим туториалом.

В конце, я хотел бы также прояснить пару возможных вопросов:

1. Можно ли на сервере сделать несколько секций одинаковых Peer, которые будут отличаться только EndPoint?

Да можно, и это даже может быть полезно в том случае, когда вы пользуетесь сервисом из разных мест, к примеру, на работе и дома. Но проблемы могут возникнуть если такие Peer, выйдут в онлайн одновременно, в этом случае будет конфликт IP адресов.

2. Какой внешний IP и порт будет определяться по STUN протоколу для нескольких клиентов за NAT?

Один и тот же для всех клиентов, он будет одинаковый. Будет ли это проблемой? Это все зависит от настроек вашего провайдера/роутера, но принципиально проблемы возникать не должны, так как роутер должен широковещательно ретранслировать UDP пакеты внутри сети по маске локальной сети, соответственно те принимающие стороны, которые смогут расшифровать пакеты, должны их успешно принимать. Мы проводили тесты, на нашем оборудовании, тесты прошли успешно.

Целью статьи не было написать полный туториал как настроить WireGuard, это не сложно сделать воспользовавшись официальной документацией. Мы хотели показать, как WireGuard может работать за NAT.

Если вы хотите попробовать WireGuard в деле, вы можете обратиться к нам, у нас есть доступ в тестовом режиме.


ссылка на оригинал статьи https://habr.com/ru/post/481838/


Комментарии

Добавить комментарий

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