Featured image of post Wireguard Ansible

Wireguard Ansible

Ansible плейбуки для развёртывания Wireguard

GitHub

Обновление от 25 ноября 2022

Перешёл на классический wg-quick с этого Ansible. Решение получилось в целом много проще технически, а по функционалу меня удовлетворяет.

Обновление от 21 марта 2022

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

Введение

Wireguard – обалденный, простой VPN, который уже включён в состав ядра. Очень мощный и простой инструмент. Ставиться в разы проще чем OpenVPN.

Постановка задачи

  • Я живу в Украине и, к сожалению, у нас заблокированы некоторые Интернет ресурсы, а доступ иногда нужен.
  • Хочется иметь возможность достучаться по удалённому доступу с телефона или чужого компьютера до домашнего сервера.
  • Хочется, чтобы на ПК проксировался трафик только на домены из списка, а не вообще всё.

Вот с такими запросами я стал работать. Для себя, всё для себя. Больше пока никому не нужен, хотя на GitHub выложил. Выложил - это тоже громко сказано. Ни документации, ничего! Да! Лень просто написать… Ну да ладно.

Обзор решения

Использовал Ansible, который может настроить сразу сеть. Что умеет:

  1. Использование константного preshared ключа для всех соединений
  2. Возможность прописывать свои AllowedIPs
  3. Возможность добавлять пиров со статически прописанными ключами (на телефоне-то Ansible не запустить)
  4. Автоматический подбор свободных rt_table ID и fwmark-ов
  5. Возможность за один запуск поднимать больше одной сети на тех же машинах!

Чего не умеет.

  1. Отдельный запуск на одном или подгруппе хостов. Только на всём сразу.

Разбираем переменные Ansible

all.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# CIDR сетей
wireguard_networks:
  home: 192.168.99.0/24
  vpn: 10.0.0.0/24
# марки для маршрутизации - для каждой сети своя
wireguard_fwmarks:
  home: 1000
  vpn: 2000
# по прешаренному ключу на сеть
wireguard_preshared_keys:
  home: longalphanum
  vpn: longalphanum
# ключи каждого сервера в каждой сети где он есть
wireguard_keys:
  home:
    public_host:
      public: longalphanum
      private: longalphanum
    home_server:
      public: longalphanum
      private: longalphanum
    laptop:
      public: longalphanum
      private: longalphanum
  vpn:
    public_host:
      public: longalphanum
      private: longalphanum
    laptop:
      public: longalphanum
      private: longalphanum
    smartphone:
      # у телефона, только публичный, так как приватный тут не нужен
      public: longalphanum
wireguard_addresses:
  # адреса каждого сервера в каждой сети
  home:
    public_host: 192.168.99.1
    laptop: 192.168.99.2
    home_server: 192.168.99.3
  vpn:
    public_host: 10.0.0.1
    laptop: 10.0.0.2
    smartphone: 10.0.0.3

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# это переменнные для отдельно взятого хоста - сервера
wireguard_enabled: yes
# wireguard-tools поставили уже, по-этому тут это выключаем
wireguard_install_tools: no
# список пиров
wireguard_peers:
  # для домашней сети
  home:
  # первый пир это наш ноутбук, на котором мы Ansible запускаем
  - name: laptop
  # а второй, имеет inventory_hostname home_server
  - name: home_server
    # и поддерживай сеть, чтобы всегда можно было достучаться,
    # потому что сервер за NAT-ом
    keepalive_seconds: 25
  # вторую сеть только с телефона и ПК использовать будем
  vpn:
  - name: laptop
  # а вот и телефон
  - name: smartphone
# ну и выберем порты, по которым он должен слушать
# для остальных можно не указывать - не важно, а вот
# для сервера лучше всё сразу прописать статикой
# чтобы ничего не было перегенерено если что
# и не нужно было перенастраивать всех клиентов
# на новые креды сервера
wireguard_ports:
  home: 2000
  vpn: 3000
# включаем маскарад, чтобы сервер через себя в Интернет
# выпускал трафик пиров как gateway
wireguard_masquarade:
  vpn: auto

А теперь укажем переменные для ноутбука, за которым работаем.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# и опять включем роль явным образом
wireguard_enabled: yes
wireguard_peers:
  vpn:
  # из пиров в сети VPN только наш публичный сервер
  - hostname: public_host
    # у нас есть домен, который указывает на сервер чтобы адрес не запоминать
    endpoint: vpn.example.com
    # направляем через VPN весь трафик, и тут важно понимать,
    # что мы не весь трафик системы пускаем через wireguard
    # мы говорим wireguard-у на хосте, что в эту сетку пускай
    # всё, что к тебе конкретно пришло на выход и не подходит
    # в другие сети по более узким правилам
    allowed_ips:
    - 0.0.0.0/0
    - ::0
    keepalive_seconds: 25
  home:
  # точкой связи для домашней сети является он же
  - hostname: public_host
    endpoint: vpn.example.com
    keepalive_seconds: 25
    allowed_ips:
    # а в путях прописываем только подсеть домашней сети
    - "{{ wireguard_networks.home }}"
# и включаем проксирование отдельных доменов через сеть VPN
wireguard_proxy_domains:
  vpn:
    list:
    - site.we.want.access
    - another.one

Ну и домашний сервер, просто должен быть доступен. В VPN ему ни к чему.

1
2
3
4
5
6
7
8
9
# тут я надеюсь уже всё понятно
wireguard_enabled: yes
wireguard_peers:
  home:
  - hostname: public_host
    endpoint: vpn.example.com
    allowed_ips:
    - "{{ wireguard_networks.home }}"
    keepalive_seconds: 25

Итог

С любого пира на любой есть доступ в пределах сети. Трафик находит свой путь через публичный сервер. Всё работает. Померял iperf-ом, из 80 Мбит, Wireguard отдаёт ~60 - как по мне, так это блестящий результат!

Licensed under Apache License, Version 2.0
Обновлено дек. 10, 2024 14:01 +0200
All rights reserved
Создано при помощи Hugo
Тема Stack, дизайн Jimmy