From 9b1eeb3d58092b3a73a90640355d70a7be9af260 Mon Sep 17 00:00:00 2001 From: Dmitrii Kashin Date: Fri, 6 Dec 2019 01:01:33 +0300 Subject: [PATCH 01/12] openvpn_client_conf_template --- defaults/main.yml | 2 ++ tasks/core/clients.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index ab08232..ca1ecc7 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -136,3 +136,5 @@ openvpn_simple_auth_password: "" openvpn_tls_auth: false openvpn_tls_key: "ta.key" # }}} + +openvpn_client_conf_template: client.conf.j2 diff --git a/tasks/core/clients.yml b/tasks/core/clients.yml index ae1434e..11324f6 100644 --- a/tasks/core/clients.yml +++ b/tasks/core/clients.yml @@ -7,7 +7,7 @@ - name: Generate client configurations template: - src: client.conf.j2 + src: "{{ openvpn_client_conf_template }}" dest: "{{ openvpn_etcdir }}/ovpns/{{ item }}.ovpn" loop: "{{ openvpn_clients }}" register: openvpn_clients_changed From 0116443f9c7275d5fc5f2b41ad56864bce7570e7 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 14:32:29 +0100 Subject: [PATCH 02/12] Fixes elasticsearch ingest pipeline --- meta/beats/elasticsearch-ingest-pipelines.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/meta/beats/elasticsearch-ingest-pipelines.yml b/meta/beats/elasticsearch-ingest-pipelines.yml index 2d12930..479ca04 100644 --- a/meta/beats/elasticsearch-ingest-pipelines.yml +++ b/meta/beats/elasticsearch-ingest-pipelines.yml @@ -15,6 +15,8 @@ pipelines: pattern_definitions: TIMESTAMP: "%{DAY} %{MONTH} ?%{MONTHDAY} %{TIME} %{YEAR}" - gsub: + # the month day is ' 3' or '24'. The space before '3' will break the + # date filter that follows, so removing it. field: "openvpn.date" pattern: " " replacement: ' ' @@ -25,6 +27,7 @@ pipelines: - set: field: 'openvpn.event' value: 'client-connected' + # Parses log lines created with the # `templates/etc/openvpn/scripts/client-disconnect.sh` script. - description: "openvpn-disconnection-log-line" @@ -36,7 +39,9 @@ pipelines: field: message ignore_failure: true patterns: - - "%{DATESTAMP_OTHER:openvpn.date},%{DATA:openvpn.common_name},%{IP:openvpn.client_ip}" + - "%{TIMESTAMP:openvpn.date},%{DATA:openvpn.common_name},%{IP:openvpn.client_ip}" + pattern_definitions: + TIMESTAMP: "%{DAY} %{MONTH} ?%{MONTHDAY} %{TIME} %{TZ} %{YEAR}" - gsub: field: "openvpn.date" pattern: " " From 1ad7e8141550f94a49156c1b7e2efad7dfc89121 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 14:39:52 +0100 Subject: [PATCH 03/12] Properly checks for a bridge configuration Fixes #154 --- tasks/system/bridge/Debian.yml | 6 ++++-- tasks/system/bridge/RedHat.yml | 37 +++++++++++++++++----------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tasks/system/bridge/Debian.yml b/tasks/system/bridge/Debian.yml index 8538bf5..cca7ee3 100644 --- a/tasks/system/bridge/Debian.yml +++ b/tasks/system/bridge/Debian.yml @@ -4,11 +4,13 @@ template: src: bridge/bridge-interface.deb.j2 dest: "/etc/network/interfaces.d/{{ openvpn_dev }}" - when: openvpn_bridge | bool + when: + - openvpn_bridge is defined + - openvpn_bridge | length > 0 notify: restart networking debian - name: Remove interface configuration for "{{ openvpn_dev }}" file: path: "/etc/network/interfaces.d/{{ openvpn_dev }}" state: absent - when: not openvpn_bridge | bool + when: openvpn_bridge is not defined or openvpn_bridge | length == 0 diff --git a/tasks/system/bridge/RedHat.yml b/tasks/system/bridge/RedHat.yml index 05e540a..8444889 100644 --- a/tasks/system/bridge/RedHat.yml +++ b/tasks/system/bridge/RedHat.yml @@ -1,28 +1,29 @@ --- -- name: Setup up script - when: openvpn_bridge | bool - template: - src: bridge/up.sh.j2 - dest: "{{ openvpn_scripts_dir }}/up.sh" - mode: o+x +- block: + - name: Setup up script + template: + src: bridge/up.sh.j2 + dest: "{{ openvpn_scripts_dir }}/up.sh" + mode: o+x -- name: Setup down script - template: - src: bridge/down.sh.j2 - dest: "{{ openvpn_scripts_dir }}/down.sh" - mode: o+x - when: openvpn_bridge | bool + - name: Setup down script + template: + src: bridge/down.sh.j2 + dest: "{{ openvpn_scripts_dir }}/down.sh" + mode: o+x -- name: Setup bridge - template: - src: bridge/bridge-interface.rh.j2 - dest: "/etc/sysconfig/network-scripts/ifcfg-br-{{ openvpn_dev }}" - when: openvpn_bridge | bool + - name: Setup bridge + template: + src: bridge/bridge-interface.rh.j2 + dest: "/etc/sysconfig/network-scripts/ifcfg-br-{{ openvpn_dev }}" + when: + - openvpn_bridge is defined + - openvpn_bridge | length > 0 notify: restart networking redhat - name: Remove interface configuration for "{{ openvpn_dev }}" file: path: "/etc/sysconfig/network-scripts/ifcfg-br-{{ openvpn_dev }}" state: absent - when: not openvpn_bridge | bool + when: openvpn_bridge is not defined or openvpn_bridge | length == 0 From 13ea8afb536c5ac614d563af829be2d9ede57a45 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 14:42:06 +0100 Subject: [PATCH 04/12] Fixes upploading inline scripts Fixes #155 --- tasks/scripts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/scripts.yml b/tasks/scripts.yml index bb71ed5..8d1fb97 100644 --- a/tasks/scripts.yml +++ b/tasks/scripts.yml @@ -23,7 +23,7 @@ loop: "{{ openvpn_script_files }}" - name: Upload inline scripts - template: + copy: content: "{{ item.content }}" dest: "{{ openvpn_scripts_dir }}/{{ item.name }}" owner: "{{ openvpn_user }}" From 2fa95dccad83ed0fbc2e966d4676e77ed973f7b8 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 14:46:48 +0100 Subject: [PATCH 05/12] Includes ta.key in client zip Closes #156 --- tasks/core/clients.yml | 5 ----- tasks/core/configure.yml | 8 ++++++++ tasks/openvpn.yml | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tasks/core/clients.yml b/tasks/core/clients.yml index 49eb49c..30b6bc4 100644 --- a/tasks/core/clients.yml +++ b/tasks/core/clients.yml @@ -1,10 +1,5 @@ --- -- name: Create client configuration directory - file: - path: "{{ openvpn_etcdir }}/ovpns" - state: directory - - name: Generate client configurations template: src: client.conf.j2 diff --git a/tasks/core/configure.yml b/tasks/core/configure.yml index 40a6f75..6916598 100644 --- a/tasks/core/configure.yml +++ b/tasks/core/configure.yml @@ -17,3 +17,11 @@ src: server.conf.j2 dest: "{{ openvpn_etcdir }}/server.conf" notify: openvpn restart + +# Needed by both tls-authentication tasks and client-configuration tasks. Placed +# here to avoid repeating it twice in both places where the tls and +# client-config tasks are located. +- name: Create client configuration directory + file: + path: "{{ openvpn_etcdir }}/ovpns" + state: directory diff --git a/tasks/openvpn.yml b/tasks/openvpn.yml index 196d9cc..28a1965 100644 --- a/tasks/openvpn.yml +++ b/tasks/openvpn.yml @@ -28,8 +28,6 @@ - include_tasks: core/read-client-files.yml when: openvpn_unified_client_profiles -- import_tasks: core/clients.yml - - include_tasks: authentication/ldap.yml - include_tasks: authentication/pam.yml @@ -38,6 +36,8 @@ - include_tasks: authentication/tls.yml +- import_tasks: core/clients.yml + - include_tasks: scripts.yml - include_tasks: "system/bridge/{{ ansible_os_family }}.yml" From b6f42a0a32dc10729ed0f01389916c46f0057fb2 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 14:54:02 +0100 Subject: [PATCH 06/12] Tests creating scripts --- defaults/main.yml | 11 ++++++----- molecule/default/converge.yml | 13 +++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index b1a0e75..72aed80 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -186,13 +186,14 @@ openvpn_tls_key: "ta.key" # Scripting {{{ # A list of directories that the role should create and that should be # accessible by the OpenVPN server to write into after it has dropped -# privileges. The OpenVPN server should run with limited privileges, eg with +# privileges. The OpenVPN server should run with limited privileges, e.g. with # `openvpn_user` set to `nobody`. Such a user will not be able to access many # files and directories in the file system. This means that if you want one of -# your scripts to write to some file, that file will need to be writable by the -# OpenVPN server. The directories included in this variable will be created by -# the role and your scripts will be able to create and write to files inside -# them. Eg, `/var/log/openvpn-script-out/` +# your scripts to write to some file (e.g. under `/var/log`), that file will +# need to be writable by the OpenVPN server. The directories included in this +# variable will be created by the role with permissions that will allow the +# OpenVPN server to write into them, thus your scripts will be able to create +# and write to files inside them. Example: [`/var/log/openvpn-script-out/`]. openvpn_script_output_directories: [] # A path on the OpenVPN server where OpenVPN scripts should be uploaded to. diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index e8d8515..a7c008b 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -21,6 +21,19 @@ - name: client2 content: '# pass' + ## scripting + openvpn_script_output_directories: + - /var/log/openvpn-script-out/ + + openvpn_script_files: + - scripts/client-disconnect.sh.j2 + + openvpn_inline_scripts: + - name: my-up-script.sh + content: | + #!/usr/bin/env + echo 'Up!' >> "/var/up.log" + # Enabled them openvpn_download_clients: false openvpn_open_firewall: false From c6e27c90d19f808feb4e6043b6efa6aebe5703cb Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 17 Mar 2020 15:02:10 +0100 Subject: [PATCH 07/12] Fixes tests --- templates/scripts/client-disconnect.sh.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/scripts/client-disconnect.sh.j2 b/templates/scripts/client-disconnect.sh.j2 index e7bc837..99199b1 100644 --- a/templates/scripts/client-disconnect.sh.j2 +++ b/templates/scripts/client-disconnect.sh.j2 @@ -3,6 +3,11 @@ {# openvpn_client_disconnect_log is a variable specific to this file and is not mentioned in $(defaults/main.yml) #} +{%- if openvpn_client_disconnect_log is not defined -%} + {% set openvpn_client_disconnect_log = "{{ + openvpn_script_output_directories[0] }}/disconnect.log" %} +{%- endif -%} + if [[ ! -e "{{ openvpn_client_disconnect_log }}" ]]; then echo 'time,common_name,external_ip' >"{{ openvpn_client_disconnect_log }}" fi From f4c9c81011a84f1c1be281a5f7a666f1847225cd Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Tue, 24 Mar 2020 19:52:49 +0100 Subject: [PATCH 08/12] Renames file --- meta/beats/{filebeat-inputs.yml => openvpn.filebeat.inputs.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename meta/beats/{filebeat-inputs.yml => openvpn.filebeat.inputs.yml} (100%) diff --git a/meta/beats/filebeat-inputs.yml b/meta/beats/openvpn.filebeat.inputs.yml similarity index 100% rename from meta/beats/filebeat-inputs.yml rename to meta/beats/openvpn.filebeat.inputs.yml From 49984922846df84592a9dfa9694793a066ce2a81 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Thu, 30 Apr 2020 18:02:21 +0200 Subject: [PATCH 09/12] Moves beat files under templates --- .../beats/elasticsearch.openvpn.ingest.pipelines.yml | 0 templates/beats/filebeat.openvpn.fields.yml | 12 ++++++++++++ .../beats/filebeat.openvpn.inputs.yml | 0 .../beats/heartbeat.openvpn.monitors.yml | 0 4 files changed, 12 insertions(+) rename meta/beats/elasticsearch-ingest-pipelines.yml => templates/beats/elasticsearch.openvpn.ingest.pipelines.yml (100%) create mode 100644 templates/beats/filebeat.openvpn.fields.yml rename meta/beats/openvpn.filebeat.inputs.yml => templates/beats/filebeat.openvpn.inputs.yml (100%) rename meta/beats/heartbeat-monitors.yml => templates/beats/heartbeat.openvpn.monitors.yml (100%) diff --git a/meta/beats/elasticsearch-ingest-pipelines.yml b/templates/beats/elasticsearch.openvpn.ingest.pipelines.yml similarity index 100% rename from meta/beats/elasticsearch-ingest-pipelines.yml rename to templates/beats/elasticsearch.openvpn.ingest.pipelines.yml diff --git a/templates/beats/filebeat.openvpn.fields.yml b/templates/beats/filebeat.openvpn.fields.yml new file mode 100644 index 0000000..2e4b334 --- /dev/null +++ b/templates/beats/filebeat.openvpn.fields.yml @@ -0,0 +1,12 @@ +--- + +- name: openvpn.date + type: date +- name: openvpn.client_ip + type: ip +- name: openvpn.common_name + type: keyword +- name: openvpn.event + type: keyword +- name: openvpn.port + type: long diff --git a/meta/beats/openvpn.filebeat.inputs.yml b/templates/beats/filebeat.openvpn.inputs.yml similarity index 100% rename from meta/beats/openvpn.filebeat.inputs.yml rename to templates/beats/filebeat.openvpn.inputs.yml diff --git a/meta/beats/heartbeat-monitors.yml b/templates/beats/heartbeat.openvpn.monitors.yml similarity index 100% rename from meta/beats/heartbeat-monitors.yml rename to templates/beats/heartbeat.openvpn.monitors.yml From e78ebcaf6cdbecc8e1c0a3e52458ea87ca52a739 Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Fri, 1 May 2020 16:08:30 +0200 Subject: [PATCH 10/12] Fixes uploading scripts when openvpn_scripts_dir has no trailing slash --- tasks/scripts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/scripts.yml b/tasks/scripts.yml index 8d1fb97..9244054 100644 --- a/tasks/scripts.yml +++ b/tasks/scripts.yml @@ -16,7 +16,7 @@ - name: Upload script files template: src: "{{ item }}" - dest: "{{ openvpn_scripts_dir }}{{ item | basename | replace('.j2', '') }}" + dest: "{{ openvpn_scripts_dir }}/{{ item | basename | replace('.j2', '') }}" owner: "{{ openvpn_user }}" group: "{{ openvpn_group }}" mode: 0o744 From f51f20c62be415282bf43e834010cebe979ab2cb Mon Sep 17 00:00:00 2001 From: Nikolaos Kakouros Date: Sun, 3 May 2020 15:16:46 +0200 Subject: [PATCH 11/12] Fixes linter --- defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/main.yml b/defaults/main.yml index 3725f8c..a55c82b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -160,7 +160,7 @@ openvpn_ccd_configs: [] # the `ifconfig-push` directive. This will be applied to the `client` when it # connects to the openvpn server. -# Use a custom template for client configuration. In that case, you have to +# Use a custom template for client configuration. In that case, you have to # take care of which of the above variables will actually have an effect on # the client config. openvpn_client_conf_template: client.conf.j2 From 91c62a719b47cbc129208c3fafdc6946ee50e013 Mon Sep 17 00:00:00 2001 From: santiagomr Date: Fri, 8 May 2020 16:17:42 -0300 Subject: [PATCH 12/12] Updating deprecated option ns-cert-type with new remote-cert-tls - linter improvements --- templates/client.conf.j2 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/templates/client.conf.j2 b/templates/client.conf.j2 index 2881f6c..0637f88 100644 --- a/templates/client.conf.j2 +++ b/templates/client.conf.j2 @@ -20,7 +20,7 @@ cipher {{ openvpn_cipher }} # The hostname/IP and port of the server. You can have multiple remote entries # to load balance between the servers. -remote {{openvpn_host}} {{openvpn_port}} +remote {{ openvpn_host }} {{ openvpn_port }} # Keep trying indefinitely to resolve the host name of the OpenVPN server. # Very useful on machines which are not permanently connected to the internet @@ -42,10 +42,10 @@ persist-tun {{ openvpn_ca_file_contents }} -{{ openvpn_client_cert_output |default([{'item':client,'stdout':''}])|selectattr('item', 'match', client)|map(attribute='stdout')|list|first }} +{{ openvpn_client_cert_output | default([{'item':client,'stdout':''}]) | selectattr('item', 'match', client) | map(attribute='stdout') | list | first }} -{{ openvpn_client_keys_output |default([{'item':client,'stdout':''}])|selectattr('item', 'match', client)|map(attribute='stdout')|list|first }} +{{ openvpn_client_keys_output | default([{'item':client,'stdout':''}]) | selectattr('item', 'match', client) | map(attribute='stdout') | list | first }} {% if openvpn_tls_auth %} key-direction 1 @@ -56,22 +56,24 @@ key-direction 1 {% else %} ca ca.crt -cert {{client}}.crt -key {{client}}.key +cert {{ client }}.crt +key {{ client }}.key {% endif %} -# Verify server certificate by checking that the certicate has the nsCertType -# field set to "server". This is an important precaution to protect against a -# potential attack discussed here: http://openvpn.net/howto.html#mitm +# To avoid a possible Man-in-the-Middle attack where an authorized client tries +# to connect to another client by impersonating the server, make sure to enforce +# some kind of server certificate verification by clients. +# This is an important precaution to protect against a potential attack +# discussed here: http://openvpn.net/howto.html#mitm # # To use this feature, you will need to generate your server certificates with -# the nsCertType field set to "server". The build-key-server script in the -# easy-rsa folder will do this. -ns-cert-type server +# the nsCertType field set to "server". The build-key-server script in the easy-rsa +# folder will do this. See https://openvpn.net/community-resources/rsa-key-management/ +remote-cert-tls server {% if openvpn_tls_auth and not openvpn_unified_client_profiles -%} # Use a static pre-shared key (PSK) -tls-auth {{openvpn_tls_key}} 1 +tls-auth {{ openvpn_tls_key }} 1 {% endif %} # Enable compression on the VPN link. Don't enable this unless it is also @@ -83,12 +85,12 @@ comp-lzo {% endif %} # Set log file verbosity. -verb {{openvpn_verb}} +verb {{ openvpn_verb }} {% if openvpn_use_pam or openvpn_use_ldap %} auth-user-pass {% endif %} {% for option in openvpn_client_options %} -{{option}} +{{ option }} {% endfor %}