Skip to content
This repository has been archived by the owner on Sep 28, 2024. It is now read-only.

Commit

Permalink
new feature: wireguard automatic key management
Browse files Browse the repository at this point in the history
  • Loading branch information
imp1sh committed Jun 29, 2022
1 parent b5fdfb4 commit 9c759d7
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 0 deletions.
1 change: 1 addition & 0 deletions roles/ansible_openwrtnetwork/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
# defaults file for ansible_openwrtnetwork
openwrt_network_deploypath: "/etc/config/network"
openwrt_network_wg_keypath: "/etc/wireguard/ansiblekeys"
openwrt_network_interfacesdefault:
loopback:
device: "lo"
Expand Down
4 changes: 4 additions & 0 deletions roles/ansible_openwrtnetwork/tasks/generate_clientconf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
:q


14 changes: 14 additions & 0 deletions roles/ansible_openwrtnetwork/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
---
# tasks file for ansible_openwrtnetwork
# Wireguard
- name: make sure wireguard management dir exists
file:
path: "{{ openwrt_network_wg_keypath }}"
state: directory
mode: 0700
delegate_to: 127.0.0.1
become: false
- name: run wg server tasks
include_tasks: wg_server.yml
loop: "{{ openwrt_network_interfaces | dict2items }}"
- name: run wg peers tasks
include_tasks: wg_client.yml
loop: "{{ openwrt_network_wireguardpeers | dict2items }}"
- name: Deploy Network configuration
template:
src: network.jinja2
Expand Down
226 changes: 226 additions & 0 deletions roles/ansible_openwrtnetwork/tasks/wg_client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
#- name: set empty list to fill with wireguard interfaces and attributes
- name: display current wireguard peer
debug:
msg: "We are iterating on peer {{ item.key }}"
- name: make sure key directory for interface exists
file:
path: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}"
state: directory
mode: 0700
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
# Generate Private Key
- name: generate private key if not there
command: wg genkey
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_private.key"
register: client_privatekey
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- name: save private key to file if changed
copy:
content: "{{ client_privatekey.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_private.key"
delegate_to: 127.0.0.1
become: false
when:
- client_privatekey.changed
- item.value.managekeys
- name: set strict private key permissions
file:
path: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_private.key"
mode: '0600'
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- name: read private key from file
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_private.key"
register: client_privatekey_data
become: false
delegate_to: 127.0.0.1
when:
- item.value.managekeys
- name: private key decode base64
set_fact:
client_privatekey_data_decoded: "{{ client_privatekey_data.content | b64decode | trim }}"
when:
- item.value.managekeys
- name: insert private key into dict base64
set_fact:
openwrt_network_wireguardpeers: "{{ openwrt_network_wireguardpeers | combine({ item.key: {'private_key': client_privatekey_data_decoded } }, recursive=True) }}"
when:
- item.value.managekeys
# Generate Public Key
- name: generate public key
command: wg pubkey
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}"
stdin: "{{ client_privatekey_data_decoded }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_public.key"
register: client_publickey
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- name: write public key to file
copy:
content: "{{ client_publickey.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_public.key"
delegate_to: 127.0.0.1
become: false
when:
- client_publickey.changed
- item.value.managekeys
- name: read public key from file
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}_public.key"
register: client_publickey_data
become: false
delegate_to: 127.0.0.1
when:
- item.value.managekeys
- name: insert public key into dict base64
set_fact:
openwrt_network_wireguardpeers: "{{ openwrt_network_wireguardpeers | combine({ item.key: {'public_key': client_publickey_data.content|b64decode|trim } }, recursive=True) }}"
delegate_to: 127.0.0.1
when:
- item.value.managekeys
# Getting public key from server
- name: getting public key from corresponding server
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.value.remote_peer }}_public.key"
register: server_publickey_data
become: false
delegate_to: 127.0.0.1
when:
- item.value.managekeys
- name: server public key decode base64
set_fact:
server_publickey_data_decoded: "{{ server_publickey_data.content | b64decode | trim }}"
when:
- item.value.managekeys
- name: insert servers public key into dict base64
set_fact:
openwrt_network_wireguardpeers: "{{ openwrt_network_wireguardpeers | combine({ item.key: {'server_public_key': server_publickey_data_decoded } }, recursive=True) }}"
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
# PSK
# S2S PSK
- name: generate psk for S2S
command: wg genpsk
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/S2S.psk"
register: s2s_psk
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- item.value.s2s is defined
- item.value.s2s
- name: write psk for S2S to file
copy:
content: "{{ s2s_psk.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/S2S.psk"
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- s2s_psk.changed
- item.value.s2s is defined
- item.value.s2s
- name: read s2s psk from file
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/S2S.psk"
register: s2s_psk_data
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- item.value.s2s is defined
- item.value.s2s
- name: decode s2s psk base64
set_fact:
s2s_psk_decoded: "{{ s2s_psk_data.content | b64decode | trim }}"
when:
- item.value.managekeys
- item.value.setpsk
- item.value.s2s is defined
- item.value.s2s
- name: insert s2s psk into dict
set_fact:
openwrt_network_wireguardpeers: "{{ openwrt_network_wireguardpeers | combine({ item.key: {'preshared_key': s2s_psk_decoded } }, recursive=True) }}"
when:
- item.value.managekeys
- item.value.setpsk
- item.value.s2s is defined
- item.value.s2s
# Roadwarrior PSK
- name: generate psk if enabled
command: wg genpsk
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}.psk"
register: client_psk
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- (item.value.s2s is not defined) or ( item.value.s2s is defined and not item.value.s2s )
- name: write psk to file
copy:
content: "{{ client_psk.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}.psk"
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- client_psk.changed
- (item.value.s2s is not defined) or ( item.value.s2s is defined and not item.value.s2s )
- name: read psk from file
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key }}.psk"
register: client_psk_data
delegate_to: 127.0.0.1
become: false
when:
- item.value.managekeys
- item.value.setpsk
- (item.value.s2s is not defined) or ( item.value.s2s is defined and not item.value.s2s )
- name: decode psk base64
set_fact:
client_psk_decoded: "{{ client_psk_data.content | b64decode | trim }}"
when:
- item.value.managekeys
- item.value.setpsk
- (item.value.s2s is not defined) or ( item.value.s2s is defined and not item.value.s2s )
- name: insert psk into dict
set_fact:
openwrt_network_wireguardpeers: "{{ openwrt_network_wireguardpeers | combine({ item.key: {'preshared_key': client_psk_decoded } }, recursive=True) }}"
when:
- item.value.managekeys
- item.value.setpsk
- (item.value.s2s is not defined) or ( item.value.s2s is defined and not item.value.s2s )
- name: generate client config
template:
src: "clientconfig.jinja2"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.value.interface }}/{{ item.key}}.conf"
delegate_to: 127.0.0.1
become: false
when:
- item.value.generateclientconfig is defined
- item.value.generateclientconfig
88 changes: 88 additions & 0 deletions roles/ansible_openwrtnetwork/tasks/wg_server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#- name: set empty list to fill with wireguard interfaces and attributes
- name: display current network interface
debug:
msg: "We are iterating on interface {{ item.key }}"
- name: make sure key directory for interface exists
file:
path: "{{ openwrt_network_wg_keypath }}/{{ item.key }}"
state: directory
mode: 0700
delegate_to: 127.0.0.1
become: false
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: generate private key if not there
command: wg genkey
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.key }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_private.key"
register: server_privatekey
delegate_to: 127.0.0.1
become: false
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: save private key to file if changed
copy:
content: "{{ server_privatekey.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_private.key"
delegate_to: 127.0.0.1
become: false
when:
- item.value.proto == "wireguard"
- server_privatekey.changed
- item.value.wg_managekeys
- name: set strict private key permissions
file:
path: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_private.key"
mode: '0600'
delegate_to: 127.0.0.1
become: false
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: read private key from file
slurp:
src: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_private.key"
register: server_privatekey_data
become: false
delegate_to: 127.0.0.1
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: decode privatekey base64
set_fact:
server_privatekey_decoded: "{{ server_privatekey_data.content | b64decode | trim }}"
delegate_to: 127.0.0.1
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: insert private key into dict
set_fact:
openwrt_network_interfaces: "{{ openwrt_network_interfaces | combine({ item.key: {'wg_private_key': server_privatekey_decoded } }, recursive=True) }}"
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: generate public key
command: wg pubkey
args:
chdir: "{{ openwrt_network_wg_keypath }}/{{ item.key }}"
stdin: "{{ server_privatekey_decoded }}"
creates: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_public.key"
register: server_publickey
delegate_to: 127.0.0.1
become: false
when:
- item.value.proto == "wireguard"
- item.value.wg_managekeys
- name: write public key to file
copy:
content: "{{ server_publickey.stdout }}"
dest: "{{ openwrt_network_wg_keypath }}/{{ item.key }}/{{ inventory_hostname }}_public.key"
delegate_to: 127.0.0.1
become: false
when:
- server_publickey.changed
- item.value.proto == "wireguard"
- item.value.wg_managekeys
23 changes: 23 additions & 0 deletions roles/ansible_openwrtnetwork/templates/clientconfig.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[Interface]
Address = {{ item.value.allowed_ips | join(', ') }}
PrivateKey = {{ client_privatekey_data_decoded }}

[Peer]
PublicKey = {{ server_publickey_data_decoded }}
{% if item.value.s2s is defined and item.value.s2s %}
PresharedKey = {{ s2s_psk_decoded }}
{% else %}
PresharedKey = {{ client_psk_decoded }}
{% endif %}
{% if item.value.routes_to is defined %}
AllowedIPs = {{ hostvars[inventory_hostname]['openwrt_network_interfaces'][item.value.interface]['wg_addresses'] | join(', ') }}, {{ routes_to | join(', ') }}
{% else %}
AllowedIPs = {{ hostvars[inventory_hostname]['openwrt_network_interfaces'][item.value.interface]['wg_addresses'] | join(', ') }}
{% endif %}

{% if item.value.endpoint is not defined %}
Endpoint = {{ hostvars[inventory_hostname]['openwrt_network_interfaces'][item.value.interface]['wg_myendpoint']}}:{{ hostvars[inventory_hostname]['openwrt_network_interfaces'][item.value.interface]['wg_listen_port']}}
{% else %}
Endpoint = {{ item.value.endpoint }}:{{ item.value.endpointport }}
{% endif %}
PersistentKeepalive = {{ item.value.keepalive | default('30', true) }}

0 comments on commit 9c759d7

Please sign in to comment.