diff --git a/defaults/main.yml b/defaults/main.yml
index e15ccae..2f70cca 100755
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -4,26 +4,28 @@ cloud_storage: /opt/storage
cloud_stage: prod
cloud_update: false
-sysctl_configs:
- - net.ipv4.ip_forward=1
+vpn_internal_dns: 1.1.1.1
-vpn_host: "vpn.{{ domain_external | default('my-domain.tld') }}"
-vpn_protocol: "udp"
-vpn_server: "cloud-openvpn"
-vpn_cidr: 10.10.10.0
-vpn_mask: 255.255.255.0
-vpn_port: 1194
-vpn_log: /var/log/openvpn/openvpn.log
-vpn_dns:
- - 208.67.222.222
- - 208.67.220.220
+vpn_allow_adjacent_client_traffic: True
+vpn_keepalive: 25
-vpn_clients:
- - name: username
- state: present
+vpn_gateway_clientfolder: /etc/wireguard/clients
+vpn_gateway_interface: eth0
+vpn_gateway_host: my-wireguard-server.tld
+vpn_gateway_port: 51820
+vpn_gateway_net_prefix: 10.10.123
+vpn_gateway_net_cidr: 28
+vpn_gateway_public_key: your-public-key
+vpn_gateway_private_key: your-privat-key
-easy_rsa_home: "/usr/share/easy-rsa"
+vpn_gateway_forward: []
+# - server_port: 22
+# client_port: "{{ ssh_port }}"
+# client_index: 0
-easy_rsa_clients:
- - name: easyrsa_username
- state: present
+
+vpn_clients: []
+# - name:
+# index: 1
+# private_key:
+# public_key:
diff --git a/handlers/main.yml b/handlers/main.yml
index f377e6f..ed97d53 100755
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,9 +1 @@
---
-- name: restart sysctl
- command: sysctl -p
-
-- name: restart openvpn
- systemd:
- name: openvpn@server
- state: restarted
- enabled: yes
diff --git a/meta/main.yml b/meta/main.yml
index 9455611..1313445 100755
--- a/meta/main.yml
+++ b/meta/main.yml
@@ -1,17 +1,16 @@
---
galaxy_info:
role_name: vpn
- namespace: hahn-cloud
+ namespace: opendevchain
author: Lars Hahn
company: OpenDevChain
license: MIT
- description: Role to setup an OpenVPN server, to make e.g. personal networks available from remote.
+ description: Role to setup a wireguard server.
min_ansible_version: 2.7
platforms:
- name: Debian
versions:
- - 10
+ - 12
galaxy_tags:
- vpn
-dependencies:
- - easy-rsa
+dependencies: []
diff --git a/tasks/clients.yml b/tasks/clients.yml
deleted file mode 100755
index a2ff28c..0000000
--- a/tasks/clients.yml
+++ /dev/null
@@ -1,57 +0,0 @@
----
-- name: install client ovpn configs
- template:
- src: etc/openvpn/client/client.ovpn.j2
- dest: "{{ vpn_home }}/client/{{ client }}.ovpn"
- mode: 0600
- owner: root
- group: vpn
- loop: "{{ vpn_clients_active }}"
- loop_control:
- loop_var: client
- label: "{{ client }}"
-
-- name: find abstent clients ovpn config
- find:
- paths: "{{ vpn_home }}/client/"
- pattern: "{{ client }}.*"
- loop: "{{ vpn_clients_passive }}"
- loop_control:
- loop_var: client
- label: "{{ client }}"
- register: absent_clients
-
-- name: remove absent clients ovpn config
- file:
- state: absent
- path: "{{ client }}"
- loop: "{{ absent_clients.results | json_query('[*].files[*].path') | flatten }}"
- loop_control:
- loop_var: client
- label: "{{ client | basename }}"
- when: absent_clients.results | length > 0
-
-- name: setup OpenVPN config folder for each vpn client
- file:
- state: directory
- path: "/home/{{ user }}/.openvpn"
- mode: 0700
- owner: "{{ user }}"
- group: "{{ user }}"
- loop: "{{ vpn_clients_active | map('regex_replace','\\.[^\\.]+$','') | list | unique }}"
- loop_control:
- loop_var: user
- label: "{{ user }}"
-
-- name: rollout .ovpn single-file config for active clients
- copy:
- src: "{{ vpn_home }}/client/{{ client }}.ovpn"
- dest: "/home/{{ client.split('.')[0] }}/.openvpn/"
- mode: 0400
- owner: "{{ client.split('.')[0] }}"
- group: "{{ client.split('.')[0] }}"
- loop: "{{ vpn_clients_active }}"
- loop_control:
- loop_var: client
- label: "{{ client }}"
-
\ No newline at end of file
diff --git a/tasks/main.yml b/tasks/main.yml
index 6a787b7..3b89a06 100755
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,32 +1,53 @@
---
-- name: install openvpn and recommendations
+- name: install fail2ban service
apt:
update_cache: yes
state: "{% if cloud_update | bool %}latest{% else %}present{% endif %}"
install_recommends: yes
- pkg:
- - "openvpn"
+ pkg: wireguard
+ register: wireguard_installed
-- name: setup sysctl config for openvpn
- lineinfile:
- path: "{{ sysctl_conf }}"
- regexp: '^#?{{ configline.split("=")[0] }}='
- line: "{{ configline }}"
- backrefs: yes
+- name: setup key files
+ template:
+ src: "etc/wireguard/{{ item }}.j2"
+ dest: "/etc/wireguard/{{ item }}"
owner: root
- group: root
- mode: 0644
- loop: "{{ sysctl_configs }}"
- loop_control:
- loop_var: configline
- label: "{{ configline }}"
- notify: restart sysctl
+ mode: 0600
+ loop:
+ - private.key
+ - public.key
+ notify: restart wireguard service
-# run in a block only when for every vpn_client user there is a certificate
-# otherwise ignore ...
-# It is better to have a matching config (dependency currently only to vpn)
-# then to catch spectacular cases.
-- block:
- - include_tasks: server.yml
- - include_tasks: clients.yml
- when: vpn_clients | difference(easy_rsa_clients) | length == 0
+- name: setup wireguard config
+ template:
+ src: "etc/wireguard/wireguard.conf.j2"
+ dest: "/etc/wireguard/{{ cloud_name }}.conf"
+ owner: root
+ mode: 0600
+ notify: restart wireguard service
+
+- name: setup client folder
+ file:
+ state: directory
+ mode: 0600
+ owner: root
+ path: "{{ vpn_gateway_clientfolder }}"
+
+- name: setup client configs
+ template:
+ src: "etc/wireguard/clients/wireguard-client.conf.j2"
+ dest: "{{ vpn_gateway_clientfolder }}/{{ vpn_client.name }}.conf"
+ owner: root
+ mode: 0600
+ loop: "{{ vpn_clients }}"
+ loop_control:
+ loop_var: vpn_client
+ label: "{{ vpn_client.name }}"
+
+
+- name: enable wireguard systemd unit
+ systemd:
+ name: wg-quick@{{ cloud_name }}
+ enabled: yes
+ daemon_reload: yes
+ state: started
diff --git a/tasks/server.yml b/tasks/server.yml
deleted file mode 100755
index 11ccb62..0000000
--- a/tasks/server.yml
+++ /dev/null
@@ -1,78 +0,0 @@
----
-- name: find installed openvpn clients
- find:
- paths: "{{ vpn_home }}/client/"
- patterns: "*.crt"
- register: easyrsa_key_file
-
-#- name: Setup default OpenVPN configuration
-# shell:
-# cmd: "gunzip -c {{ vpn_doc_examples }}/server.conf.gz > {{ vpn_home }}/server.conf"
-# creates: "{{ vpn_home }}/server.conf"
-
-- name: Setup default OpenVPN configuration
- copy:
- src: "{{ vpn_doc_examples }}/server.conf"
- dest: "{{ vpn_home }}/server.conf"
- owner: root
- group: root
- force: no
-
-- name: find server TLS-Auth key
- find:
- paths: "{{ vpn_home }}/server/"
- patterns: "ta.key"
- register: tlsauth_key_files
-
-- name: generate TLS-Auth key
- command: "openvpn --genkey --secret {{ vpn_tlsauth_key_file }}"
- when: tlsauth_key_files.matched == 0
-
-- name: install easy-rsa CA and server certs
- copy:
- src: "{{ easy_rsa_home }}/pki/{{ item }}"
- dest: "{{ vpn_home }}/server/"
- mode: 0600
- owner: root
- group: root
- loop:
- - "ca.crt"
- - "dh.pem"
- - "private/{{ vpn_server }}.key"
- - "issued/{{ vpn_server }}.crt"
-
-- name: setup OpenVPN configuration
- lineinfile:
- path: "{{ vpn_home }}/server.conf"
- regexp: '^;?{{ configline.split(" ")[0] }}{% if configline.split(" ") | length > 1 %} {% endif %}'
- line: "{{ configline }}"
- owner: root
- group: root
- mode: 0644
- loop: "{{ vpn_server_conf }}"
- loop_control:
- loop_var: configline
- label: "{{ configline }}"
- notify: restart openvpn
-
-- name: off-setup OpenVPN configuration
- lineinfile:
- path: "{{ vpn_home }}/server.conf"
- regexp: '^{{ configline.split(" ")[0] }}{% if configline.split(" ") | length > 1 %} {% endif %}'
- line: ";{{ configline }}"
- backrefs: yes
- owner: root
- group: root
- mode: 0644
- loop: "{{ vpn_server_conf_off }}"
- loop_control:
- loop_var: configline
- label: ";{{ configline }}"
- notify: restart openvpn
-
-- name: enable openvpn@server systemd unit
- systemd:
- name: openvpn@server
- enabled: yes
- daemon_reload: yes
- state: started
\ No newline at end of file
diff --git a/templates/etc/openvpn/client/client.ovpn.j2 b/templates/etc/openvpn/client/client.ovpn.j2
deleted file mode 100755
index 100a7ac..0000000
--- a/templates/etc/openvpn/client/client.ovpn.j2
+++ /dev/null
@@ -1,29 +0,0 @@
-client
-dev tun
-proto {{ vpn_protocol }}
-remote {{ vpn_host }} {{ vpn_port }}
-remote-cert-tls server
-key-direction 1
-cipher AES-256-CBC
-auth SHA512
-auth-nocache
-tls-version-min 1.2
-tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
-comp-lzo
-nobind
-persist-key
-persist-tun
-mute-replay-warnings
-verb 3
-
-{{ lookup("file", easy_rsa_home + "/pki/ca.crt") }}
-
-
-{{ lookup("file", easy_rsa_home + "/pki/issued/" + client + ".crt") }}
-
-
-{{ lookup("file", easy_rsa_home + "/pki/private/" + client + ".key") }}
-
-
-{{ lookup("file", vpn_tlsauth_key_file) }}
-
diff --git a/templates/etc/wireguard/clients/wireguard-client.conf.j2 b/templates/etc/wireguard/clients/wireguard-client.conf.j2
new file mode 100644
index 0000000..1d1b91c
--- /dev/null
+++ b/templates/etc/wireguard/clients/wireguard-client.conf.j2
@@ -0,0 +1,11 @@
+[Interface]
+Address = {{ vpn_gateway_net_prefix }}.{{ vpn_client.index }}/32
+PrivateKey = {{ vpn_client.private_key }}
+DNS = {{ vpn_internal_dns }}
+
+[Peer]
+PublicKey = {{ vpn_gateway_public_key }}
+Endpoint = {{ vpn_gateway_host }}:{{ vpn_gateway_port }}
+AllowedIPs = {{ vpn_gateway_net_prefix }}.1/{% if vpn_allow_adjacent_client_traffic %}{{ vpn_gateway_net_cidr }}{% else %}32{% endif %}
+
+PersistentKeepalive = {{ vpn_keepalive }}
diff --git a/templates/etc/wireguard/private.key.j2 b/templates/etc/wireguard/private.key.j2
new file mode 100644
index 0000000..3fc053d
--- /dev/null
+++ b/templates/etc/wireguard/private.key.j2
@@ -0,0 +1 @@
+{{ vpn_gateway_private_key }}
\ No newline at end of file
diff --git a/templates/etc/wireguard/public.key.j2 b/templates/etc/wireguard/public.key.j2
new file mode 100644
index 0000000..7a794c7
--- /dev/null
+++ b/templates/etc/wireguard/public.key.j2
@@ -0,0 +1 @@
+{{ vpn_gateway_public_key }}
\ No newline at end of file
diff --git a/templates/etc/wireguard/wireguard.conf.j2 b/templates/etc/wireguard/wireguard.conf.j2
new file mode 100644
index 0000000..909d8d4
--- /dev/null
+++ b/templates/etc/wireguard/wireguard.conf.j2
@@ -0,0 +1,25 @@
+[Interface]
+Address = {{ vpn_gateway_net_prefix }}.1/{{ vpn_gateway_net_cidr }}
+ListenPort = {{ vpn_gateway_port }}
+PrivateKey = {{ vpn_gateway_private_key }}
+
+{% if vpn_gateway_forward is defined and vpn_gateway_forward | length > 0 %}
+PreUp = sysctl -w net.ipv4.ip_forward=1
+PreUp = sysctl -w net.ipv6.conf.all.forwarding=1
+
+{% for config in vpn_gateway_forward %}
+PreUp = iptables -t nat -A PREROUTING -i {{ vpn_gateway_interface }} -p {{ config.protocol | default('tcp') }} --dport {{ config.server_port }} -j DNAT --to-destination {{ vpn_gateway_net_prefix }}.{{ config.client_index }}:{{ config.client_port }}
+PostDown = iptables -t nat -D PREROUTING -i {{ vpn_gateway_interface }} -p {{ config.protocol | default('tcp') }} --dport {{ config.server_port }} -j DNAT --to-destination {{ vpn_gateway_net_prefix }}.{{ config.client_index }}:{{ config.client_port }}
+
+{% endfor %}
+PreUp = iptables -t nat -A POSTROUTING -o {{ cloud_name }} -j MASQUERADE
+PostDown = iptables -t nat -D POSTROUTING -o {{ cloud_name }} -j MASQUERADE
+{% endif %}
+
+{% for client in vpn_clients %}
+## vpn {{ cloud_name }} - {{ client }} ##
+[Peer]
+PublicKey = {{ vpn_clients[client].public_key }}
+AllowedIPs = {{ vpn_gateway_net_prefix }}.{{ vpn_clients[client].index }}/32
+
+{% endfor %}
\ No newline at end of file
diff --git a/vars/main.yml b/vars/main.yml
index 8d090b0..e69de29 100755
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -1,43 +0,0 @@
----
-sysctl_path: "/etc/"
-sysctl_conf: "{{ sysctl_path }}/sysctl.conf"
-
-vpn_doc_examples: /usr/share/doc/openvpn/examples/sample-config-files/
-
-vpn_home: "/etc/openvpn"
-
-vpn_clients_active: "{{ vpn_clients | json_query('[?state==`present`].name') }}"
-vpn_clients_passive: "{{ vpn_clients | json_query('[?state!=`present`].name') }}"
-
-vpn_tlsauth_key: ta.key
-vpn_tlsauth_key_file: "{{ vpn_home }}/server/{{ vpn_tlsauth_key }}"
-
-vpn_server_conf:
- - "port {{ vpn_port }}"
- - "proto {{ vpn_protocol }}"
- - dev tun
- - "ca {{ vpn_home }}/server/ca.crt"
- - "cert {{ vpn_home }}/server/{{ vpn_server }}.crt"
- - "key {{ vpn_home }}/server/{{ vpn_server }}.key"
- - "dh {{ vpn_home }}/server/dh.pem"
- - topology subnet
- - "server {{ vpn_cidr }} {{ vpn_mask }}"
- - cipher AES-256-CBC
- - "tls-auth {{ vpn_home }}/server/ta.key 0"
- - tls-version-min 1.2
- - tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
- - auth SHA512
- - auth-nocache
- - keepalive 20 60
- - persist-key
- - persist-tun
- - client-to-client
- - comp-lzo
- - user nobody
- - group nogroup
- - "log-append {{ vpn_log }}"
- - verb 3
-
-vpn_server_conf_off:
- - explicit-exit-notify 1
-