From 87e3f3dd39565557c124f6abebbda8da38a80c22 Mon Sep 17 00:00:00 2001 From: nd Date: Thu, 21 May 2020 14:57:00 +0200 Subject: [PATCH] support ownca certificates --- README.md | 35 ++++++++++++- defaults/main.yml | 6 +++ tasks/common_cert.yml | 1 + tasks/ownca_cert.yml | 118 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 tasks/ownca_cert.yml diff --git a/README.md b/README.md index 88e7e5e..4416192 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ All configuration is to be placed inside the `certificates` dict. backends: letsencrypt: *letsencrypt-backend-config* selfsigned: *selfsigned-backend-config* + ownca: *ownca-backend-config* # default options for certificates defaults: @@ -57,7 +58,7 @@ san: [] # services to restart if this certificate changes depending_services: [] -# which backend to use, can be 'selfsigned' or 'letsencrypt' +# which backend to use, can be 'selfsigned', 'letsencrypt' or 'ownca'' backend: 'selfsigned' # overwrite a backend setting for this certificate @@ -85,11 +86,34 @@ challangeserver: [] #### Selfsigned +*selfsigned-backend-config* + ``` # how long should the certificate be valid? not_after: "+3650d" ``` +#### Own CA + +*ownca-backend-config* + +``` +# how long should the certificate be valid? +not_after: "+3650d" + +# how long should the ca itself be valid? +ca_not_after: "+3650d" + +# delegate the CA to another host. Set to Null to disable and have the ca on the same host this role runs +remote: Null + +# base path to store the ca in +basepatht: "/etc/ssl/ca" + +# name of the ca, used in paths +name: "ownca" +``` + ## Paths Certificates are stored at a defined location: @@ -99,3 +123,12 @@ Certificates are stored at a defined location: * CSR: `/etc/ssl/.csr` * chain: `/etc/ssl/.chain.crt` * key, certificate and chain combined: `/etc/ssl/private/.complete.pem` + +Please note that "chain" contains the ca for self signed and "ownca" certificates to work around some stupid bugs. + +On the CA host for self signed certs those paths are used: + +* ca base path: `/` +* ca key: `/ca.key` +* ca cert: `/ca.crt` +* all signed certs: `/signed/` diff --git a/defaults/main.yml b/defaults/main.yml index d21ddb2..afe31d8 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,6 +6,12 @@ certificates: challangeserver: [] selfsigned: not_after: "+3650d" + ownca: + not_after: "+3650d" + ca_not_after: "+3650d" + remote: ~ + basepath: /etc/ssl/ca + name: ownca defaults: country: "SU" province: "CYBER" diff --git a/tasks/common_cert.yml b/tasks/common_cert.yml index e0c4e6a..9fc9281 100644 --- a/tasks/common_cert.yml +++ b/tasks/common_cert.yml @@ -3,6 +3,7 @@ - set_fact: cert_paths: csrpath: "{{ basepath + '/' + certname + '.csr' }}" + capath: "{{ basepath + '/' + certname + '.ca' }}" keypath: "{{ basepath + '/private/' + certname + '.key' }}" certpath: "{{ basepath + '/' + certname + '.crt' }}" chainpath: "{{ basepath + '/' + certname + '.chain.crt' }}" diff --git a/tasks/ownca_cert.yml b/tasks/ownca_cert.yml new file mode 100644 index 0000000..99440e2 --- /dev/null +++ b/tasks/ownca_cert.yml @@ -0,0 +1,118 @@ +- include_tasks: common_cert.yml + +- set_fact: + capath: "{{ cert_backend.basepath }}/{{ cert_backend.name }}" +- set_fact: + cacertpath: "{{ capath }}/ca.crt" + cakeypath: "{{ capath }}/ca.key" + cacsrpath: "{{ capath }}/ca.csr" + casignedpath: "{{ capath }}/signed" + remotecrtpath: "{{ capath }}/signed/{{ certname }}.crt" + remotecsrpath: "{{ capath }}/signed/{{ certname }}.csr" + +- name: slurp csr for {{ certname }} + slurp: + src: "{{ cert.csrpath }}" + register: csrfile + +- name: setup ca + delegate_to: "{{ cert_backend.remote|default(inventory_hostname, true) }}" + block: + - name: "setup base path for {{ cert_backend.name }} ({{ certname }})" + file: + path: "{{ cert_backend.basepath }}" + state: directory + mode: 755 + owner: root + group: root + - name: "setup ca path for {{ cert_backend.name }} ({{ certname }})" + file: + path: "{{ capath }}" + state: directory + mode: 0755 + owner: root + group: root + - name: "setup ca signed path for {{ cert_backend.name }} ({{ certname }})" + file: + path: "{{ casignedpath }}" + state: directory + mode: 0755 + owner: root + group: root + - name: "setup ca key {{ cert_backend.name }} ({{ certname }})" + openssl_privatekey: + path: "{{ cakeypath }}" + size: 4096 + type: RSA + mode: 0640 + owner: root + group: root + - name: "setup ca csr for {{ cert_backend.name }} ({{ certname }})" + openssl_csr: + path: "{{ cacsrpath }}" + privatekey_path: "{{ cakeypath }}" + - name: "self sign ca crt for {{ cert_backend.name }} ({{ certname }})" + openssl_certificate: + path: "{{ cacertpath }}" + privatekey_path: "{{ cakeypath }}" + csr_path: "{{ cacsrpath }}" + provider: selfsigned + selfsigned_not_after: "{{ cert_backend.ca_not_after }}" + - name: slurp ca crt for {{ cert_backend.name }} ({{ certname }})" + slurp: + src: "{{ cacertpath }}" + register: cafile + - name: "write csr to ca folder ({{ certname }})" + copy: + content: "{{ csrfile['content'] | b64decode }}" + dest: "{{ remotecsrpath }}" + - name: "sign certificate for {{ certname }}" + register: casignedsign + openssl_certificate: + path: "{{ remotecrtpath }}" + csr_path: "{{ remotecsrpath }}" + ownca_path: "{{ cacertpath }}" + ownca_privatekey_path: "{{ cakeypath }}" + provider: ownca + ownca_not_after: "{{ cert_backend.not_after }}" + - name: "copy crt from ca for {{ certname }}" + slurp: + src: "{{ remotecrtpath }}" + register: crtfile + +- name: "write crt ({{ certname }})" + copy: + content: "{{ crtfile['content'] | b64decode }}" + dest: "{{ cert.certpath }}" +- name: "write ca ({{ certname }})" + copy: + content: "{{ cafile['content'] | b64decode }}" + dest: "{{ cert.capath }}" +- name: "generate concatinated versions (chain) for {{ certname }}" + shell: "umask 0137; cat {{ cert.certpath }} {{ cert.capath }} > {{ cert.chainpath }}" + args: + creates: "{{ cert.chainpath }}" + +- name: "set permission for concatinated versions (chain) for {{ certname }}" + file: + path: "{{ cert.chainpath }}" + mode: 0644 + owner: root + group: ssl-cert + +- name: "generate concatinated versions (full) for {{ certname }}" + shell: "umask 0137; cat {{ cert.chainpath }} {{ cert.keypath }} > {{ cert.fullpath }}" + args: + creates: "{{ cert.fullpath }}" + +- name: "set permissions for concatinated versions (full) for {{ certname }}" + file: + path: "{{ cert.fullpath }}" + mode: 0640 + owner: root + group: ssl-cert + +- set_fact: + certchanged: "{{ casignedsign is changed }}" +- name: handle postflight + include: common_post.yml