Rewrote playbook as a role.

This commit is contained in:
Brian Lee 2023-05-23 08:30:17 -07:00
commit 38e79b3659
9 changed files with 183 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
vars/targets/*.yml
!vars/targets/example.yml

17
LICENSE Normal file
View File

@ -0,0 +1,17 @@
MIT No Attribution License
Copyright (c) 2023 Brian Lee
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

64
README.md Normal file
View File

@ -0,0 +1,64 @@
# Ansible Role: Wireguard
This Ansible Role manages wireguard configuration.
## Requirements
None.
## Platforms
Any distro with a repository that has wireguard-tools. It has only been tested on the following:
* Ubuntu 22.04
* Debian 11
### Legacy systems
For distros that do not have the package in their repositories, see the [official installation instructions](https://www.wireguard.com/install/) for your specific distro.
For example, the older Debian 10 buster basically needs you to build the module for the kernel using dkms:
```bash
apt-get install linux-headers-$(uname -r)
apt-get reinstall wireguard-dkms
```
## Role Variables
Available variables are listed below, along with default values (see `defaults/main.yml`):
```yaml
wireguard_public_key: '..'
wireguard_private_key: '..'
wireguard_subnet: 10.0.0.0/24
wireguard_address: 10.0.0.1/24
wireguard_listen_port: 42069
wireguard_peers:
- { allowed_ips: '10.0.0.100/32', public_key: '..' }
```
## Secrets
I use [pass](https://www.passwordstore.org/) as a local secret store, which keeps credentials outside of any source code repository. To add credentials for a new host, generate a new key pair for a host `example.acme.com`:
```bash
key=$(wg genkey)
echo $key | pass insert -e example.com/hostname/WIREGUARD_PRIVATE_KEY
echo $key | wg pubkey
unset key
```
Then add an entry to your `.env` so you can source the private key before the playbook runs.
```bash
export example_WIREGUARD_PRIVATE_KEY=$(pass acme.com/example/WIREGUARD_PRIVATE_KEY)
```
## Example Playbook
```yaml
- hosts: all
roles:
- bleetube.wireguard
```

11
defaults/main.yml Normal file
View File

@ -0,0 +1,11 @@
---
wireguard_snat_address: "{{ ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0]) }}"
wireguard_inet_if: "{{ ansible_default_ipv4.interface }}"
wireguard_if: wg0
wireguard_forward_targets:
- 0.0.0.0/0
wireguard_packages:
- iptables # missing in some Debian 11 cloudimages
- tcpdump
- wireguard
- wireguard-tools

5
handlers/main.yml Normal file
View File

@ -0,0 +1,5 @@
---
- name: restart {{ wireguard_if }}
ansible.builtin.service:
name: wg-quick@{{ wireguard_if }}
state: restarted

2
meta/main.yml Normal file
View File

@ -0,0 +1,2 @@
---
dependencies: []

47
tasks/main.yml Normal file
View File

@ -0,0 +1,47 @@
---
#- name: Load target host configuration if it is defined.
# ansible.builtin.include_vars:
# file: "{{ item }}"
# with_first_found:
# - files:
# - "vars/targets/{{ inventory_hostname_short }}.yml"
# - "../../host_vars/wireguard/{{ inventory_hostname_short }}.yml"
# skip: true
# tags: test
- name: Assert the private key has been configured.
ansible.builtin.assert:
that:
- wireguard_private_key != ''
fail_msg: "FAILED: Wireguard private key is not set."
no_log: true
- name: Install and update Wireguard related packages
ansible.builtin.package:
name: "{{ item }}"
state: latest
loop: "{{ wireguard_packages }}"
# https://docs.ansible.com/ansible/latest/collections/ansible/posix/sysctl_module.html
- ansible.posix.sysctl:
name: "{{ item }}"
value: 1
sysctl_set: yes
loop:
- net.ipv4.ip_forward
- net.ipv6.conf.all.forwarding
# TODO: come up with a way to have different routing policy templates for different hosts
- name: Configure Wireguard forwarding
ansible.builtin.template:
src: routes.sh.j2
dest: /etc/wireguard/routes.sh
mode: '0755'
- name: Configure Wireguard tunnel
ansible.builtin.template:
src: interface.conf.j2
dest: "/etc/wireguard/{{ wireguard_if }}.conf"
mode: '0600'
notify: "restart {{ wireguard_if }}"
tags: interface

View File

@ -0,0 +1,13 @@
[Interface]
Address = {{ wireguard_address }}
PostUp = /etc/wireguard/routes.sh add
PostDown = /etc/wireguard/routes.sh del
ListenPort = {{ wireguard_listen_port }}
PrivateKey = {{ wireguard_private_key }}
SaveConfig = false
{% for peer in wireguard_peers %}
[Peer]
PublicKey = {{ peer.public_key }}
AllowedIPs = {{ peer.allowed_ips }}
{% endfor %}

22
templates/routes.sh.j2 Normal file
View File

@ -0,0 +1,22 @@
#!/bin/bash
set -x
if [[ "add" == ${1} ]]
then
{% for forward_target in wireguard_forward_targets %}
iptables -A FORWARD -i {{ wireguard_if }} -d {{ forward_target }} -j ACCEPT
{% endfor %}
iptables -A FORWARD -o {{ wireguard_if }} -j ACCEPT
iptables -t nat -A POSTROUTING -s {{ wireguard_subnet }} -o {{ wireguard_inet_if }} -j SNAT --to-source {{ wireguard_snat_address }}
iptables -P FORWARD DROP
fi
if [[ "del" == ${1} ]]
then
{% for forward_target in wireguard_forward_targets %}
iptables -D FORWARD -i {{ wireguard_if }} -d {{ forward_target }} -j ACCEPT
{% endfor %}
iptables -D FORWARD -o {{ wireguard_if }} -j ACCEPT
iptables -t nat -D POSTROUTING -s {{ wireguard_subnet }} -o {{ wireguard_inet_if }} -j SNAT --to-source {{ wireguard_snat_address }}
fi