diff --git a/dev.yml b/dev.yml index 156e7fe0d4..277bfed932 100644 --- a/dev.yml +++ b/dev.yml @@ -15,9 +15,11 @@ - { role: php, tags: [php] } - { role: xdebug, tags: [php, xdebug] } - { role: memcached, tags: [memcached] } - - { role: nginx, tags: [nginx] } + - { role: nginx, tags: [nginx, wordpress, wordpress-setup] } - { role: logrotate, tags: [logrotate] } - { role: composer, tags: [composer] } - { role: wp-cli, tags: [wp-cli] } - { role: wordpress-setup, tags: [wordpress, wordpress-setup] } + - { role: manual-certificates, tags: [wordpress, wordpress-setup] } + - { role: self-signed-certificates, tags: [wordpress, wordpress-setup] } - { role: wordpress-install, tags: [wordpress, wordpress-install] } diff --git a/roles/manual-certificates/defaults/main.yml b/roles/manual-certificates/defaults/main.yml new file mode 100644 index 0000000000..750f071f63 --- /dev/null +++ b/roles/manual-certificates/defaults/main.yml @@ -0,0 +1,2 @@ +sites_using_manual_certificates: "[{% for name, site in wordpress_sites.iteritems() if site.ssl.enabled and site.ssl.provider | default('manual') == 'manual' %}'{{ name }}',{% endfor %}]" +site_uses_manual_certificates: ssl_enabled and item.value.ssl.provider | default('manual') == 'manual' diff --git a/roles/manual-certificates/tasks/certificates.yml b/roles/manual-certificates/tasks/certificates.yml new file mode 100644 index 0000000000..71182c441d --- /dev/null +++ b/roles/manual-certificates/tasks/certificates.yml @@ -0,0 +1,24 @@ +--- +- name: Ensure SSL directories exist + file: + path: "{{ nginx_ssl_path }}/manual-certificates" + state: directory + mode: 0700 + when: site_uses_manual_certificates + with_dict: "{{ wordpress_sites }}" + +- name: Copy SSL cert + copy: + src: "{{ item.value.ssl.cert }}" + dest: "{{ nginx_ssl_path }}/manual-certificates/{{ item.value.ssl.cert | basename }}" + mode: 0640 + with_dict: "{{ wordpress_sites }}" + when: site_uses_manual_certificates and item.value.ssl.cert is defined + +- name: Copy SSL key + copy: + src: "{{ item.value.ssl.key }}" + dest: "{{ nginx_ssl_path }}/manual-certificates/{{ item.value.ssl.key | basename }}" + mode: 0600 + with_dict: "{{ wordpress_sites }}" + when: site_uses_manual_certificates and item.value.ssl.key is defined diff --git a/roles/manual-certificates/tasks/main.yml b/roles/manual-certificates/tasks/main.yml new file mode 100644 index 0000000000..28d61e7442 --- /dev/null +++ b/roles/manual-certificates/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- import_tasks: certificates.yml +- import_tasks: nginx.yml diff --git a/roles/manual-certificates/tasks/nginx.yml b/roles/manual-certificates/tasks/nginx.yml new file mode 100644 index 0000000000..9b667acb77 --- /dev/null +++ b/roles/manual-certificates/tasks/nginx.yml @@ -0,0 +1,16 @@ +--- +- name: Ensure SSL includes.d directories exist + file: + path: "{{ nginx_path }}/includes.d/{{ item.key }}/ssl" + state: directory + mode: 0755 + when: site_uses_manual_certificates + with_dict: "{{ wordpress_sites }}" + +- name: Template Nginx SSL directives out to includes.d + template: + src: manual-certificates.conf.j2 + dest: "{{ nginx_path }}/includes.d/{{ item.key }}/ssl/manual-certificates.conf" + when: site_uses_manual_certificates + with_dict: "{{ wordpress_sites }}" + notify: reload nginx diff --git a/roles/manual-certificates/templates/manual-certificates.conf.j2 b/roles/manual-certificates/templates/manual-certificates.conf.j2 new file mode 100644 index 0000000000..9137bbdcdc --- /dev/null +++ b/roles/manual-certificates/templates/manual-certificates.conf.j2 @@ -0,0 +1,6 @@ +# {{ ansible_managed }} + +# Manual Certificates + +ssl_certificate {{ nginx_ssl_path }}/manual-certificates/{{ item.value.ssl.cert | basename }}; +ssl_certificate_key {{ nginx_ssl_path }}/manual-certificates/{{ item.value.ssl.key | basename }}; diff --git a/roles/self-signed-certificates/defaults/main.yml b/roles/self-signed-certificates/defaults/main.yml new file mode 100644 index 0000000000..24d440eb76 --- /dev/null +++ b/roles/self-signed-certificates/defaults/main.yml @@ -0,0 +1,2 @@ +sites_using_self_signed_certificates: "[{% for name, site in wordpress_sites.iteritems() if site.ssl.enabled and site.ssl.provider | default('manual') == 'self-signed' %}'{{ name }}',{% endfor %}]" +site_uses_self_signed_certificates: ssl_enabled and item.value.ssl.provider | default('manual') == 'self-signed' diff --git a/roles/self-signed-certificates/tasks/certificates.yml b/roles/self-signed-certificates/tasks/certificates.yml new file mode 100644 index 0000000000..c0c22d04ab --- /dev/null +++ b/roles/self-signed-certificates/tasks/certificates.yml @@ -0,0 +1,32 @@ +--- +- name: Ensure SSL directories exist + file: + path: "{{ nginx_ssl_path }}/self-signed-certificates" + state: directory + mode: 0700 + when: site_uses_self_signed_certificates + with_dict: "{{ wordpress_sites }}" + +- name: Generate private keys + openssl_privatekey: + path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.key" + with_dict: "{{ wordpress_sites }}" + when: site_uses_self_signed_certificates + +- name: Generate certificate signing requests + openssl_csr: + path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.csr" + privatekey_path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.key" + common_name: "{{ item.value.site_hosts[0].canonical }}" + subject_alt_name: "{{ site_hosts | union(multisite_subdomains_wildcards) | map('regex_replace', '(.*)', 'DNS:\\1') | join(',') }}" + with_dict: "{{ wordpress_sites }}" + when: site_uses_self_signed_certificates + +- name: Generate self-signed certificates + openssl_certificate: + path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.cert" + privatekey_path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.key" + csr_path: "{{ nginx_ssl_path }}/self-signed-certificates/{{ item.key | quote }}.csr" + provider: selfsigned + with_dict: "{{ wordpress_sites }}" + when: site_uses_self_signed_certificates diff --git a/roles/self-signed-certificates/tasks/main.yml b/roles/self-signed-certificates/tasks/main.yml new file mode 100644 index 0000000000..e68343fef9 --- /dev/null +++ b/roles/self-signed-certificates/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- import_tasks: setup.yml + when: sites_using_self_signed_certificates | count +- import_tasks: certificates.yml +- import_tasks: nginx.yml diff --git a/roles/self-signed-certificates/tasks/nginx.yml b/roles/self-signed-certificates/tasks/nginx.yml new file mode 100644 index 0000000000..a8a73cbc7b --- /dev/null +++ b/roles/self-signed-certificates/tasks/nginx.yml @@ -0,0 +1,16 @@ +--- +- name: Ensure SSL includes.d directories exist + file: + path: "{{ nginx_path }}/includes.d/{{ item.key }}/ssl" + state: directory + mode: 0755 + when: site_uses_self_signed_certificates + with_dict: "{{ wordpress_sites }}" + +- name: Template Nginx SSL directives out to includes.d + template: + src: self-signed-certificates.conf.j2 + dest: "{{ nginx_path }}/includes.d/{{ item.key }}/ssl/self-signed-certificates.conf" + when: site_uses_self_signed_certificates + with_dict: "{{ wordpress_sites }}" + notify: reload nginx diff --git a/roles/self-signed-certificates/tasks/setup.yml b/roles/self-signed-certificates/tasks/setup.yml new file mode 100644 index 0000000000..fd99dcdd63 --- /dev/null +++ b/roles/self-signed-certificates/tasks/setup.yml @@ -0,0 +1,12 @@ +--- +- name: Install python pip + apt: + name: python-pip + state: latest + update_cache: yes + cache_valid_time: "{{ apt_cache_valid_time }}" + +- name: Install pyOpenSSL + pip: + name: pyopenssl + state: latest diff --git a/roles/self-signed-certificates/templates/self-signed-certificates.conf.j2 b/roles/self-signed-certificates/templates/self-signed-certificates.conf.j2 new file mode 100644 index 0000000000..0f966999af --- /dev/null +++ b/roles/self-signed-certificates/templates/self-signed-certificates.conf.j2 @@ -0,0 +1,7 @@ +# {{ ansible_managed }} + +# Self-signed Certificates + +ssl_certificate {{ nginx_ssl_path }}/self-signed-certificates/{{ item.key }}.cert; +ssl_trusted_certificate {{ nginx_ssl_path }}/self-signed-certificates/{{ item.key }}.cert; +ssl_certificate_key {{ nginx_ssl_path }}/self-signed-certificates/{{ item.key }}.key; diff --git a/roles/wordpress-setup/tasks/main.yml b/roles/wordpress-setup/tasks/main.yml index 732d95e383..6080c2ef35 100644 --- a/roles/wordpress-setup/tasks/main.yml +++ b/roles/wordpress-setup/tasks/main.yml @@ -1,8 +1,6 @@ --- - import_tasks: database.yml tags: wordpress-setup-database -- import_tasks: self-signed-certificate.yml - tags: wordpress-setup-self-signed-certificate - import_tasks: nginx-client-cert.yml tags: wordpress-setup-nginx-client-cert diff --git a/roles/wordpress-setup/tasks/nginx.yml b/roles/wordpress-setup/tasks/nginx.yml index e2d9b58cc8..490602f5fc 100644 --- a/roles/wordpress-setup/tasks/nginx.yml +++ b/roles/wordpress-setup/tasks/nginx.yml @@ -1,22 +1,4 @@ --- -- name: Copy SSL cert - copy: - src: "{{ item.value.ssl.cert }}" - dest: "{{ nginx_ssl_path }}/{{ item.value.ssl.cert | basename }}" - mode: 0640 - with_dict: "{{ wordpress_sites }}" - when: ssl_enabled and item.value.ssl.cert is defined - notify: reload nginx - -- name: Copy SSL key - copy: - src: "{{ item.value.ssl.key }}" - dest: "{{ nginx_ssl_path }}/{{ item.value.ssl.key | basename }}" - mode: 0600 - with_dict: "{{ wordpress_sites }}" - when: ssl_enabled and item.value.ssl.key is defined - notify: reload nginx - - import_tasks: "{{ playbook_dir }}/roles/common/tasks/disable_challenge_sites.yml" - name: Create Nginx conf for challenges location diff --git a/roles/wordpress-setup/tasks/self-signed-certificate.yml b/roles/wordpress-setup/tasks/self-signed-certificate.yml deleted file mode 100644 index 80c6600cb1..0000000000 --- a/roles/wordpress-setup/tasks/self-signed-certificate.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- -- name: Generate self-signed certificates - shell: "openssl req -new -newkey rsa:2048 \ - -days 3650 -nodes -x509 -sha256 \ - -extensions req_ext -config <( \ -cat <<' EOF'\n -[req]\n -prompt = no\n -distinguished_name = req_dn\n -[req_dn]\n -commonName = {{ item.value.site_hosts[0].canonical }}\n -[req_ext]\n -subjectAltName = {{ site_hosts | union(multisite_subdomains_wildcards) | map('regex_replace', '(.*)', 'DNS:\\1') | join(',') }}\n -EOF\n - ) \ - -keyout {{ item.key | quote }}.key -out {{ item.key | quote }}.cert" - args: - executable: "/bin/bash" - chdir: "{{ nginx_ssl_path }}" - creates: "{{ item.key }}.*" - with_dict: "{{ wordpress_sites }}" - when: ssl_enabled and item.value.ssl.provider | default('manual') == 'self-signed' - notify: reload nginx diff --git a/roles/wordpress-setup/templates/wordpress-site.conf.j2 b/roles/wordpress-setup/templates/wordpress-site.conf.j2 index 3b8905846e..180fdeb4b8 100644 --- a/roles/wordpress-setup/templates/wordpress-site.conf.j2 +++ b/roles/wordpress-setup/templates/wordpress-site.conf.j2 @@ -85,20 +85,11 @@ server { ssl_client_certificate {{ nginx_ssl_path }}/client-{{ (item.value.ssl.client_cert_url | hash('md5'))[:7] }}.crt; {% endif -%} - {% if item.value.ssl.provider | default('manual') == 'manual' and item.value.ssl.cert is defined and item.value.ssl.key is defined -%} - ssl_certificate {{ nginx_path }}/ssl/{{ item.value.ssl.cert | basename }}; - ssl_certificate_key {{ nginx_path }}/ssl/{{ item.value.ssl.key | basename }}; - - {% elif item.value.ssl.provider | default('manual') == 'letsencrypt' -%} + {% if item.value.ssl.provider | default('manual') == 'letsencrypt' -%} ssl_certificate {{ nginx_path }}/ssl/letsencrypt/{{ item.key }}-{{ letsencrypt_cert_ids[item.key] }}-bundled.cert; ssl_certificate_key {{ nginx_path }}/ssl/letsencrypt/{{ item.key }}.key; - - {% elif item.value.ssl.provider | default('manual') == 'self-signed' -%} - ssl_certificate {{ nginx_path }}/ssl/{{ item.key }}.cert; - ssl_trusted_certificate {{ nginx_path }}/ssl/{{ item.key }}.cert; - ssl_certificate_key {{ nginx_path }}/ssl/{{ item.key }}.key; - {% endif -%} + {% endif -%} {% endblock -%} @@ -108,6 +99,7 @@ server { {% endblock -%} {% block includes_d -%} + include includes.d/{{ item.key }}/ssl/*.conf; include includes.d/{{ item.key }}/*.conf; {% endblock -%} diff --git a/server.yml b/server.yml index bd181f1f96..85f548e5bf 100644 --- a/server.yml +++ b/server.yml @@ -34,9 +34,11 @@ - { role: ssmtp, tags: [ssmtp, mail] } - { role: php, tags: [php] } - { role: memcached, tags: [memcached] } - - { role: nginx, tags: [nginx] } + - { role: nginx, tags: [nginx, wordpress, wordpress-setup] } - { role: logrotate, tags: [logrotate] } - { role: composer, tags: [composer] } - { role: wp-cli, tags: [wp-cli] } - - { role: letsencrypt, tags: [letsencrypt], when: sites_using_letsencrypt | count } + - { role: letsencrypt, tags: [wordpress, wordpress-setup, letsencrypt], when: sites_using_letsencrypt | count } - { role: wordpress-setup, tags: [wordpress, wordpress-setup, letsencrypt] } + - { role: manual-certificates, tags: [wordpress, wordpress-setup, letsencrypt] } + - { role: self-signed-certificates, tags: [wordpress, wordpress-setup, letsencrypt] }