ansible_role_wireguard
ansible-role-wireguard
Эта роль Ansible используется в серии моих блогов Kubernetes the not so hard way with Ansible, но может быть использована и отдельно. Я использую WireGuard и эту роль Ansible для настройки полностью соединённой VPN между всеми узлами моего небольшого кластера Kubernetes.
В целом, WireGuard — это сетевой туннель (VPN) для IPv4 и IPv6, который использует UDP. Если вам нужна дополнительная информация о WireGuard, вы можете найти хорошее введение здесь: Installing WireGuard, the Modern VPN.
Linux
Эта роль должна работать с:
- Ubuntu 20.04 (Focal Fossa)
- Ubuntu 22.04 (Jammy Jellyfish)
- Ubuntu 24.04 (Noble Numbat)
- Archlinux
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
- Fedora 39
- AlmaLinux 9
- Rocky Linux 9
- openSUSE Leap 15.5
- openSUSE Leap 15.6
- Oracle Linux 9
Наилучшие усилия
- AlmaLinux 8
- Rocky Linux 8
- elementary OS 6
- CentOS 7 (выводится из эксплуатации с конца июня 2024 года)
Тесты Molecule доступны (см. ниже). Также должно работать с Raspbian Buster
, но для этого нет доступного теста. MacOS (см. ниже) также должна работать частично, но это только наилучшие усилия.
MacOS
В то время как этот плейбук настраивает, включает и запускает службу systemd
на Linux таким образом, что не требуется дополнительных действий, на MacOS он устанавливает необходимые пакеты и просто генерирует правильный файл wg0.conf
, который затем помещается в указанный wireguard_remote_directory
(по умолчанию /opt/local/etc/wireguard
). Чтобы запустить VPN, вам нужно выполнить:
sudo wg-quick up wg0
Чтобы отключить его:
sudo wg-quick down wg0
Или вы можете установить официальное приложение и импортировать файл wg0.conf
.
Версии
Я помечаю каждое релиз и стараюсь следовать семантическому версионированию. Если вы хотите использовать роль, я рекомендую проверить последний тег. Основная ветка в основном для разработки, тогда как теги отмечают стабильные релизы. Но вообще я стараюсь поддерживать основную ветку в хорошем состоянии.
Требования
По умолчанию порт 51820
(протокол UDP) должен быть доступен снаружи. Однако вы можете настроить порт, изменив переменную wireguard_port
. Также необходимо включить пересылку IP, например, с помощью echo 1 > /proc/sys/net/ipv4/ip_forward
. Я решил не реализовывать эту задачу в этой роли Ansible. По моему мнению, это должно обрабатываться в другом месте.
Вы можете использовать мой ansible-role-harden-linux и т.д. Кроме изменения записей sysctl (которые необходимы для включения пересылки IP), он также управляет настройками брандмауэра, среди прочего.
Тем не менее, крючки PreUp
, PreDown
, PostUp
и PostDown
могут быть хорошим местом для выполнения некоторых сетевых задач перед тем, как интерфейс WireGuard поднимется или упадет.
Изменения
История изменений:
Смотрите полный CHANGELOG.md
Недавние изменения:
17.0.0
СЛОМАНО
- убрана поддержка
openSUSE 15.4
(дошла до конца жизни)
- убрана поддержка
ХАРАКТЕРИСТИКА
- добавлена поддержка
Ubuntu 24.04
- добавлена поддержка
openSUSE 15.6
- добавлена поддержка
MOLECULE
- убрана устаревшая часть кода
Proxmox
- заменена Vagrant коробка
rockylinux/9
наbento/rockylinux-9
- использование
ansible.builtin.package
для AlmaLinux - убраны
AlmaLinux 8
,Rocky Linux 8
иCentOS 7
(устаревший Python усложняет тестирование с Ansible)
- убрана устаревшая часть кода
16.0.2
- ДРУГОЕ
- отменено изменение в
.github/workflows/release.yml
- отменено изменение в
16.0.1
- ДРУГОЕ
- обновлен
.github/workflows/release.yml
- обновлен
meta/main.yml
- обновлен
16.0.0
СЛОМАНО
- убрана поддержка Fedora 37/38 (дошла до конца жизни)
ХАРАКТЕРИСТИКА
- добавлена поддержка Fedora 39
- введена переменная
wireguard_conf_backup
для отслеживания изменений конфигурации. По умолчаниюfalse
. (вклад от @shk3bq4d) - введена переменная
wireguard_install_kernel_module
. Позволяет пропустить загрузку модуля ядраwireguard
. По умолчаниюtrue
(что было предыдущим поведением). (вклад от @gregorydlogan)
Molecule
- использование различных IP-адресов
- использование
generic
Vagrant boxes для Rocky Linux - использование Vagrant boxes
alvistack
для Ubuntu - использование официальной Rocky Linux 9 Vagrant box
- использование официальных AlmaLinux Vagrant boxes
- перемещение параметров
memory
иcpus
в Vagrant boxes
Установка
Загрузите напрямую с Github (перейдите в директорию роли Ansible перед клонированием):
git clone https://github.com/githubixx/ansible-role-wireguard.git githubixx.ansible_role_wireguard
Через команду
ansible-galaxy
и загрузка напрямую из Ansible Galaxy:ansible-galaxy role install githubixx.ansible_role_wireguard
Создайте файл
requirements.yml
со следующим содержимым (это загрузит роль из Github) и установите с помощьюansible-galaxy role install -r requirements.yml
:
---
roles:
- name: githubixx.ansible_role_wireguard
src: https://github.com/githubixx/ansible-role-wireguard.git
version: 17.0.0
Переменные роли
Эти переменные могут быть изменены в group_vars/
, например:
# Директория для хранения конфигурации WireGuard на удаленных хостах
wireguard_remote_directory: "/etc/wireguard" # На Linux
# wireguard_remote_directory: "/opt/local/etc/wireguard" # На MacOS
# Порт, на котором WireGuard будет слушать, если не указано иначе
wireguard_port: "51820"
# Имя интерфейса по умолчанию, которое WireGuard должен использовать, если не указано иначе
wireguard_interface: "wg0"
# Владельцем файла wg.conf по умолчанию
wireguard_conf_owner: root
# Группа файла wg.conf по умолчанию
wireguard_conf_group: "{{ 'root' if not ansible_os_family == 'Darwin' else 'wheel' }}"
# Режим файла wg.conf по умолчанию
wireguard_conf_mode: 0600
# Нужно ли делать резервную копию файла wg.conf при любом изменении
wireguard_conf_backup: false
# Статус службы wireguard по умолчанию
wireguard_service_enabled: "yes"
wireguard_service_state: "started"
# По умолчанию используется "wg syncconf", чтобы применить настройки интерфейса WireGuard, если они были изменены.
# Более старые инструменты WireGuard не предоставляют эту опцию. В этом случае, в качестве резервного варианта, интерфейс WireGuard будет перезапущен.
# Это приводит к кратковременному прерыванию сетевых соединений.
#
# Так что даже если значение по умолчанию "false", роль определяет доступность опции "syncconf"
# утилиты "wg" и, если нет, переходит к "true"
# (что означает, что интерфейс будет перезапущен, так как это единственный вариант
# в этом случае).
#
# Возможные варианты:
# - false (по умолчанию)
# - true
#
# Обе опции имеют свои плюсы и минусы. Значение по умолчанию "false" (не перезапускайте интерфейс)
# - не требует перезапуска WireGuard интерфейса для применения изменений
# - не вызывает кратковременного прерывания соединения VPN при применении изменений
# - может вызвать проблемы с перезагрузкой сетевых маршрутов
#
# Установка значения опции на "true" приведет к
# - перезапуску интерфейса WireGuard в случае изменений
# - вызовет кратковременное прерывание соединения VPN при применении изменений
# - обеспечит правильную перезагрузку сетевых маршрутов
#
# Таким образом, немного зависит от вашей настройки, какая опция работает лучше всего.
# Если у вас нет слишком сложной маршрутизации, которая изменяется очень часто или вообще
# использование "false" будет для вас вполне приемлемым, например, если вы просто
# хотите соединить несколько серверов по VPN, и это обычно остается так.
#
# Если у вас более динамичная настройка маршрутизации, установка этого параметра на "true" может быть
# самым безопасным выбором. Также, если вы хотите избежать возможности создания
# трудных для выявления побочных эффектов, эту опцию следует рассмотреть.
wireguard_interface_restart: false
# Обычно роль автоматически создает закрытый ключ в первый раз
# если конфигурации WireGuard еще нет. Однако эта опция позволяет
# предоставить ваш собственный закрытый ключ WireGuard, если это действительно необходимо.
# Поскольку это, конечно, очень чувствительное значение, вы можете рассмотреть возможность использования инструмента, такого как Ansible Vault
# для хранения его в зашифрованном виде.
# wireguard_private_key:
# Установите на "false", если кэш пакетов не должен быть обновлен
# (актуально только если менеджер пакетов поддерживает эту опцию).
wireguard_update_cache: "true"
# Обычно роль устанавливает и активирует модуль ядра wireguard, где
# это уместно. В некоторых случаях мы можем не быть в состоянии загрузить модули ядра, такие как
# соединения LXC без привилегий. Если вы установите это значение на false, вам нужно будет
# обеспечить наличие модуля wireguard в ядре!
wireguard_install_kernel_module: true
Существуют также несколько специфических настроек для дистрибутивов Linux:
#######################################
# Настройки, относящиеся только к:
# - Ubuntu
# - elementary OS
#######################################
# УСТАРЕЛО: Пожалуйста, используйте вместо этого "wireguard_update_cache".
# Установите на "false", если кэш пакетов не должен быть обновлен.
wireguard_ubuntu_update_cache: "{{ wireguard_update_cache }}"
# Установите время действительности кэша пакетов
wireguard_ubuntu_cache_valid_time: "3600"
#######################################
# Настройки, относящиеся только к CentOS 7
#######################################
# Установите wireguard_centos7_installation_method в "kernel-plus"
# для использования ядра kernel-plus, которое включает встроенный,
# подписанный модуль WireGuard.
#
# По умолчанию "standard" будет использовать стандартное ядро и
# модуль ELRepo для WireGuard.
wireguard_centos7_installation_method: "standard"
# Перезагрузите хост, если необходимо, если используется ядро "kernel-plus"
wireguard_centos7_kernel_plus_reboot: true
# Количество секунд, которые нужно подождать для перезагрузки машины и ответа
# если используется "kernel-plus". Актуально только если
# "wireguard_centos7_kernel_plus_reboot" установлено в "true".
wireguard_centos7_kernel_plus_reboot_timeout: "600"
# Перезагрузите хост, если необходимо, если используется стандартное ядро
wireguard_centos7_standard_reboot: true
# Количество секунд, которые нужно подождать для перезагрузки машины и ответа
# если используется "standard". Актуально только если
# "wireguard_centos7_standard_reboot" установлено в "true".
wireguard_centos7_standard_reboot_timeout: "600"
#########################################
# Настройки, относящиеся только к RockyLinux 8
#########################################
# Установите wireguard_rockylinux8_installation_method в "dkms"
# чтобы скомпилировать модуль WireGuard из исходников с помощью wireguard-dkms.
# Это требуется, если вы используете собственное ядро и/или ваша архитектура
# не x86_64.
#
# По умолчанию "standard" установит модуль ядра
# с kmod-wireguard из ELRepo.
wireguard_rockylinux8_installation_method: "standard"
Каждый узел в host_vars/
должен настроить по меньшей мере один адрес через wireguard_address
или wireguard_addresses
. Переменная wireguard_address
может содержать только один IPv4, поэтому рекомендуется использовать переменную wireguard_addresses
, которая может содержать массив как IPv4, так и IPv6 адресов.
wireguard_addresses:
- "10.8.0.101/24"
Конечно, все IP-адреса должны быть в одной подсети, такой как /24
, как мы видим в приведённом выше примере. Если wireguard_allowed_ips
не установлено, то значениями по умолчанию будут IP-адреса, определённые в wireguard_address
и wireguard_addresses
, без CIDR, а вместо этого с /32
(IPv4) или /128
(IPv6), что является, по сути, маршрутом хоста (обратите внимание на templates/wg.conf.j2
). Рассмотрим этот пример и допустим, что вы явно не задали wireguard_allowed_ips
:
[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820
Это часть конфигурации WireGuard с моего рабочего места. У него VPN IP 10.8.0.2
, и мы находимся в подсети /24
, в которой расположены все мои хосты WireGuard. Также вы можете видеть, что у нас есть пир, который имеет конечную точку controller01.p.domain.tld:51820
. Когда wireguard_allowed_ips
не задано явно, шаблон Ansible добавит запись AllowedIPs
с IP этого хоста и /32
или /128
. В WireGuard это, по сути, определяет маршрутизацию. Конфигурация выше говорит: На моем рабочем месте с IP 10.8.0.2
я хочу отправлять весь трафик на 10.8.0.101/32
на конечную точку controller01.p.domain.tld:51820
. Теперь допустим, мы задаем wireguard_allowed_ips: "0.0.0.0/0"
. Тогда получившаяся конфигурация будет выглядеть так.
[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820
[Peer]
PublicKey = ....
AllowedIPs = 0.0.0.0/0
Endpoint = controller01.p.domain.tld:51820
Теперь это в основном то же самое, что и выше, НО теперь конфигурация говорит: я хочу маршрутизировать ВСЕ соединения, исходящие от моего рабочего места, к конечной точке controller01.p.domain.tld:51820
. Может ли эта конечная точка обрабатывать трафик — это уже другой вопрос, и всё зависит от того, как вы настроите маршрутизацию конечной точки ;-)
Вы можете указать дополнительные необязательные настройки (они не имеют значения по умолчанию и не будут установлены, если не указаны, кроме wireguard_allowed_ips
, как уже было упомянуто) также для каждого хоста в host_vars/
(или в вашем файле хостов Ansible, если хотите). Значения для следующих переменных являются лишь примерами и не имеют значений по умолчанию (для получения дополнительной информации и примеров см. wg-quick.8):
wireguard_allowed_ips: ""
wireguard_endpoint: "host1.domain.tld"
wireguard_persistent_keepalive: "30"
wireguard_dns: "1.1.1.1"
wireguard_fwmark: "1234"
wireguard_mtu: "1492"
wireguard_table: "5000"
wireguard_preup:
- ...
wireguard_predown:
- ...
wireguard_postup:
- ...
wireguard_postdown:
- ...
wireguard_save_config: "true"
wireguard_(preup|predown|postup|postdown)
указываются как списки. Вот два примера:
wireguard_postup:
- iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
- iptables -A FORWARD -i %i -j ACCEPT
- iptables -A FORWARD -o %i -j ACCEPT
wireguard_preup:
- echo 1 > /proc/sys/net/ipv4/ip_forward
- ufw allow 51820/udp
Команды выполняются в порядке, как описано в wg-quick.8.
Кроме того, можно добавить "неуправляемые" пиры. Эти пиры не обрабатываются Ansible и не входят в группу хостов vpn
, например:
wireguard_unmanaged_peers:
client.example.com:
public_key: 5zsSBeZZ8P9pQaaJvY9RbELQulcwC5VBXaZ93egzOlI=
# preshared_key: ... например, из ansible-vault?
allowed_ips: 10.0.0.3/32
endpoint: client.example.com:51820
persistent_keepalive: 0
Требуется один из wireguard_address
(устарело) или wireguard_addresses
(рекомендуется), как уже упоминалось. Это IP-адреса имени интерфейса, определённого с переменной wireguard_interface
(wg0
по умолчанию). Каждый хост, конечно, должен иметь хотя бы один уникальный VPN IP. Если вы не зададите wireguard_endpoint
, плейбук будет использовать имя хоста, определённое в группе хостов vpn
(имя хоста в инвентаре Ansible). Если вы установите wireguard_endpoint
в ""
(пустую строку), то этот пир не будет иметь конечной точки. Это означает, что этот хост сможет подключаться только к хостам, которые имеют wireguard_endpoint
. Это полезно для клиентов, которые не открывают никаких сервисов для VPN и просто хотят получать доступ к сервисам на других хостах. Таким образом, если вы определите только один хост с установленным wireguard_endpoint
и все остальные хосты имеют wireguard_endpoint
, установленный в ""
(пустую строку), это, по сути, означает, что у вас есть только клиенты, кроме одного, в данном случае это сервер WireGuard. Третий вариант — установить wireguard_endpoint
в какое-либо имя хоста. Например, если у вас есть разные имена хостов для частного и публичного DNS этого хоста и вам нужны разные DNS записи для этого случая, установка wireguard_endpoint
станет полезной. Возьмем, к примеру, IP выше: wireguard_address: "10.8.0.101"
. Это частный IP, и я создал запись DNS для этого частного IP, как host01.i.domain.tld
(i
для внутреннего в данном случае). Для публичного IP я создал запись DNS, как host01.p.domain.tld
(p
для публичного). wireguard_endpoint
должен быть интерфейсом, к которому могут подключаться другие участники группы vpn
. Таким образом, в этом случае я бы установил wireguard_endpoint
в host01.p.domain.tld
, потому что WireGuard обычно должен иметь возможность подключаться к публичному IP других хостов.
Вот небольшой пример использования моего плейбука: Я использую WireGuard для настройки полностью соединённой VPN (каждый хост может напрямую подключаться к каждому другому хосту) и запускаю свой Kubernetes (K8s) кластер в Hetzner Cloud (но вы можете использовать любого хостера, которого хотите). Таким образом, важные компоненты, такие как контроллер K8s и рабочие узлы (включая поды), общаются только через зашифрованный WireGuard VPN. Кроме того (как уже упоминалось), у меня есть два клиента. Оба имеют kubectl
установлен и могут взаимодействовать с внутренним сервером API Kubernetes, используя WireGuard VPN. Один из двух клиентов также открывает конечную точку WireGuard, потому что почтовый сервер Postfix в облаке и мой внутренний Postfix должны иметь возможность общаться друг с другом. Думаю, это может быть не так уж и обычное использование WireGuard :D Но это показывает, что возможно. Теперь позвольте мне объяснить настройку, которая может помочь вам использовать эту роль Ansible.
Сначала приведу часть моего файла Ansible hosts
:
[vpn]
controller0[1:3].i.domain.tld
worker0[1:2].i.domain.tld
server.at.home.i.domain.tld
workstation.i.domain.tld
[k8s_controller]
controller0[1:3].i.domain.tld
[k8s_worker]
worker0[1:2].i.domain.tld
Как видите, у меня здесь три группы: vpn
(все хосты, на которых будет установлен WireGuard), k8s_controller
(узлы контроллера Kubernetes) и k8s_worker
(узлы рабочих Kubernetes). Буква i
в доменном имени обозначает внутренний
. Все DNS записи i.domain.tld
имеют запись A
, которая указывает на VPN IP, которую мы определим вскоре для каждого хоста, например: controller01.i.domain.tld. IN A 10.8.0.101
. Причина этого в том, что все компоненты Kubernetes связываются и слушают только на интерфейсе WireGuard в моей настройке. И поскольку я нуждаюсь в этих внутренних IP для всех моих компонентов Kubernetes, я указываю внутренние DNS записи в моём файле Ansible hosts
. Таким образом, я могу легко использовать имена хостов инвентаря Ansible и переменные в плейбуках и шаблонах.
Для узлов контроллера Kubernetes я определил следующие переменные хоста:
Файл Ansible хоста: host_vars/controller01.i.domain.tld
---
wireguard_addresses:
- "10.8.0.101/24"
wireguard_endpoint: "controller01.p.domain.tld"
ansible_host: "controller01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3
Файл Ansible хоста: host_vars/controller02.i.domain.tld
:
---
wireguard_addresses:
- "10.8.0.102/24"
wireguard_endpoint: "controller02.p.domain.tld"
ansible_host: "controller02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3
Файл Ansible хоста: host_vars/controller03.i.domain.tld
:
---
wireguard_addresses:
- "10.8.0.103/24"
wireguard_endpoint: "controller03.p.domain.tld"
ansible_host: "controller03.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3
Я указал ansible_python_interpreter
здесь для каждого узла, так как узлы контроллера используют Ubuntu 18.04, на котором Python 3 установлен по умолчанию. ansible_host
установлен в публичный DNS этого хоста. Ansible будет использовать это имя для подключения к хосту по SSH. Я также использую то же значение для wireguard_endpoint
по той же причине. Пиры WireGuard должны подключаться к другим пирами через публичный IP (хотя это может быть и внутренний IP, если это работает для вас). IP-адреса, указанные в wireguard_address
или wireguard_addresses
, должны быть уникальными для каждого хоста.
Для рабочих узлов Kubernetes я определил следующие переменные:
Файл Ansible хоста: host_vars/worker01.i.domain.tld
---
wireguard_addresses:
- "10.8.0.111/24"
wireguard_endpoint: "worker01.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker01.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3
Файл Ansible хоста: host_vars/worker02.i.domain.tld
:
---
wireguard_addresses:
- "10.8.0.112/24"
wireguard_endpoint: "worker02.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: "worker02.p.domain.tld"
ansible_python_interpreter: /usr/bin/python3
Как видно, переменные по сути те же, что и для узлов контроллера, с одним исключением: wireguard_persistent_keepalive: "30"
. Мои рабочие узлы (в Hetzner Cloud) и мой внутренний сервер (мой сервер дома) связаны, так как я запустил Postfix на своих облачных узлах, и внешний сервер Postfix пересылает полученные письма на мой внутренний сервер (и наоборот). Мне потребовалась настройка keepalive, потому что время от времени облачные экземпляры и внутренний сервер теряли соединение, и эта настройка решала проблему. Причина этого, конечно, в том, что мой внутренний сервер находится за NAT, и брандмауэр/маршрутизатор должен поддерживать действительность сопоставления NAT/брандмауэра (персистентность NAT и преодоление брандмауэра).
Для моего внутреннего сервера дома (подключенного через DSL-роутер к интернету) у нас есть такая конфигурация:
---
wireguard_addresses:
- "10.8.0.1/24"
wireguard_endpoint: "server.at.home.p.domain.tld"
wireguard_persistent_keepalive: "30"
ansible_host: 192.168.2.254
ansible_port: 22
По умолчанию SSH демон слушает на другом порту, отличном от 22, на всех моих публичных узлах, но внутри я использую 22
, и именно поэтому нужно установить ansible_port: 22
здесь. Также ansible_host
— это, конечно, внутренний IP для этого хоста. Значение wireguard_endpoint
— это динамическая DNS запись. Поскольку у меня дома IP не статический, мне нужно запускать скрипт каждую минуту на моем сервере дома, который проверяет, изменился ли IP, и если да, то корректирует мою DNS запись. Я использую функцию DynHost от OVH, чтобы добиться этого, но вы тоже можете использовать и любого провайдера DynDNS, которого захотите. Я также перенаправляю входящий трафик на порт 51820/UDP
на мой внутренний сервер, чтобы разрешить входящий трафик WireGuard. IP-адреса из wireguard_address
и wireguard_addresses
должны, конечно, быть частью нашей подсети WireGuard.
И наконец, для моего рабочего места (на котором я запускаю все команды ansible-playbook
):
wireguard_addresses:
- "10.8.0.2/24"
wireguard_endpoint: ""
ansible_connection: local
ansible_become: false
Как видите, wireguard_endpoint: ""
— это пустая строка здесь. Это означает, что роль Ansible не будет устанавливать конечную точку для моего рабочего места. Поскольку нет необходимости, чтобы другие хосты подключались к моему рабочему месту, не имеет смысла определять конечную точку. Таким образом, в этом случае я могу получить доступ ко всем хостам, определённым в группе Ansible vpn
, но это не наоборот. Таким образом, результирующая конфигурация WireGuard для моего рабочего места будет выглядеть так:
[Interface]
Address = 10.8.0.2/24
PrivateKey = ....
ListenPort = 51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.101/32
Endpoint = controller01.p.domain.tld:51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.102/32
Endpoint = controller02.p.domain.tld:51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.103/32
Endpoint = controller03.p.domain.tld:51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.111/32
PersistentKeepalive = 30
Endpoint = worker01.p.domain.tld:51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.112/32
PersistentKeepalive = 30
Endpoint = worker02.p.domain.tld:51820
[Peer]
PublicKey = ....
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 30
Endpoint = server.at.home.p.domain.tld:51820
Другие файлы конфигурации WireGuard (wg0.conf
по умолчанию) выглядят аналогично, но, конечно, [Interface]
включает конфигурацию конкретного хоста, а записи [Peer]
перечисляют конфигурацию других хостов.
Примеры плейбуков
- hosts: vpn
roles:
- githubixx.ansible_role_wireguard
hosts: vpn
roles:
-
role: githubixx.ansible_role_wireguard
tags: role-wireguard
Пример инвентаря с использованием двух различных интерфейсов WireGuard на хосте "multi"
Это сложный пример, использующий формат YAML инвентаря:
vpn1:
hosts:
multi:
wireguard_addresses:
- "10.9.0.1/32"
wireguard_allowed_ips: "10.9.0.1/32, 192.168.2.0/24"
wireguard_endpoint: multi.example.com
nated:
wireguard_addresses:
- "10.9.0.2/32"
wireguard_allowed_ips: "10.9.0.2/32, 192.168.3.0/24"
wireguard_persistent_keepalive: 15
wireguard_endpoint: nated.example.com
wireguard_postup:
- iptables -t nat -A POSTROUTING -o ens12 -j MASQUERADE
- iptables -A FORWARD -i %i -j ACCEPT
- iptables -A FORWARD -o %i -j ACCEPT
wireguard_postdown:
- iptables -t nat -D POSTROUTING -o ens12 -j MASQUERADE
- iptables -D FORWARD -i %i -j ACCEPT
- iptables -D FORWARD -o %i -j ACCEPT
vpn2:
hosts:
# Используйте другое имя и определите ansible_host, чтобы избежать смешивания переменных без
# необходимости префиксовать переменные именем интерфейса.
multi-wg1:
ansible_host: multi
wireguard_interface: wg1
# когда используете несколько интерфейсов на одном хосте, мы должны использовать разные порты
wireguard_port: 51821
wireguard_addresses:
- "10.9.1.1/32"
wireguard_endpoint: multi.example.com
another:
wireguard_address:
- "10.9.1.2/32"
wireguard_endpoint: another.example.com
Пример плейбуков для примера выше:
- hosts: vpn1
roles:
- githubixx.ansible_role_wireguard
- hosts: vpn2
roles:
- githubixx.ansible_role_wireguard
Тестирование
Эта роль имеет небольшую тестовую установку, которая создаётся с помощью Molecule, libvirt (vagrant-libvirt) и QEMU/KVM. Пожалуйста, смотрите мой блог Testing Ansible roles with Molecule, libvirt (vagrant-libvirt) and QEMU/KVM о том, как настроить. Тестовая конфигурация здесь.
После этого можно выполнить молекулу:
molecule converge
Это настроит множество виртуальных машин (VM) с различными поддерживаемыми операционными системами Linux. Чтобы провести несколько тестов:
molecule verify
Чтобы очистить, выполните:
molecule destroy
Существует также небольшая настройка Molecule, которая имитирует центральный сервер WireGuard с несколькими клиентами:
molecule converge -s single-server
Лицензия
GNU General Public License v3.0 или новее
Информация об авторе
ansible-galaxy install githubixx/ansible-role-wireguard