WireGuard

WireGuard — инструмент для построения виртуальных сетей. Многие называют его этаким «VPN нового поколения». Он включен в состав ядра, начиная с версии 5.6.

Заметка обновлена 27.02.2020.

В рамках этой заметки, мы запустим в работу простой WireGuard VPN сервер и настроим подключение из Linux клиента к нему. Работать мы будем в CentOS 8, но инструкция вполне подойдёт и для других дистрибутивов, разве что пакетные менеджеры и репозитории будут отличаться.

wireguard

Сервер wireguard.

Подготовка и установка.

1. Для начала, подключаем репозитории EPEL и RPMFusion Free. Cтавим доступные обновления и запускаем систему с новым ядром.

# dnf install epel-release
# dnf install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
# dnf clean all; dnf update;
# reboot

2. Далее, ставим на сервер всё необходимое и собираем модуль для Wireguard. После, убеждаемся, что модуль запущен в работу:

# dnf install akmod-wireguard wireguard
# akmods --force
# modprobe wireguard && lsmod | grep wireguard

Вывод последней команды будет примерно таким:

# modprobe wireguard && lsmod | grep wireguard
wireguard 229376 0
ip6_udp_tunnel 16384 1 wireguard
udp_tunnel 16384 1 wireguard

Настройка сервера.

3. Генерируем ключи для клиента и сервера:

# mkdir ~/wireguard; cd ~/wireguard
# wg genkey | tee server_private_key | wg pubkey > server_public_key
# wg genkey | tee client_private_key | wg pubkey > client_public_key
# chmod 600 ./*_private_key

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

4. Создаём конфигурационный файл для сервера /etc/wireguard/wg0.conf со следующим содержимым:

[Interface]
Address = 10.8.0.1/24
PrivateKey = SERVER_PRIVATE_KEY
ListenPort = 35053

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32

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

Address — адрес виртуального интерфейса wg0 на сервере.
ListenPort — порт, на котором будет работать VPN.
AllowedIPs — виртуальные IP клиентов, которые будут подключаться к нашему серверу.

При необходимости, мы можем так же указать параметры PostUp и PostDown — команды, которые будут выполнены при включении и отключении интерфейса.

5. Включаем форвардинг пакетов:

# cat /etc/sysctl.conf 
net.ipv4.ip_forward = 1
# sysctl -p

6. Настраиваем фаервол:

# firewall-cmd --permanent --zone=public --add-port=35053/udp
# firewall-cmd --permanent --zone=public --add-masquerade
# firewall-cmd --reload

7. Запускаем сервис в работу:

# systemctl enable wg-quick@wg0.service
# systemctl restart wg-quick@wg0.service

Клиент wireguard.

Пишем конфиг.

8. На основе сделанной настройки, пишем простой конфиг для клиента. Этот конфиг подойдёт и для десктопа, и для, например, android приложения:

[Interface]
Address = 10.8.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0
Endpoint = SERVER_REAL_IP:35053
PersistentKeepalive = 20

В данном случае, вместо CLIENT_PRIVATE_KEY и SERVER_PUBLIC_KEY мы опять же, подставляем ключи, сгенерированные ранее, а вместо SERVER_REAL_IP прописываем IP адрес нашего сервера, на котором установлен VPN.

Wireguard и десктоп клиент.

— Создаём директорию /etc/wireguard, а в ней сохраняем наш конфигурационный файл под именем wg0-client.conf.
— Пробуем подключиться к серверу с помощью wg-quick:

# wg-quick up wg0-client

[#] ip link add wg0-client type wireguard
[#] wg setconf wg0-client /dev/fd/63
[#] ip address add 10.8.0.2/32 dev wg0-client
[#] ip link set mtu 1420 dev wg0-client
[#] ip link set wg0-client up
[#] mount `8.8.8.8' /etc/resolv.conf
[#] wg set wg0-client fwmark 35053
[#] ip -4 route add 0.0.0.0/0 dev wg0-client table 35053
[#] ip -4 rule add not fwmark 35053 table 35053
[#] ip -4 rule add table main suppress_prefixlength 0

Проверяем подключение, и если всё сделано верно, то весь наш трафик теперь будет проходить через VPN сервер.

Для отключения от VPN просто выполняем команду wg-quick down wg0-client:

# wg-quick down wg0-client

[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip link delete dev wg0-client
[#] umount /etc/resolv.conf

При необходимости, мы можем управлять сервисом через systemd:

# systemctl restart wg-quick@wg0-client.service

Wireguard на android.

Для использоания wireguard на android, достаточно скачать клиента из Play Market или из F-Droid репозитория, а для подключения просто выполнить импорт подготовленного wg конфига для клиента.

wireguard

И, собственно, всё. Вот так, очень просто (куда проще чем тот же OpenVPN) мы можем настроить защищённый VPN туннель и использовать его в повседневной работе.

Дополнительно.

Быстрая установка.

wireguard-manager — инструмент для быстрой установки и настройки Wireguard на сервере.
wireguard-install — ещё одна реализация быстрого установщика.

Использование iptables.

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

[Interface]
Address = 10.8.0.1/24
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 35053
PrivateKey = SERVER_PRIVATE_KEY

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
Несколько клиентов.

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

[Interface]
Address = 10.8.0.1/24
PrivateKey = SERVER_PRIVATE_KEY
ListenPort = 35053

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32

[Peer]
PublicKey = ANOTHER_CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.3/32
Просто, для истории.

В дополнение — на видео ещё один пример быстрой настройки WireGuard, но уже вручную:

20 thoughts on “WireGuard

  1. Буквально с месяц назад пробовал, понравилось. НО всегда есть одно «но»:
    Не могу повесить несколько клиентов на один интерфейс сервера, работает по принципу «кто ПЕРВЫЙ встал того и тапки». остальные подключаются но с сетью не работают, даже сервер не пингуют, не говоря уже о том чтобы между собой по ssh гулять или ещё что. Может ты подскажешь как это исправить?

    1. Хм, как появится время — протестирую это дело и отпишусь либо тут, либо как-то в отдельной заметке.

    1. Более производительный. На роутере где tinc загибался под 10 мегабитами, wireguard 80-90 давал.

      1. Потому что в офисной сетке нашей например UDP вообще зарезан. А вот OpenVPN по TCP на 443-й порт прекрасно работает.

  2. Возможно ли с помощью WireGuard создать VPN между
    точкой с реальным IP адресом и точкой без реального IP адреса ( роутер+OpenWRT+3G/4G internet)? При этом требуется доступ к компьютерам, находящимся за роутером с OpenWRT.

  3. Не получилось подключиться. Всё сделал по инструкции.
    wg-quick up wg0-client
    Warning: `/etc/wireguard/wg0-client.conf’ is world accessible
    [#] ip link add wg0-client type wireguard
    [#] wg setconf wg0-client /dev/fd/63
    [#] ip -4 address add 10.8.0.2/32 dev wg0-client
    [#] ip link set mtu 1420 up dev wg0-client
    [#] mount `8.8.8.8′ /etc/resolv.conf
    Error: ipv6: FIB table does not exist.
    Dump terminated
    [#] wg set wg0-client fwmark 51820
    [#] ip -4 route add 0.0.0.0/0 dev wg0-client table 51820
    [#] ip -4 rule add not fwmark 51820 table 51820
    [#] ip -4 rule add table main suppress_prefixlength 0

    Возможно неправильно указываю -> Endpoint = SERVER_REAL_IP:51820

    Пробывал разные внешние сервисы, но не получилось.
    Что не так? Где смотреть?

  4. У WireGuard есть одна большая проблема — если по какой-то причине отваливается сервер, то клиент всё равно пытается посылать трафик в несуществующий тоннель. Для мобилки это даже хорошо — мы уверены в том, что наше соединение защищено. Но если я использую WireGuard для подключения удалённой точки, то даже3если на этой точке есть интернет, но нет коннекта с WireGuard сервером (например, инстанс на DO попал в чёрный список), то эта точка остаётся без связи вообще до тех пор, пока не подключится снова к WireGuard или кто-то там далеко на точке не остановить wireguard клиента.

    Вы пробовали делать настройки, чтобы default gateway поднимался только после установления соединения?

    1. Чтобы этого не произошло, достаточно настроить Kill Switch.
      В конфиг клиента добавляем пару строк. Покажу на примере iptables в линукс:

      —————————————-CONF—————————————-

      [Interface]
      Address = 10.8.0.2/32
      PrivateKey = CLIENT_PRIVATE_KEY
      DNS = 193.138.218.74
      PostUp = iptables -I OUTPUT ! -o %i -m mark ! —mark $(wg show %i fwmark) -m addrtype ! —dst-type LOCAL -j REJECT && ip6tables -I OUTPUT ! -o %i -m mark ! —mark $(wg show %i fwmark) -m addrtype ! —dst-type LOCAL -j REJECT
      PreDown = iptables -D OUTPUT ! -o %i -m mark ! —mark $(wg show %i fwmark) -m addrtype ! —dst-type LOCAL -j REJECT && ip6tables -D OUTPUT ! -o %i -m mark ! —mark $(wg show %i fwmark) -m addrtype ! —dst-type LOCAL -j REJECT

      [Peer]
      PublicKey = SERVER_PUBLIC_KEY
      Endpoint = SERVER_REAL_IP:51820
      AllowedIPs = 0.0.0.0/0
      PersistentKeepalive = 21

      —————————————-CONF—————————————-
      Примечания к конфигу:
      — DNS — для примера указан non-logged DNS-сервер Mullvad. Лучшим решением будет указание собственного DNS.
      — PostUp и PostDown — вот тут настраиваем KillSwitch
      — CLIENT_PRIVATE_KEY и SERVER_PUBLIC_KEY — мы опять же, подставляем ключи, сгенерированные ранее,
      — SERVER_REAL_IP — прописываем IP адрес нашего сервера, на котором установлен WireGuard

  5. А как написать конфиг если у меня на серваке серый адре, на роутере белый с пробросом протов на серый и клиентом является плашет с симкой?

  6. Здравствуйте, есть VPS установил WG (192.168.2.1) так же есть debian 10 клиент 192.128.2.2 он же шлюз в локальной сети для обхода блокировок, соединение через WG с сервером установлено, как сделать так что бы был доступ в локальную сеть 192.168.1.0/24 с сервера? Не могу разобраться с маршрутом

  7. Здравствуйте, есть VPS установил WG (192.168.2.1) так же есть debian 10 клиент 192.128.2.2 он же шлюз (192.168.1.2) в локальной сети для обхода блокировок, соединение через WG с сервером установлено, как сделать так что бы был доступ в локальную сеть 192.168.1.0/24 с сервера? Не могу разобраться с маршрутом

  8. Столкнулся с не критичной проблемой:
    Несмотря на то, что мой хостинг провайдер находится в Англии, а по тестам DNS leaks мне выделили сервер во Франции, поисковики считают что я в Украине..
    Вот и думаю, где пошаманить, чтобы играться с определением геолокации

  9. Ребят, подскажите, пожалуйста, как сконфигурировать route, чтобы клиент не маршрутизировал трафик до одного конкретного айпишника? То есть чтобы трафик до этого шел напрямую на клиенте.

    в конфиге опенвпн на клиенте я просто добавлял
    route 255.255.255.255 net_gateway

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

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