diff --git a/CHANGELOG.md b/CHANGELOG.md index f8581c1d6f..7ce7814c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### HEAD +* `reverse_www` filter improvements (ignore subdomains) ([#525](https://github.com/roots/trellis/pull/525)) * Fix #520 - Disable MariaDB binary logging by default ([#521](https://github.com/roots/trellis/pull/521)) * Let's Encrypt integration ([#518](https://github.com/roots/trellis/pull/518)) * Improve Git repo format validation [#516](https://github.com/roots/trellis/pull/516) diff --git a/filter_plugins/trellis_filters.py b/filter_plugins/trellis_filters.py index 91c5485e83..8eca6de8d1 100644 --- a/filter_plugins/trellis_filters.py +++ b/filter_plugins/trellis_filters.py @@ -7,26 +7,36 @@ from ansible import errors from ansible.compat.six import string_types -def reverse_www(value): +def reverse_www(hosts, enabled=True, append=True): ''' Add or remove www subdomain ''' - # Check if value is a list and parse each item - if isinstance(value, (list, tuple, types.GeneratorType)): - values = [] - for item in value: - values.append(reverse_www(item)) - return values + if not enabled: + return hosts + + # Check if hosts is a list and parse each host + if isinstance(hosts, (list, tuple, types.GeneratorType)): + reversed_hosts = [reverse_www(host) for host in hosts] + + if append: + return list(set(hosts + reversed_hosts)) + else: + return reversed_hosts # Add or remove www - elif isinstance(value, string_types): - if value.startswith('www.'): - return value[4:] + elif isinstance(hosts, string_types): + host = hosts + + if len(host.split('.')) > 2: + return host + + if host.startswith('www.'): + return host[4:] else: - return 'www.{0}'.format(value) + return 'www.{0}'.format(host) # Handle invalid input type else: - raise errors.AnsibleFilterError('The reverse_www filter expects a string or list of strings, got ' + repr(value)) + raise errors.AnsibleFilterError('The reverse_www filter expects a string or list of strings, got ' + repr(hosts)) class FilterModule(object): diff --git a/roles/letsencrypt/tasks/certificates.yml b/roles/letsencrypt/tasks/certificates.yml index 898c1bde0a..c0ce8eb5ad 100644 --- a/roles/letsencrypt/tasks/certificates.yml +++ b/roles/letsencrypt/tasks/certificates.yml @@ -22,8 +22,8 @@ with_dict: "{{ wordpress_sites }}" tags: [letsencrypt_keys] -- name: Generate CSRs for multi domain keys or single domain with "reverse www" domains - shell: "openssl req -new -sha256 -key '{{ letsencrypt_keys_dir }}/{{ item.key }}.key' -subj '/' -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:{{ item.value.site_hosts | join(',DNS:') }},DNS:{{ item.value.site_hosts | reverse_www | join(',DNS:') }}')) > {{ acme_tiny_data_directory }}/csrs/{{ item.key }}.csr" +- name: Generate CSRs for multiple domain keys + shell: "openssl req -new -sha256 -key '{{ letsencrypt_keys_dir }}/{{ item.key }}.key' -subj '/' -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:{{ item.value.site_hosts | reverse_www(enabled=item.value.www_redirect | default(true)) | join(',DNS:') }}')) > {{ acme_tiny_data_directory }}/csrs/{{ item.key }}.csr" args: executable: /bin/bash creates: "{{ acme_tiny_data_directory }}/csrs/{{ item.key }}.csr" @@ -31,15 +31,6 @@ with_dict: "{{ wordpress_sites }}" tags: [letsencrypt_keys] -- name: Generate CSRs for multi domain keys without "reverse www" domains - shell: "openssl req -new -sha256 -key '{{ letsencrypt_keys_dir }}/{{ item.key }}.key' -subj '/' -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:{{ item.value.site_hosts | join(',DNS:') }}')) > {{ acme_tiny_data_directory }}/csrs/{{ item.key }}.csr" - args: - executable: /bin/bash - creates: "{{ acme_tiny_data_directory }}/csrs/{{ item.key }}.csr" - when: site_uses_letsencrypt and item.value.site_hosts | length > 1 and not item.value.www_redirect | default(true) - with_dict: "{{ wordpress_sites }}" - tags: [letsencrypt_keys] - - name: Generate the initial certificate command: ./renew-certs.py args: diff --git a/roles/letsencrypt/templates/nginx-challenge-site.conf.j2 b/roles/letsencrypt/templates/nginx-challenge-site.conf.j2 index aead863f7e..7b80c271ce 100644 --- a/roles/letsencrypt/templates/nginx-challenge-site.conf.j2 +++ b/roles/letsencrypt/templates/nginx-challenge-site.conf.j2 @@ -1,11 +1,5 @@ server { listen 80; - - {% if item.item.value.www_redirect | default(true) -%} - server_name {{ item.item.value.site_hosts | join(' ') }} {{ item.item.value.site_hosts | reverse_www | join(' ') }}; - {% else -%} - server_name {{ item.item.value.site_hosts | join(' ') }}; - {% endif %} - + server_name {{ item.item.value.site_hosts | reverse_www(enabled=item.item.value.www_redirect | default(true)) | join(' ') }}; include acme-challenge-location.conf; } diff --git a/roles/wordpress-setup/templates/wordpress-site.conf.j2 b/roles/wordpress-setup/templates/wordpress-site.conf.j2 index 1f3c941264..ec016c6702 100644 --- a/roles/wordpress-setup/templates/wordpress-site.conf.j2 +++ b/roles/wordpress-setup/templates/wordpress-site.conf.j2 @@ -94,15 +94,11 @@ server { } } -{% if item.value.ssl is defined and item.value.ssl.enabled | default(False) %} +{% if item.value.ssl is defined and item.value.ssl.enabled | default(false) %} server { listen 80; - {% if item.value.www_redirect | default(true) -%} - server_name {{ item.value.site_hosts | join(' ') }} {{ item.value.site_hosts | reverse_www | join(' ') }}; - {% else -%} - server_name {{ item.value.site_hosts | join(' ') }}; - {% endif %} + server_name {{ item.value.site_hosts | reverse_www(enabled=item.value.www_redirect | default(true)) | join(' ') }}; {% if item.value.ssl.provider | default('manual') == 'letsencrypt' -%} include acme-challenge-location.conf; @@ -124,7 +120,7 @@ server { listen 80; {% endif -%} - server_name {{ host | reverse_www }}; + server_name {{ host | reverse_www(append=false) }}; return 301 $scheme://{{ host }}$request_uri; } {% endfor %}