[install WireGuard](https://www.wireguard.com/install/) yourself. You can use | [install WireGuard](https://www.wireguard.com/install/) yourself. You can use | ||||
this formula afterwards. | this formula afterwards. | ||||
**Important**: On every configuration change, this formula restarts the | |||||
wireguard interface in order to apply any changes. | |||||
# Requirements | # Requirements | ||||
- systemd: This formula makes use of wireguard systemd service files. | |||||
- wireguard kermel module | |||||
- systemd: This formula makes use of wireguard-shipped systemd service files | |||||
- wireguard kernel module | |||||
# Installation | # Installation | ||||
# Available states | # Available states | ||||
No states. Include `wireguard` in the top.sls file. | No states. Include `wireguard` in the top.sls file. | ||||
``` | |||||
base: | |||||
[... snip ...] | |||||
'some_minion': | |||||
- wireguard | |||||
[... snip ...] | |||||
``` |
wireguard: | wireguard: | ||||
wg0: | |||||
# The two following keys are non-wireguard options. | |||||
# Delete the config file. The interface will also be stopped and disables. | |||||
# Defaults to False. | |||||
#delete: False | |||||
# Start and enable the service. Setting this to false causes the interface | |||||
# to be stopped and disabled. Defaults to True. | |||||
#enable: True | |||||
interfaces: | |||||
wg0: | |||||
# The two following keys are non-wireguard options. | |||||
# Delete the config file. The interface will also be stopped and disables. | |||||
# Defaults to False. | |||||
#delete: False | |||||
# Start and enable the service. Setting this to false causes the interface | |||||
# to be stopped and disabled. Defaults to True. | |||||
#enable: True | |||||
# see wg(8) and wg-quick(8) for supported keys. We use all lowercase | |||||
# letters. | |||||
config: | |||||
# see wg(8) and wg-quick(8) for supported keys. We use all lowercase | |||||
# letters. | |||||
# address must be a list | |||||
address: | |||||
- fe80::1/64 | |||||
- 10.0.0.1/24 | |||||
listenport: 51820 | |||||
# very important to quote off. Jinja expands off without quotes to False | |||||
# which will result in 'table' not being set in the config file, resulting | |||||
# in defaulting to auto. | |||||
table: 'off' | |||||
peers: | |||||
- publickey: foobar | |||||
# address must be a list | |||||
allowedips: | |||||
- fe80::2 | |||||
- 10.0.0.2/32 | |||||
presharedkey: secret1 | |||||
- publickey: bazbar | |||||
allowedips: | |||||
- fe80::3 | |||||
- 10.0.0.3/32 | |||||
presharedkey: secret2 | |||||
PrivateKey: private_key_string | |||||
# the config key can be used to pass a whole wireguard config in. The config | |||||
# key takes precendce. Every other wireguard option in will then be ignored. | |||||
# Make sure to have the correct indentation of 4 spaces more than the config | |||||
# key and to start with config: | | |||||
config: | | |||||
[Interface] | |||||
Address = fe80::1/64 | |||||
ListenPort = 51820 | |||||
PrivateKey = private | |||||
Table = off | |||||
[Peer] | |||||
PublicKey = peer | |||||
AllowedIPs = fe80::2 | |||||
# address must be a list of strings or a comma separated string | |||||
Address: | |||||
- fe80::1/64 | |||||
- 10.0.0.1/24 | |||||
#Address: fe80::1/64, 10.0.0.1/24 | |||||
ListenPort: 51820 | |||||
# It is very important to quote off. Jinja expands off without quotes to | |||||
# False which will result in 'table' not being set in the config file, | |||||
# resulting in defaulting to auto. | |||||
Table: 'off' | |||||
peers: | |||||
- PublicKey: foobar | |||||
# AllowedIPs must be a list of strings or a comma separated string | |||||
AllowedIPs: | |||||
- fe80::2 | |||||
- 10.0.0.2/32 | |||||
PresharedKey: secret1 | |||||
- Publickey: bazbar | |||||
AllowedIPs: | |||||
- fe80::3 | |||||
- 10.0.0.3/32 | |||||
PresharedKey: secret2 | |||||
# the raw_config key can be used to pass a whole wireguard config in. The | |||||
# raw_config key takes precendce before the regular config and peers keys. | |||||
# Every other wireguard option in will then be ignored. Make sure to have | |||||
# the correct indentation of 4 spaces more than the raw_config key and to | |||||
# start with raw_config: | | |||||
raw_config: | | |||||
[Interface] | |||||
Address = fe80::1/64 | |||||
ListenPort = 51820 | |||||
PrivateKey = private | |||||
Table = off | |||||
[Peer] | |||||
PublicKey = peer | |||||
AllowedIPs = fe80::2 |
{%- macro output_if_set(object, lookup_key, output_key) -%} | |||||
{%- if object.get(lookup_key) -%} | |||||
{{output_key}} = {{object.get(lookup_key)}} | |||||
{%- macro output(key, value) -%} | |||||
{%- if key in ['Address', 'DNS', 'AllowedIPs'] -%} | |||||
{{output_list(key, value)}} | |||||
{%- else -%} | |||||
{{key}} = {{value}} | |||||
{%- endif -%} | {%- endif -%} | ||||
{%- endmacro -%} | {%- endmacro -%} | ||||
{%- macro output_list_if_set(object, lookup_key, output_key) -%} | |||||
{%- set l = object.get(lookup_key, []) -%} | |||||
{%- if l is not string -%} | |||||
{%- for item in l -%} | |||||
{{output_key}} = {{item}} | |||||
{%- macro output_list(key, value) -%} | |||||
{%- if value is string -%} | |||||
{{key}} = {{value}} | |||||
{%- else -%} | |||||
{%- for item in value %} | |||||
{{key}} = {{item}} | |||||
{%- endfor -%} | {%- endfor -%} | ||||
{%- endif -%} | {%- endif -%} | ||||
{%- endmacro -%} | {%- endmacro -%} | ||||
[Interface] | [Interface] | ||||
{{ output_list_if_set(interface, 'address', 'Address') }} | |||||
{{ output_if_set(interface, 'listenport', 'ListenPort') }} | |||||
{{ output_list_if_set(interface, 'dns', 'DNS') }} | |||||
{{ output_if_set(interface, 'mtu', 'MTU') }} | |||||
{{ output_if_set(interface, 'privatekey', 'PrivateKey') }} | |||||
{{ output_if_set(interface, 'table', 'Table') }} | |||||
{{ output_if_set(interface, 'preup', 'PreUp') }} | |||||
{{ output_if_set(interface, 'postup', 'PostUp') }} | |||||
{{ output_if_set(interface, 'predown', 'PreDown') }} | |||||
{{ output_if_set(interface, 'postdown', 'PostDown') }} | |||||
{{ output_if_set(interface, 'saveconfig', 'SaveConfig') }} | |||||
{{ output_if_set(interface, 'fwmark', 'FwMark') }} | |||||
{%- for peer in interface.get('peers', []) -%} | |||||
{% for key, value in interface.items() -%} | |||||
{{ output(key, value) }} | |||||
{% endfor -%} | |||||
{%- for peer in peers -%} | |||||
[Peer] | [Peer] | ||||
{{ output_if_set(peer, 'publickey', 'PublicKey') }} | |||||
{{ output_if_set(peer, 'presharedkey', 'PresharedKey') }} | |||||
{{ output_list_if_set(peer, 'allowedips', 'AllowedIPs') }} | |||||
{{ output_if_set(peer, 'endpoint', 'Endpoint') }} | |||||
{{ output_if_set(peer, 'persistentkeepalive', 'PersistentKeepalive') }} | |||||
{% for key, value in peer.items() -%} | |||||
{{ output(key, value) }} | |||||
{% endfor -%} | |||||
{%- endfor -%} | {%- endfor -%} |
{%- for interface in salt['pillar.get']('wireguard', {}).keys() %} | |||||
{%- for interface_name, interface_dict in salt.pillar.get('wireguard:interfaces', {}).items() %} | |||||
{% if salt['pillar.get']('wireguard:' ~ interface ~ ':delete', False) %} | |||||
stop and disable wg-quick@{{interface}}: | |||||
{% if interface_dict.get('delete', False) %} | |||||
stop and disable wg-quick@{{interface_name}}: | |||||
service.dead: | service.dead: | ||||
- name: wg-quick@{{interface}} | |||||
- name: wg-quick@{{interface_name}} | |||||
- enable: False | - enable: False | ||||
remove wireguard_interface_{{interface}}: | |||||
remove wireguard_interface_{{interface_name}}: | |||||
file.absent: | file.absent: | ||||
- name: /etc/wireguard/{{interface}}.conf | |||||
{% elif not salt['pillar.get']('wireguard:' ~ interface ~ ':enable', True) %} | |||||
stop and disable wg-quick@{{interface}}: | |||||
- name: /etc/wireguard/{{interface_name}}.conf | |||||
{% else %} | |||||
{% if not interface_dict.get('enable', True) %} | |||||
stop and disable wg-quick@{{interface_name}}: | |||||
service.dead: | service.dead: | ||||
- name: wg-quick@{{interface}} | |||||
- name: wg-quick@{{interface_name}} | |||||
- enable: False | - enable: False | ||||
{% else %} | |||||
{% else %} | |||||
restart wg-quick@{{interface_name}}: | |||||
service.running: | |||||
- name: wg-quick@{{interface_name}} | |||||
- enable: True | |||||
- watch: | |||||
- file: wireguard_interface_{{interface_name}}_config | |||||
{% endif %} | |||||
{% if salt['pillar.get']('wireguard:' ~ interface ~ ':config') %} | |||||
wireguard_interface_{{interface}}_config: | |||||
{% if interface_dict.get('raw_config') %} | |||||
wireguard_interface_{{interface_name}}_config: | |||||
file.managed: | file.managed: | ||||
- name: /etc/wireguard/{{interface}}.conf | |||||
- contents_pillar: wireguard:{{interface}}:config | |||||
- name: /etc/wireguard/{{interface_name}}.conf | |||||
- contents_pillar: wireguard:interfaces:{{interface_name}}:raw_config | |||||
- mode: 600 | - mode: 600 | ||||
{% else %} | |||||
wireguard_interface_{{interface}}_config: | |||||
{% else %} | |||||
wireguard_interface_{{interface_name}}_config: | |||||
file.managed: | file.managed: | ||||
- name: /etc/wireguard/{{interface}}.conf | |||||
- name: /etc/wireguard/{{interface_name}}.conf | |||||
- source: salt://wireguard/files/wg.conf | - source: salt://wireguard/files/wg.conf | ||||
- template: jinja | - template: jinja | ||||
- context: | - context: | ||||
interface: {{salt['pillar.get']('wireguard:' ~ interface)}} | |||||
interface: {{interface_dict.get('config', {})}} | |||||
peers: {{interface_dict.get('peers', [])}} | |||||
- mode: 600 | - mode: 600 | ||||
{% endif %} | |||||
{% endif %} | |||||
restart wg-quick@{{interface}}: | |||||
service.running: | |||||
- name: wg-quick@{{interface}} | |||||
- enable: True | |||||
- watch: | |||||
- file: wireguard_interface_{{interface}}_config | |||||
{% endif %} | |||||
{% endif %} | |||||
{%- endfor %} | {%- endfor %} |