From 42220a14f9fb4a6e16a0c00a5839c0a0e831be4d Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 16 Nov 2021 21:16:00 +0100 Subject: openvpn roles - bas scaffolding and certs --- roles/network/openvpn/base/tasks/main.yml | 5 ++ roles/network/openvpn/ca/tasks/main.yml | 52 +++++++++++++ roles/network/openvpn/client/defaults/main.yml | 1 + roles/network/openvpn/client/handlers/main.yml | 5 ++ roles/network/openvpn/client/tasks/main.yml | 7 ++ roles/network/openvpn/client/tasks/tls.yml | 97 +++++++++++++++++++++++ roles/network/openvpn/server/defaults/main.yml | 1 + roles/network/openvpn/server/handlers/main.yml | 5 ++ roles/network/openvpn/server/tasks/main.yml | 8 ++ roles/network/openvpn/server/tasks/tls.yml | 104 +++++++++++++++++++++++++ 10 files changed, 285 insertions(+) create mode 100644 roles/network/openvpn/base/tasks/main.yml create mode 100644 roles/network/openvpn/ca/tasks/main.yml create mode 100644 roles/network/openvpn/client/defaults/main.yml create mode 100644 roles/network/openvpn/client/handlers/main.yml create mode 100644 roles/network/openvpn/client/tasks/main.yml create mode 100644 roles/network/openvpn/client/tasks/tls.yml create mode 100644 roles/network/openvpn/server/defaults/main.yml create mode 100644 roles/network/openvpn/server/handlers/main.yml create mode 100644 roles/network/openvpn/server/tasks/main.yml create mode 100644 roles/network/openvpn/server/tasks/tls.yml (limited to 'roles/network/openvpn') diff --git a/roles/network/openvpn/base/tasks/main.yml b/roles/network/openvpn/base/tasks/main.yml new file mode 100644 index 00000000..c5b43401 --- /dev/null +++ b/roles/network/openvpn/base/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- name: install openvpn + apt: + name: openvpn + state: present diff --git a/roles/network/openvpn/ca/tasks/main.yml b/roles/network/openvpn/ca/tasks/main.yml new file mode 100644 index 00000000..90b021fc --- /dev/null +++ b/roles/network/openvpn/ca/tasks/main.yml @@ -0,0 +1,52 @@ +--- +- name: install python-cryptoraphy + apt: + name: "{{ python_basename }}-cryptography" + state: present + +- name: create base directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}" + state: directory + +- name: create CA directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca" + state: directory + owner: root + group: root + mode: 0700 + +- name: create CA private key + openssl_privatekey: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/key.pem" + type: RSA + size: 4096 + owner: root + group: root + mode: 0600 + +- name: create signing request for CA certificate + openssl_csr: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/csr.pem" + privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/key.pem" + CN: "CA for OpenVPN zone {{ openvpn_zone.name }}" + useCommonNameForSAN: no + key_usage: + - cRLSign + - keyCertSign + key_usage_critical: yes + basic_constraints: + - 'CA:TRUE' + - 'pathlen:0' + basic_constraints_critical: yes + +- name: create self-signed CA certificate + openssl_certificate: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + csr_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/csr.pem" + privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/key.pem" + provider: selfsigned + selfsigned_digest: sha256 + selfsigned_not_after: "+18250d" ## 50 years + selfsigned_create_subject_key_identifier: always_create diff --git a/roles/network/openvpn/client/defaults/main.yml b/roles/network/openvpn/client/defaults/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/roles/network/openvpn/client/defaults/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/network/openvpn/client/handlers/main.yml b/roles/network/openvpn/client/handlers/main.yml new file mode 100644 index 00000000..dc05dd89 --- /dev/null +++ b/roles/network/openvpn/client/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart openvpn-client + service: + name: "openvpn-client@{{ openvpn_zone.name }}" + state: restarted diff --git a/roles/network/openvpn/client/tasks/main.yml b/roles/network/openvpn/client/tasks/main.yml new file mode 100644 index 00000000..49f6443f --- /dev/null +++ b/roles/network/openvpn/client/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: create TLS certificate and key + import_tasks: tls.yml + +## TODO: +## - generate/install openvpn configuration +## - enable/start "openvpn-server@{{ openvpn_zone.name }}" diff --git a/roles/network/openvpn/client/tasks/tls.yml b/roles/network/openvpn/client/tasks/tls.yml new file mode 100644 index 00000000..3c0d9b3f --- /dev/null +++ b/roles/network/openvpn/client/tasks/tls.yml @@ -0,0 +1,97 @@ +--- +- name: install python-cryptography + apt: + name: "{{ python_basename }}-cryptography" + state: present + +- name: create base directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}" + state: directory + +- name: create client cert/key directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client" + state: directory + owner: root + group: root + mode: 0750 + +- name: create private key for client certificate + openssl_privatekey: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/key.pem" + type: RSA + size: 4096 + owner: root + group: root + mode: 0400 + notify: restart openvpn-client + +- name: create signing request for client certificate + openssl_csr: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/csr.pem" + privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/key.pem" + CN: "{{ inventory_hostname }}" + key_usage: + - digitalSignature + key_usage_critical: yes + extended_key_usage: + - clientAuth + extended_key_usage_critical: yes + basic_constraints: + - 'CA:FALSE' + basic_constraints_critical: yes + +- name: slurp CSR + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/csr.pem" + register: openvpn_client_csr + +- name: check if client certificate exists + stat: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/crt.pem" + register: openvpn_client_cert + +- name: read client certificate validity + when: openvpn_client_cert.stat.exists + openssl_certificate_info: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/crt.pem" + valid_at: + ten_years: '+3650d' ## 10 years + register: openvpn_client_cert_info + +- name: slurp existing client certificate + when: openvpn_client_cert.stat.exists + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/crt.pem" + register: openvpn_client_cert_current + +- name: generate client certificate + delegate_to: "{{ openvpn_zone.ca_host }}" + community.crypto.x509_certificate_pipe: + content: "{{ openvpn_client_cert_current.content | default('') | b64decode }}" + csr_content: "{{ openvpn_client_csr.content | b64decode }}" + provider: ownca + ownca_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + ownca_privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/key.pem" + ownca_digest: sha256 + ownca_not_after: "+18250d" ## 50 years + force: "{{ openvpn_client_cert.stat.exists and (not openvpn_client_cert_info.valid_at.ten_years) }}" + register: openvpn_client_cert + +- name: store client certificate + copy: + content: "{{ openvpn_client_cert.certificate }}" + dest: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/client/crt.pem" + notify: restart openvpn-client + +- name: slurp CA certificate + delegate_to: "{{ openvpn_zone.ca_host }}" + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + register: openvpn_client_ca_certificate + +- name: install CA certificate + copy: + content: "{{ openvpn_client_ca_certificate.content | b64decode }}" + dest: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" diff --git a/roles/network/openvpn/server/defaults/main.yml b/roles/network/openvpn/server/defaults/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/roles/network/openvpn/server/defaults/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/network/openvpn/server/handlers/main.yml b/roles/network/openvpn/server/handlers/main.yml new file mode 100644 index 00000000..0d29e194 --- /dev/null +++ b/roles/network/openvpn/server/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart openvpn-server + service: + name: "openvpn-server@{{ openvpn_zone.name }}" + state: restarted diff --git a/roles/network/openvpn/server/tasks/main.yml b/roles/network/openvpn/server/tasks/main.yml new file mode 100644 index 00000000..98bb220b --- /dev/null +++ b/roles/network/openvpn/server/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: create TLS certificate and key + import_tasks: tls.yml + +## TODO: +## - generate/install openvpn configuration +## - generate/install client config directory +## - enable/start "openvpn-server@{{ openvpn_zone.name }}" diff --git a/roles/network/openvpn/server/tasks/tls.yml b/roles/network/openvpn/server/tasks/tls.yml new file mode 100644 index 00000000..6508676d --- /dev/null +++ b/roles/network/openvpn/server/tasks/tls.yml @@ -0,0 +1,104 @@ +--- +- name: install python-cryptography + apt: + name: "{{ python_basename }}-cryptography" + state: present + +- name: create base directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}" + state: directory + +- name: create server cert/key directory + file: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server" + state: directory + owner: root + group: root + mode: 0750 + +- name: create private key for server certificate + openssl_privatekey: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/key.pem" + type: RSA + size: 4096 + owner: root + group: root + mode: 0400 + notify: restart openvpn-server + +- name: create signing request for server certificate + openssl_csr: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/csr.pem" + privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/key.pem" + CN: "{{ inventory_hostname }}" + key_usage: + - digitalSignature + - keyEncipherment + key_usage_critical: yes + extended_key_usage: + - serverAuth + extended_key_usage_critical: yes + basic_constraints: + - 'CA:FALSE' + basic_constraints_critical: yes + +- name: slurp CSR + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/csr.pem" + register: openvpn_server_csr + +- name: check if server certificate exists + stat: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/crt.pem" + register: openvpn_server_cert + +- name: read server certificate validity + when: openvpn_server_cert.stat.exists + openssl_certificate_info: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/crt.pem" + valid_at: + ten_years: '+3650d' ## 10 years + register: openvpn_server_cert_info + +- name: slurp existing server certificate + when: openvpn_server_cert.stat.exists + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/crt.pem" + register: openvpn_server_cert_current + +- name: generate server certificate + delegate_to: "{{ openvpn_zone.ca_host }}" + community.crypto.x509_certificate_pipe: + content: "{{ openvpn_server_cert_current.content | default('') | b64decode }}" + csr_content: "{{ openvpn_server_csr.content | b64decode }}" + provider: ownca + ownca_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + ownca_privatekey_path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca/key.pem" + ownca_digest: sha256 + ownca_not_after: "+18250d" ## 50 years + force: "{{ openvpn_server_cert.stat.exists and (not openvpn_server_cert_info.valid_at.ten_years) }}" + register: openvpn_server_cert + +- name: store server certificate + copy: + content: "{{ openvpn_server_cert.certificate }}" + dest: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/server/crt.pem" + notify: restart openvpn-server + +- name: slurp CA certificate + delegate_to: "{{ openvpn_zone.ca_host }}" + slurp: + src: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + register: openvpn_server_ca_certificate + +- name: install CA certificate + copy: + content: "{{ openvpn_server_ca_certificate.content | b64decode }}" + dest: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/ca-crt.pem" + +- name: generate Diffie-Hellman parameters + openssl_dhparam: + path: "/etc/ssl/openvpn/{{ openvpn_zone.name }}/dhparams.pem" + size: 2048 + notify: restart openvpn-server -- cgit v1.2.3