From 817929becad49bb7d0b32b14373cb7cdafb40d0c Mon Sep 17 00:00:00 2001 From: Emilien Mantel Date: Fri, 20 Apr 2018 09:32:46 +0200 Subject: [PATCH] Add self-signed cert feature --- doc/ssl.md | 36 ++++++++++++++++++++++++++++++------ tasks/ssl/standard.yml | 10 ++++++++++ tests/test.yml | 8 ++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/doc/ssl.md b/doc/ssl.md index dd7a065..d95e6d1 100644 --- a/doc/ssl.md +++ b/doc/ssl.md @@ -15,25 +15,42 @@ Variables Cert/Key pairs -------------- -This list have 3 mandatory keys: +Each pair must have a `name`. +Note: `name` is used to deploy key/cert. With defaults values dans `name` = "foo", key is -> /etc/nginx/ssl/foo/foo.key -- `name`: MUST be unique +### Content mode + +Key/Cert content is stored in variable. Usefull with vault. - `key`: content of the private key - `cert`: content of the public key -OR +### Remote file + +You can use these variables if you use another task/role to manages your certificates. - `dest_cert`: remote path where certificate is located - `dest_key`: remote path where key is located -Note: `name` is used to deploy key/cert. With defaults values dans `name` = "foo", key is -> /etc/nginx/ssl/foo/foo.key +### Self signed + +Create a self-signed pair and deploy it. Do not use this feature in production. + +- `self_signed`: set true to use this featrure +- `force`: optional feature (default: false), force regen pair (not idempotent) + +### Acme + +Uses acme.sh to create free certificates. It uses HTTP-01 challenge. Use this feature for standalone servers. + +- `acme`: set true to use this feature. It uses `name` (can be a string or string list). + +Have a look to [acme configuratuion](acme.md configuration). Tips ---- -- Deploying key/cert is not mandatory with this role. You can manage it in other place ([letsencrypt](https://letsencrypt.org/)? :)). You just need to set `dest_cert` and `dest_key`! -- In `nginx_sites`, `ssl_name` is mandatory. This role will search in `nginx_ssl_pairs` with site `name` (first in list if it's a list). +- In `nginx_sites`, `ssl_name` is mandatory. This role will search in `nginx_ssl_pairs` with site `name` (first in list if it's a list). Diffie-Hellman -------------- @@ -55,6 +72,10 @@ nginx_sites; - name: 'test-ssl3.local' proto: ['http', 'https'] template: '_base' + - name: 'test-self-signed.local' + proto: ['http', 'https'] + template: '_base' + ssl_name: 'this.is.self.signed' nginx_ssl_pairs: - name: mysuperkey @@ -68,5 +89,8 @@ nginx_ssl_pairs: -----END CERTIFICATE----- - name: test-ssl2.local acme: true + - name: this.is.self.signed + self_signed: true + force: false ``` diff --git a/tasks/ssl/standard.yml b/tasks/ssl/standard.yml index 0f57687..d47e3a1 100644 --- a/tasks/ssl/standard.yml +++ b/tasks/ssl/standard.yml @@ -44,6 +44,16 @@ notify: restart nginx no_log: not nginx_debug_role +- name: COMMAND | Create self-signed certificates + command: "openssl req -new -newkey rsa:2048 -sha256 -days 3650 -nodes -x509 -subj '/CN={{ item | nginx_site_name }}' -keyout {{ item | nginx_site_name + '.key' }} -out {{ item | nginx_site_name + '.crt' }}" + args: + chdir: "{{ nginx_ssl_dir + '/' + item | nginx_site_name }}" + creates: "{% if item.force is defined and item.force %}/tmp/dummy{% else %}{{ nginx_ssl_dir + '/' + item | nginx_site_name + '/' + item | nginx_site_name + '.crt' }}{% endif %}" + with_items: "{{ nginx_ssl_pairs }}" + when: item.self_signed is defined + notify: restart nginx + no_log: not nginx_debug_role + - name: Check DH command status async_status: jid: "{{ dh.ansible_job_id }}" diff --git a/tests/test.yml b/tests/test.yml index 1e721e0..cf2d149 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -76,6 +76,9 @@ - '{{ ngrok.stdout }}' acme: true acme_port: 8888 + - name: 'test-ssl-selfsigned.local' + self_signed: true + force: false - name: 'test-ssl-predeployed.local' dest_key: "{{ int_ansible_ssl_dir }}/test.key" dest_cert: "{{ int_ansible_ssl_dir }}/test.crt" @@ -224,6 +227,9 @@ - name: 'test-ssl.local' proto: ['http', 'https'] template: '_base' + - name: 'test-ssl-selfsigned.local' + proto: ['http', 'https'] + template: '_base' - name: 'test-ssl-predeployed.local' proto: ['http', 'https'] template: '_base' @@ -292,6 +298,7 @@ - '/var/tmp' - '{{ nginx_root }}/test-htpasswd-all.local/public' - '{{ nginx_root }}/test-ssl.local/public' + - '{{ nginx_root }}/test-ssl-selfsigned.local/public' - '{{ nginx_root }}/test-ssl-predeployed.local/public' - '{{ nginx_root }}/test-ssl-proxy-protocol.local/public' - '{{ nginx_root }}/{{ ngrok.stdout }}/public' @@ -460,6 +467,7 @@ failed_when: sslok.content.find('Index HTML test OK') == -1 with_items: - 'test-ssl-predeployed.local' + - 'test-ssl-selfsigned.local' - 'test-ssl.local' - '{{ ngrok.stdout }}'