WireGuard

Материал из ALT Linux Wiki

'

Настройка через systemd-networkd

Запускать ваергарда в связке с systemd-networkd под Альтом проще, чем во многих других дистрибутивах.

Сервер

Дальнейшее можно делать на любом лине (будь то железный комп, виртуалка или контейнер) вне зависимости от роли — сервер это, рабочая лошадка или гей-приставка.

Чтобы всё это управлялось не доп.утилитами, а непосредственно сервисом systemd-networkd, данный сервис следует установить и запустить (см. статью), а пакеты etcnet (касается только альта) — отодвинуть (см. ту же статью) либо снести:

# apt-get remove -y `rpm -qa --qf "%{NAME}\n" etcnet*`

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

# wg genkey
IA/6UzzmOWh2XceaQO3GfIsCOiuchlK4xTRhUo0ktFc=

# echo "IA/6UzzmOWh2XceaQO3GfIsCOiuchlK4xTRhUo0ktFc=" | wg pubkey
s08w+USNyEP7h2rF9RCGxn4YoekLKGgIX9g2AV955FQ=
Внимание: Ключ приведён в качестве примера — не придумайте им пользоваться, плодите собственные! :)

Теперь состряпаем пару файлов, где этими хэшами и воспользуемся:

/etc/systemd/network/wg.netdev
[NetDev]
Name        = wg
Kind        = wireguard

# Сервер
[WireGuard]
ListenPort  = 51820
PrivateKey  = IA/6UzzmOWh2XceaQO3GfIsCOiuchlK4xTRhUo0ktFc=

# Клиент, которых можно наплодить ощутимо больше одного
[WireGuardPeer]
PublicKey   = s08w+USNyEP7h2rF9RCGxn4YoekLKGgIX9g2AV955FQ=
AllowedIPs  = 192.168.123.253/32,192.168.1.0/24
# Первый адрес — сам клиент, второй — его внутренняя сеть.
/etc/systemd/network/wg.network
[Match]
Name        = wg

# Адрес сервера: как для взаимодействия с клиентами, так и им между собой
[Network]
Address     = 192.168.123.254/24

# Пример маршрутизации в сеть клиента из предыдущего конфига
[Route]
Destination = 192.168.1.0/24
Gateway     = 192.168.123.254
Памятка: Простая аналогия для новичков:

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

А вот публичный больше похож на замóк, которым можно раскидываться направо-налево: расхватывайте, мол, люди добрые, цепляйте на свои двери — я в них войду!

Клиенты

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

/etc/systemd/network/cfgen-wg
#!/bin/bash

[ "$#" -gt 1 ] || {
    echo "Type 1) new key name without spaces and oversymbols and 2) device (mobile, windows or linux)!"
    exit
}
Who=$1             # имя доменной учётки клиента
What=$2            # дивайсина [windows|linux|mobile]
Conf=$Who-$What
Priv=`wg genkey`
Publ=`echo "$Priv" | wg pubkey`
Net=192.168.123    # туннельная сеть
IP=$[`cat ./# `-1] # "./#" — файл обратного отсчёта IP-адреса по последнему октету в каталоге со скриптом
echo $IP >"./#"

Content="[Peer]
PublicKey = s08w+USNyEP7h2rF9RCGxn4YoekLKGgIX9g2AV955FQ=
Endpoint = <IP или имя нашего сервера>:<порт>
PersistentKeepalive = 25
AllowedIPs = <н.а.ш.а>/<локалка>

[Interface]
PrivateKey = $Priv
Address = $Net.$IP/24
DNS = с.пи.со.к, н.а.ш.их, д.н.с.ов"

case "$What" in
    linux) # можно добавить правила фаервола — и не обязательно именно iptables
        Content+="
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"
    ;;
    mobile) # создание кукарекода из сгенерённого конфига для отправки его мобильному клиенту
        echo "$Content" | qrencode -t ansiutf8 >$Conf.qr
        cat $Conf.qr
    ;;
    *) # конфиги для компов рассылаются сотрудникам почтой, пока вручную
        echo "$Content" >$Conf.ini
esac

NewDev="
[WireGuardPeer]
# $Who, $What
AllowedIPs  = $Net.$IP/32
PublicKey   = $Publ
"
echo "$NewDev" >>../wg.netdev && {
    echo "$Net.$IP  $Who.wg" >>/etc/hosts
    systemctl daemon-reload
    systemctl reload dnsmasq
    systemctl restart systemd-networkd
}

Помимо занесения вновь сгенерированного клиента в конфиг ваергарда, он также добавляется в локальный ДНС-кэш (dnsmasq), с которого основные внутренние ДНСы запрашивают зону .wg.

Таким образом, адреса клиентов туннеля становятся видны клиентам локалки по имени.

Мониторинг

Для журналирования активности ядрёного модуля достаточно [на «железе» / в виртуалке] либо на [хост-системе / всех узлах кластера контейнеризации] с ваергардом создать юнит:

/lib/systemd/system/wg-log.service
[Unit]
Description = WireGuard events logging
ConditionPathExists = /sys/kernel/debug/dynamic_debug/control
ConditionPathIsDirectory = /sys/module/wireguard
After = network.target systemd-modules-load.service

[Service]
Type = oneshot
RemainAfterExit = yes
ExecStart = echo module wireguard +p >/sys/kernel/debug/dynamic_debug/control

[Install]
WantedBy = multi-user.target

И запустить его навсегда командой # systemctl enable --now wg-log

Отслеживать текучку по journalctl -kf | grep wg.


Ниже — не моё.

Настройка конфигом wg

Если еще нет пары частный-публичный ключ, ее нужно создать:

$ wg genkey > privatekey
$ wg pubkey < privatekey > publickey

Теперь файл privatekey в текущей папке содержит частный ключ, а файл publickey — публичный.

Установить wg-quick

# apt-get install wireguard-tools-wg-quick

Создать конфигурационный файл /etc/wireguard/wg0.conf (имя файла = имя поднятого интерфейса, в данном случае — wg0):

# mkdir /etc/wireguard
# touch /etc/wireguard/wg0.conf
# chmod -R 600 /etc/wireguard

Со следующим содержимым:

[Interface]
PrivateKey = частный ключ клиента
# IP-адрес клиента (маска всегда /32)
Address = 172.16.1.2/32

# Для клиента пиром является сервер (что взаимно)
[Peer]
PublicKey = <публичный ключ сервера>
# Подсети с другими доступными узлами, для которых клиент является маршрутизатором:
AllowedIPs = 172.16.1.0/24, 172.16.2.0/24, 192.168.1.0/24
# Реальный IP-адрес сервера с номером порта:
Endpoint = IP-адрес:51820

В конфиге сервера все клиенты должны быть указаны аналогичным образом — в качестве пиров. Да, серверу тоже нужны публичные ключи клиентов.

Запуск, останов и мониторинг соединения возможны только от рута:

# systemctl start wg-quick@wg0
# systemctl stop wg-quick@wg0
# wg show

Настройка в KDE

Для NetworkManager.

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

Запускаем приложение "Параметры системы KDE5": нажимаем Alt+F2, во всплывающем окне начинаем печатать systemsettings5, нажимаем Enter на появившемся пункте.

В приложении выбираем вкладку "Соединения" (группа "Сеть и связь"), нажимаем на "+", чтобы создать новое соединение.

Во всплывшем окне прокручиваем вниз до группы "VPN-соединения", выбираем тип "WireGuard" и нажимаем кнопку "Создать".

В окне "Новое соединение" вводим имя соединения (например, wg0, соответственно названию интерфейса). Окно открывается на вкладке "Интерфейс WireGuard", на ней в поле "личный ключ" вводим PrivateKey клиента и выбираем "Сохранить пароль только для этого пользователя (зашифрованный)".

Остальные поля можно оставить пустыми.

Далее нужно нажать на кнопку "Участники обмена..." и во вновь появившемся окне ввести данные для пира (сервера):

  • в поле "Открытый ключ" вводим PublicKey сервера,
  • в поле "Разрешенные адреса IP" вводим AllowedIPs,
  • в поля "Адрес подключения" и "Порт подключения" вводим реальный (видимый из Интернета) IP-адрес сервера с номером порта;
  • поле "Интервал отправки пакетов keepalive" соответствует опции PersistentKeepalive конфига, но не сохраняется — что и не требуется: сервер сам задаст нужный интервал.

Остальные поля не нужны. Просто жмем OK.

Переходим на вкладку "IPv4":

  • выбираем метод "Вручную",
  • жмем на кнопку "+ Добавить",
  • вводим IP-адрес клиента,
  • маску подсети (255.255.255.255 для одиночного адреса или 0.0.0.0 для шлюза),
  • ставим галку "Для этого соединения требуется IPv4".

На вкладке "IPv6" в методе ставим "Отключено" (если, конечно, не используете этот протокол).

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

Жмем "Сохранить". Теперь соединение можно подключать и отключать из иконки сетевых соединений в системном лотке.

Чтобы увидеть результат настроек в едином конфиг-файле, можно использовать команду (замените wg0 на имя вашего соединения):

# wg showconf wg0

Соединение должно быть активно.

Обратная связь