From 76dcb7a40cfb5e3297309a6ede91a5828e6f60d7 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Wed, 4 Jan 2017 13:21:03 +0100 Subject: [PATCH 01/21] Add the `apache__mpm_max_connections_per_child` variable --- CHANGES.rst | 4 ++++ defaults/main.yml | 17 +++++++++++++++++ docs/getting-started.rst | 4 ++-- docs/includes/role.rst | 2 ++ .../conf-available/local-debops_apache.conf.j2 | 2 ++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 814c897..afe6a4a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -23,6 +23,10 @@ Added configurable via :ref:`item.http_referrer_policy `. [ypid_] +- Add the :envvar:`apache__mpm_max_connections_per_child` variable to allow to + configure the number of requests a child process should handle before + terminating. [ypid_] + Fixed ~~~~~ diff --git a/defaults/main.yml b/defaults/main.yml index 2dfccc9..aa3bd86 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -279,6 +279,23 @@ apache__security_module_enabled: False # Refer to the `ModSecurity SecServerSignature directive documentation`_. # This directive is not set if the special value ``omit`` is set. apache__security_module_server_signature: '{{ omit }}' + # ]]] + # ]]] +# Multi-processing module [[[ +# --------------------------- + +# Selection of the MPM to use is leaved to Debian package maintainer scripts +# which will select a suitable MPM. +# Note that some Apache modules can depend on certain MPMs being used which +# will be configured in the package maintainer scripts of those modules. +# + +# .. envvar:: apache__mpm_max_connections_per_child [[[ +# +# Number of requests a child process will handle before terminating. +# Refer to the `Apache MaxConnectionsPerChild directive documentation`_ for details. +apache__mpm_max_connections_per_child: '0' + # ]]] # ]]] # Configuration snippets [[[ diff --git a/docs/getting-started.rst b/docs/getting-started.rst index e49f1a5..a7114c6 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -1,11 +1,11 @@ Getting started =============== +.. include:: includes/all.rst + .. contents:: :local: -.. include:: includes/all.rst - Example inventory ----------------- diff --git a/docs/includes/role.rst b/docs/includes/role.rst index 3c72640..2315331 100644 --- a/docs/includes/role.rst +++ b/docs/includes/role.rst @@ -28,3 +28,5 @@ .. _Apache AllowOverride directive documentation: https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride .. _Apache Options directive documentation: https://httpd.apache.org/docs/2.4/mod/core.html#options .. _ModSecurity SecServerSignature directive documentation: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#secserversignature +.. _Apache MaxConnectionsPerChild directive documentation: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxconnectionsperchild +.. _Apache MaxRequestWorkers directive documentation: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxrequestworkers diff --git a/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 b/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 index 1056516..e089863 100644 --- a/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 +++ b/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 @@ -9,6 +9,8 @@ # It is probably not good practice to change that in server context anyway. #} +MaxConnectionsPerChild {{ apache__mpm_max_connections_per_child | quote }} + {% for module_name, value in apache__combined_modules|dictsort %} {% if value is mapping and 'config' in value %} From 98e39f04c797098256b016795739f5b0cb5c862c Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Wed, 4 Jan 2017 13:22:13 +0100 Subject: [PATCH 02/21] Move OCSP Stapling default vars below basic TLS configuration First should be the basics, followed by the advanced stuff. --- defaults/main.yml | 94 +++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index aa3bd86..45a5276 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -438,53 +438,6 @@ apache__pki_trusted_filename: '{{ ansible_local.pki.trusted else "trusted.crt" }}' # ]]] # ]]] -# OCSP Stapling [[[ -# ~~~~~~~~~~~~~~~~~ - -# .. envvar:: apache__ocsp_stapling_enabled [[[ -# -# Enable or disable OCSP Stapling. -# Refer to the `Apache SSLUseStapling directive documentation`_ for details. -apache__ocsp_stapling_enabled: True - - # ]]] -# .. envvar:: apache__ocsp_stapling_cache [[[ -# -# Cache used to store OCSP responses which get included in the TLS handshake. -# Refer to the `Apache SSLStaplingCache directive documentation`_ for details. -apache__ocsp_stapling_cache: 'shmcb:${APACHE_RUN_DIR}/ocsp_scache(512000)' - - # ]]] -# .. envvar:: apache__ocsp_stapling_response_max_age [[[ -# -# This option sets the maximum allowable age ("freshness") when considering -# OCSP responses, in seconds. -# Refer to the `Apache SSLStaplingResponseMaxAge directive documentation`_ for details. -# The default update interval of `Let's Encrypt`_ is 7 days. -# Ref: `Is there a rate limit on OCSP requests? `_ -# Enforcing 30 days as default should be a good start compared to the -# Apache default which imposes no limit. -apache__ocsp_stapling_response_max_age: '{{ 30 * 24 * 3600 }}' - - # ]]] -# .. envvar:: apache__ocsp_stapling_force_url [[[ -# -# This directive overrides the URI of an OCSP responder as obtained from the -# authorityInfoAccess (AIA) extension of the certificate. One potential use is -# when a proxy is used for retrieving OCSP queries. -# Refer to the `Apache SSLStaplingForceURL directive documentation`_ for details. -apache__ocsp_stapling_force_url: False - - # ]]] -# .. envvar:: apache__ocsp_stapling_verify [[[ -# -# Verify OCSP responses from the server which requires chained intermediate and -# Root CA certificates. -# Note: Currently not implemented. -# Ref: https://github.com/debops/ansible-apache/issues/2 -apache__ocsp_stapling_verify: '{{ apache__ocsp_stapling_enabled | bool }}' - # ]]] - # ]]] # TLS ciphers and protocol versions [[[ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -568,6 +521,53 @@ apache__tls_dhparam_file: '{{ ansible_local.dhparam[apache__tls_dhparam_set_name else "" }}' # ]]] # ]]] +# OCSP Stapling [[[ +# ~~~~~~~~~~~~~~~~~ + +# .. envvar:: apache__ocsp_stapling_enabled [[[ +# +# Enable or disable OCSP Stapling. +# Refer to the `Apache SSLUseStapling directive documentation`_ for details. +apache__ocsp_stapling_enabled: True + + # ]]] +# .. envvar:: apache__ocsp_stapling_cache [[[ +# +# Cache used to store OCSP responses which get included in the TLS handshake. +# Refer to the `Apache SSLStaplingCache directive documentation`_ for details. +apache__ocsp_stapling_cache: 'shmcb:${APACHE_RUN_DIR}/ocsp_scache(512000)' + + # ]]] +# .. envvar:: apache__ocsp_stapling_response_max_age [[[ +# +# This option sets the maximum allowable age ("freshness") when considering +# OCSP responses, in seconds. +# Refer to the `Apache SSLStaplingResponseMaxAge directive documentation`_ for details. +# The default update interval of `Let's Encrypt`_ is 7 days. +# Ref: `Is there a rate limit on OCSP requests? `_ +# Enforcing 30 days as default should be a good start compared to the +# Apache default which imposes no limit. +apache__ocsp_stapling_response_max_age: '{{ 30 * 24 * 3600 }}' + + # ]]] +# .. envvar:: apache__ocsp_stapling_force_url [[[ +# +# This directive overrides the URI of an OCSP responder as obtained from the +# authorityInfoAccess (AIA) extension of the certificate. One potential use is +# when a proxy is used for retrieving OCSP queries. +# Refer to the `Apache SSLStaplingForceURL directive documentation`_ for details. +apache__ocsp_stapling_force_url: False + + # ]]] +# .. envvar:: apache__ocsp_stapling_verify [[[ +# +# Verify OCSP responses from the server which requires chained intermediate and +# Root CA certificates. +# Note: Currently not implemented. +# Ref: https://github.com/debops/ansible-apache/issues/2 +apache__ocsp_stapling_verify: '{{ apache__ocsp_stapling_enabled | bool }}' + # ]]] + # ]]] # HTTPS related security headers [[[ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 6d97fe5704a0bce29f18bcb501683d0dcadeeff6 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Wed, 4 Jan 2017 13:37:53 +0100 Subject: [PATCH 03/21] Ensure that the shared object cache provider is loaded when required --- CHANGES.rst | 4 ++++ defaults/main.yml | 5 +++++ docs/defaults-detailed.rst | 1 + tasks/main.yml | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index afe6a4a..1998a09 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -35,3 +35,7 @@ Fixed Note that all dependency variables should be passed to the main ``debops.apache`` role to avoid confusion. :envvar:`apache__dependent_packages` now only works when passed to the main role. + +- Ensure that the shared object cache provider module is loaded when required + for :envvar:`apache__ocsp_stapling_cache`. Before, the ``socache_shmcb`` + module was implicitly loaded by the ``ssl`` module. [ypid_] diff --git a/defaults/main.yml b/defaults/main.yml index 45a5276..8496da2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -253,6 +253,11 @@ apache__role_modules: enabled: '{{ True if (apache__https_listen) else False }}' 'security2': enabled: '{{ apache__security_module_enabled|bool }}' + 'socache_shmcb': + enabled: '{{ True + if (apache__ocsp_stapling_enabled|bool + and "shmcb" in apache__ocsp_stapling_cache) + else omit }}' # ]]] # .. envvar:: apache__combined_modules [[[ diff --git a/docs/defaults-detailed.rst b/docs/defaults-detailed.rst index 5ff96d0..0cc1007 100644 --- a/docs/defaults-detailed.rst +++ b/docs/defaults-detailed.rst @@ -41,6 +41,7 @@ supported options: ``enabled`` Required, boolean. Defaults to ``True``. + Set to ``{{ omit }}`` not change the state of a module. Whether the module should be enabled or disabled in Apache. ``force`` diff --git a/tasks/main.yml b/tasks/main.yml index 8779672..1a3b360 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -33,7 +33,7 @@ else item.value) | bool | ternary("present", "absent") }}' force: '{{ item.value.force|d(False) | bool }}' notify: [ 'Test apache and reload' ] - when: (item.key in apache__tpl_available_modules) + when: (item.key in apache__tpl_available_modules and item.value.enabled|d(True) != omit) with_dict: '{{ apache__combined_modules }}' tags: [ 'role::apache:modules' ] From 014abc8320f2c8e71d55e0d629c165e27b4289b2 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 13:47:35 +0100 Subject: [PATCH 04/21] Change default virtual host to `default.{{ + apache__domain }}` --- CHANGES.rst | 8 ++++++++ defaults/main.yml | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1998a09..caa04aa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -27,6 +27,14 @@ Added configure the number of requests a child process should handle before terminating. [ypid_] +Changed +~~~~~~~ + +- Change default virtual host server name from ``000-default`` to ``default.{{ + apache__domain }}`` to increase the changes that a valid certificate is + available for this virtual host (either wildcard or SAN) in order to avoid + the warning of Apache that the certificate is not valid for the server name. [ypid_] + Fixed ~~~~~ diff --git a/defaults/main.yml b/defaults/main.yml index 8496da2..4d95676 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -63,6 +63,15 @@ apache__fqdn: '{{ ansible_local.core.fqdn ansible_local.core.fqdn|d()) else ansible_fqdn }}' + # ]]] +# .. envvar:: apache__domain [[[ +# +# The domain name of the host running Apache. +apache__domain: '{{ ansible_local.core.domain + if (ansible_local|d() and ansible_local.core|d() and + ansible_local.core.domain|d()) + else ansible_domain }}' + # ]]] # .. envvar:: apache__config_path [[[ # @@ -672,9 +681,18 @@ apache__vhosts: [] # Default virtual host which will receive all requests which don’t match other virtual hosts. # Refer to the `Apache virtual host matching documentation`_ for details. apache__default_vhost: - name: '000-default' + name: '{{ apache__default_vhost_name }}' + filename: '000-default' root: '/var/www/html' + # ]]] +# .. envvar:: apache__default_vhost_name [[[ +# +# Default virtual host name. +# Ideally, this a FQDN for which a valid certificate is present so that Apache +# does not complain about a certificate subject mismatch. +apache__default_vhost_name: 'default.{{ apache__domain }}' + # ]]] # .. envvar:: apache__group_vhosts [[[ # From 83d3086872ee351640fce4548ad1c5ef05feff5d Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 13:49:31 +0100 Subject: [PATCH 05/21] Add support to enable and configure Apache mod_status --- CHANGES.rst | 7 + COPYRIGHT | 4 +- defaults/main.yml | 121 ++++++++++++++++-- docs/ansible-integration.rst | 8 +- docs/defaults-detailed.rst | 52 +++++++- docs/includes/role.rst | 7 + handlers/main.yml | 16 ++- tasks/main.yml | 2 +- .../local-debops_apache.conf.j2 | 6 + .../sites-available/apache__tpl_macros.j2 | 66 ++++++++-- .../sites-available/debops__tpl_macros.j2 | 14 +- .../apache2/sites-available/default.conf.j2 | 35 ++--- 12 files changed, 284 insertions(+), 54 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index caa04aa..bcc221a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -27,6 +27,10 @@ Added configure the number of requests a child process should handle before terminating. [ypid_] +- Add support to enable and configure `Apache mod_status`_. You can set + :envvar:`apache__status_enabled` to ``True`` to enable it and make the status + page accessible from localhost. [ypid_] + Changed ~~~~~~~ @@ -47,3 +51,6 @@ Fixed - Ensure that the shared object cache provider module is loaded when required for :envvar:`apache__ocsp_stapling_cache`. Before, the ``socache_shmcb`` module was implicitly loaded by the ``ssl`` module. [ypid_] + +- Fix ``item.https_enabled`` support for virtual hosts. This variable was + ignored previously using the global default (``True``) directly. [ypid_] diff --git a/COPYRIGHT b/COPYRIGHT index 62b1d87..7f97f93 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,7 +1,7 @@ debops.apache - Manage and configure the Apache HTTP Server -Copyright (C) 2016 Robin Schneider -Copyright (C) 2016 DebOps https://debops.org/ +Copyright (C) 2016-2017 Robin Schneider +Copyright (C) 2016-2017 DebOps https://debops.org/ This Ansible role is part of DebOps. diff --git a/defaults/main.yml b/defaults/main.yml index 4d95676..f74f764 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -102,7 +102,8 @@ apache__server_name: '{{ apache__fqdn }}' # # Default server admin contact information. Either a Email address or a URL # (preferable on another webserver if this one fails). -# Can be overwritten for virtual hosts. +# Refer to :ref:`item.server_admin ` for +# how to overwrite this for a virtual host. apache__server_admin: '{{ ansible_local.core.admin_public_email[0] if (ansible_local|d() and ansible_local.core|d() and ansible_local.core.admin_public_email|d()) @@ -160,7 +161,7 @@ apache__https_listen: [ 443 ] # # Refer to `Apache DirectoryMatch directive documentation`_ for details. -# .. envvar:: apache__role_directory_match [[[ +# .. envvar:: apache__default_directory_match [[[ # # Default ``DirectoryMatch`` directives maintained by this Ansible role. apache__default_directory_match: @@ -262,10 +263,22 @@ apache__role_modules: enabled: '{{ True if (apache__https_listen) else False }}' 'security2': enabled: '{{ apache__security_module_enabled|bool }}' + 'status': + enabled: '{{ apache__status_enabled|bool }}' + config: | + + # Revoke default permissions granted in `/etc/apache2/mods-available/status.conf`. + Require all denied + 'socache_shmcb': enabled: '{{ True if (apache__ocsp_stapling_enabled|bool and "shmcb" in apache__ocsp_stapling_cache) + else omit }}' + 'authz_host': + enabled: '{{ True + if (apache__status_enabled|bool + and apache__status_allow_localhost) else omit }}' # ]]] @@ -309,7 +322,6 @@ apache__security_module_server_signature: '{{ omit }}' # Number of requests a child process will handle before terminating. # Refer to the `Apache MaxConnectionsPerChild directive documentation`_ for details. apache__mpm_max_connections_per_child: '0' - # ]]] # ]]] # Configuration snippets [[[ @@ -469,7 +481,6 @@ apache__tls_protocols: [ 'All', '-SSLv2', '-SSLv3' ] apache__tls_cipher_suite_set_name: 'bettercrypto_org__set_b_pfs' # ]]] - # .. envvar:: apache__tls_cipher_suite_sets [[[ # # Dictionary of TLS cipher suites which can be selected from @@ -509,7 +520,6 @@ apache__tls_honor_cipher_order: 'on' # Whether compression is enabled or disabled on the TLS level. # Refer to the `Apache SSLCompression directive documentation`_ for details. apache__tls_compression: 'off' - # ]]] # ]]] # Key exchange (Diffie–Hellman) [[[ @@ -612,7 +622,6 @@ apache__hsts_subdomains: True # Refer to the `HSTS Preload List Submission`_ page to make use of this # feature. apache__hsts_preload: True - # ]]] # ]]] # ]]] @@ -729,6 +738,7 @@ apache__role_vhosts: Divert the package provided `default-ssl` site file away, we will not need it :) - '{{ apache__default_vhost }}' + - '{{ apache__status_vhost }}' # ]]] # .. envvar:: apache__dependent_vhosts [[[ @@ -768,7 +778,6 @@ apache__vhost_allow_override: 'None' # The default ``Options`` to use for virtual hosts. # Refer to the `Apache Options directive documentation`_ for details. apache__vhost_options: [ '+FollowSymLinks' ] - # ]]] # ]]] # Logging [[[ @@ -779,6 +788,7 @@ apache__vhost_options: [ '+FollowSymLinks' ] # The default log level to use. # Refer to the `Apache LogLevel directive documentation`_ for details. apache__log_level: 'warn' + # ]]] # .. envvar:: apache__access_log_format [[[ # @@ -787,6 +797,102 @@ apache__log_level: 'warn' apache__access_log_format: 'combined' # ]]] # ]]] +# Apache Status [[[ +# ----------------- + +# Refer to the `Apache mod_status documentation`_ for details. + +# .. envvar:: apache__status_enabled [[[ +# +# Should the Apache server status be enabled by loading the required modules? +apache__status_enabled: False + + # ]]] +# .. envvar:: apache__status_vhost_enabled [[[ +# +# Should the Apache server status page be accessible using a independent +# virtual host bound to localhost? +apache__status_vhost_enabled: '{{ apache__status_enabled }}' + + # ]]] +# .. envvar:: apache__status_for_vhost_enabled [[[ +# +# Should the Apache server status page be enabled in all virtual hosts? +# +# Note that even when this option evaluates to ``False``, the hardcoded +# ``/server-status`` URL path is not fully neutralized. That is because the `Apache +# SetHandler directive`_ is set by the Apache Debian package in server config +# context. All access granted by package defaults is of course revoked by this +# Ansible role, again in server config context. But this means that for any +# virtual host, a request against ``/server-status`` (regardless of the value +# of :envvar:`apache__status_location`) will be answered with a 403 Forbidden. +# If that causes a problem, the role could be changed to not enable the default +# module configuration and load the module directly from server config context. +# Or maybe someone has a workaround which does not involve changing the package +# module defaults. +# +# Refer to :ref:`item.status_enabled ` for +# how to overwrite this for a virtual host. +apache__status_for_vhost_enabled: False + + # ]]] +# .. envvar:: apache__status_location [[[ +# +# The ``Location`` or URL path by which the Apache server status should be +# accessible. +# Refer to :ref:`item.status_location ` for +# how to overwrite this for a virtual host. +apache__status_location: '/server-status' + + # ]]] +# .. envvar:: apache__status_allow_localhost [[[ +# +# Allow access to the Apache server status using the ``Require local`` +# directive (refer to the `Apache host Require directive documentation`_). +# Refer to :ref:`item.status_allow_localhost ` for +# how to overwrite this for a virtual host. +apache__status_allow_localhost: False + + # ]]] +# .. envvar:: apache__status_directives [[[ +# +# Additional directives included into the ``Location`` sections for the Apache +# server status configuration. Can be used to customize access for example. +# Refer to :ref:`item.status_directives ` for +# how to overwrite this for a virtual host. +apache__status_directives: '' + + # ]]] +# .. envvar:: apache__status_extended_enabled [[[ +# +# This option tracks additional data per worker about the currently executing +# request and creates a utilization summary. +# Refer to the `Apache ExtendedStatus directive documentation`_ for details. +# Note that this setting cannot be changed during a graceful restart. You will +# need to restart Apache yourself for a change to take effect! +apache__status_extended_enabled: '{{ apache__status_enabled|bool }}' + + # ]]] +# .. envvar:: apache__status_vhost_name [[[ +# +# Virtual host name for providing the Apache server status. +apache__status_vhost_name: + - 'localhost' + + # ]]] +# .. envvar:: apache__status_vhost [[[ +# +# Optional virtual host for providing the Apache server status. +apache__status_vhost: + name: '{{ apache__status_vhost_name }}' + filename: 'debops.apache-status' + status_enabled: True + status_allow_localhost: True + listen_http: [ 'localhost:80' ] + https_enabled: False + enabled: '{{ apache__status_vhost_enabled|bool }}' + # ]]] + # ]]] # Configuration for other Ansible roles [[[ # ----------------------------------------- @@ -803,7 +909,6 @@ apache__ferm__dependent_rules: by_role: 'debops.apache' name: 'http_https' multiport: True - # ]]] # ]]] # ]]] diff --git a/docs/ansible-integration.rst b/docs/ansible-integration.rst index 454a38e..f75541b 100644 --- a/docs/ansible-integration.rst +++ b/docs/ansible-integration.rst @@ -10,7 +10,7 @@ Design goals In particular the :file:`/etc/apache2/apache2.conf` is not altered. * The ``IfVersion`` directive is not used to keep the number of enabled modules as minimum as possible. Instead the configuration is generated for the - currently detected Apache version. + currently detected Apache version. FIXME, version_module is compiled in :) * Most variables which directly correspond to a Apache directive are not masked or otherwise changed (for example using ``True``, ``False`` for directives which expect ``on``, ``off`` is *not* supported). @@ -21,6 +21,12 @@ Design goals special variable ``omit`` (use in Jinja: ``{{ omit }}``) is intended to be used when the directive should be omitted (not written to the Apache configuration at all). +* Apache is not restarted by the role because that would require to close + established connections. Some configuration options require a restart to take + effect. The documentation for those options should give a hint about it. You + should test your settings with a test system and do a restart in production + manually when required. + Optionally, it should be possible to allow restarts using inventory variables. Alternative roles diff --git a/docs/defaults-detailed.rst b/docs/defaults-detailed.rst index 0cc1007..9277ff2 100644 --- a/docs/defaults-detailed.rst +++ b/docs/defaults-detailed.rst @@ -99,8 +99,8 @@ supported options: Whether the module should be ``present`` or ``absent`` in the :file:`conf-available` directory. ``type`` - Optional, string. Specify name of the template to use to generate the virtual - host configuration. Templates can extend other templates. + Optional, string. + Refer to the following subsections for the supported type. Type: raw @@ -147,6 +147,16 @@ same filename as the snippet which is diverted away. Allows to specify a full file path where to divert the file to. Note that the ``item.divert_suffix`` is still in affect when using this option. + +Type: dont-created +~~~~~~~~~~~~~~~~~~ + +This special type assumes the snippet file is already present and does not try +to create it. +This can be used to enable or disable snippet files managed by system packages +for example. + + Examples ~~~~~~~~ @@ -222,6 +232,8 @@ Common role options Common webserver options ~~~~~~~~~~~~~~~~~~~~~~~~ +.. _apache__ref_vhost_server_admin: + ``server_admin`` Optional, string. Defaults to :envvar:`apache__server_admin`. @@ -429,6 +441,42 @@ HTTP security headers draft as of 2016-10-11 but it is already supported by the majority of web browsers. + +.. _apache__ref_vhosts_apache_status: + +Apache status +~~~~~~~~~~~~~ + +.. _apache__ref_vhosts_status_enabled: + +``status_enabled`` + Optional, boolean. Should the Apache server status be enabled? + Defaults to :envvar:`apache__status_enabled`. + +.. _apache__ref_vhosts_status_location: + +``status_location`` + Optional, string. + The ``Location`` or URL path by which the Apache server status should be + accessible. + Defaults to :envvar:`apache__status_location`. + +.. _apache__ref_vhosts_status_allow_localhost: + +``status_allow_localhost`` + Optional, boolean. + Allow access to the Apache server status using the ``Require local`` + directive. + Defaults to :envvar:`apache__status_allow_localhost`. + +.. _apache__ref_vhosts_status_directives: + +``status_directives`` + Optional, string. + Additional directives included into the ``Location`` sections for the Apache + server status configuration. Can be used to customize access for example. + Defaults to :envvar:`apache__status_directives`. + Type: raw ~~~~~~~~~ diff --git a/docs/includes/role.rst b/docs/includes/role.rst index 2315331..0a59ee0 100644 --- a/docs/includes/role.rst +++ b/docs/includes/role.rst @@ -30,3 +30,10 @@ .. _ModSecurity SecServerSignature directive documentation: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#secserversignature .. _Apache MaxConnectionsPerChild directive documentation: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxconnectionsperchild .. _Apache MaxRequestWorkers directive documentation: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxrequestworkers +.. _Apache mod_status documentation: https://httpd.apache.org/docs/current/mod/mod_status.html +.. _Apache mod_status: https://httpd.apache.org/docs/current/mod/mod_status.html +.. _Apache Location directive: https://httpd.apache.org/docs/current/mod/core.html#location +.. _Apache Location directives: https://httpd.apache.org/docs/current/mod/core.html#location +.. _Apache ExtendedStatus directive documentation: https://httpd.apache.org/docs/current/mod/core.html#extendedstatus +.. _Apache host Require directive documentation: https://httpd.apache.org/docs/current/mod/mod_authz_host.html#requiredirectives +.. _Apache SetHandler directive: https://httpd.apache.org/docs/current/mod/core.html#sethandler diff --git a/handlers/main.yml b/handlers/main.yml index 109c06f..d9257c3 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -4,16 +4,18 @@ command: apache2ctl configtest notify: [ 'Reload apache' ] -- name: Test apache and restart - command: apache2ctl configtest - notify: [ 'Restart apache' ] +# - name: Test apache and restart +# command: apache2ctl configtest +# notify: [ 'Restart apache' ] - name: Reload apache service: name: '{{ apache__service_name }}' state: 'reloaded' -- name: Restart apache - service: - name: '{{ apache__service_name }}' - state: 'restarted' +## Listed here for completeness but not used. +## Refer to ../docs/ansible-integration.rst +# - name: Restart apache +# service: +# name: '{{ apache__service_name }}' +# state: 'restarted' diff --git a/tasks/main.yml b/tasks/main.yml index 1a3b360..72a6095 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -65,7 +65,7 @@ group: 'root' mode: '0644' when: (item.value.state|d("present") != "absent" and - (item.value.type|d("default") not in ["divert"] or item.value.raw|d())) + (item.value.type|d("default") not in ["divert", "dont-created"] or item.value.raw|d())) with_dict: '{{ apache__combined_snippets }}' notify: [ 'Test apache and reload' ] diff --git a/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 b/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 index e089863..11c1835 100644 --- a/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 +++ b/templates/etc/apache2/conf-available/local-debops_apache.conf.j2 @@ -11,6 +11,9 @@ MaxConnectionsPerChild {{ apache__mpm_max_connections_per_child | quote }} +ExtendedStatus {{ apache__status_extended_enabled|bool | ternary("On", "Off") }} + + {% for module_name, value in apache__combined_modules|dictsort %} {% if value is mapping and 'config' in value %} @@ -27,6 +30,8 @@ LogLevel {{ apache__log_level }} {{ apache__tpl_macros.get_common_headers(item) | indent(4) }} +{# Don’t use apache__combined_modules because of heavy use of template macros. #} + {{ apache__tpl_macros.get_default_tls_directives(item.value|d({})) }} {% if debops__tpl_macros.get_openssl_version()|version_compare("0.9.8h", ">=") %} @@ -35,4 +40,5 @@ SSLStaplingResponseMaxAge {{ apache__ocsp_stapling_response_max_age|string }} {% if apache__ocsp_stapling_force_url %} SSLStaplingForceURL {{ apache__ocsp_stapling_force_url | quote }} {% endif %} + {% endif %} diff --git a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 index beb5bed..4a7bcef 100644 --- a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 @@ -47,6 +47,45 @@ CustomLog ${APACHE_LOG_DIR}/{{ sanitized_name }}_access.log {{ apache__access_lo ErrorLog ${APACHE_LOG_DIR}/{{ sanitized_name }}_error.log {% endmacro %}{# ]]] #} +{% macro get_server_status_directives(item, enabled) %}{# [[[ #} +{% if enabled|bool %} + + SetHandler server-status +{% if item.status_allow_localhost|d(apache__status_allow_localhost) | bool %} + Require local +{% endif %} +{% if item.status_directives|d(apache__status_directives) %} + {{ item.status_directives|d(apache__status_directives) }} +{% elif not (item.status_allow_localhost|d(apache__status_allow_localhost) | bool) %} + Require all denied +{% endif %} + +{% endif %} +{% endmacro %}{# ]]] #} + +{% macro get_vhost_content_directives(item, mode='https', https_enabled=True) %}{# [[[ #} +{% set apache__tpl_use_redirect_module = 'alias' %} +{% set apache__tpl_status_enabled = item.status_enabled|d(apache__status_for_vhost_enabled) | bool %} +{{ get_server_status_directives(item, apache__tpl_status_enabled) -}} +{% if apache__tpl_status_enabled|bool and ( + (mode == 'http' and (item.redirect_http|d() or item.redirect_to_https|d(https_enabled) | bool)) or + (mode == 'https' and item.redirect_https|d()) + ) %} +RewriteEngine On +RewriteRule "^{{ item.status_location|d(apache__status_location) }}" "-" [L] +{% set apache__tpl_use_redirect_module = 'rewrite' %} +{% endif %} +{% if mode == 'http' and item.redirect_http|d() %} +{{ get_redirect(item.redirect_http_code|d(307), "/", item.redirect_http, apache__tpl_use_redirect_module) }} +{% elif mode == 'http' and item.redirect_to_https|d(https_enabled) | bool %} +{{ get_redirect(item.redirect_to_https_with_code|d("301"), "/", "https://" + (debops__tpl_macros.get_yaml_list_for_elem(item.name) | from_yaml)[0], apache__tpl_use_redirect_module) }} +{% elif mode == 'https' and item.redirect_https|d() %} +{{ get_redirect(item.redirect_https_code|d(307), "/", item.redirect_https, apache__tpl_use_redirect_module) }} +{% else %} +{{ get_content_directives(item) }} +{% endif %} +{% endmacro %}{# ]]] #} + {% macro get_content_directives(item) %}{# [[[ #} {% if item.include|d() %} {% for include_file in debops__tpl_macros.get_yaml_list_for_elem(item.include)|from_yaml %} @@ -65,18 +104,18 @@ DocumentRoot {{ item.root|d(item.document_root) | quote }} {{ get_alias(item.alias, item.root|d(item.document_root)) }} {%- endif %} - Options {{ debops__tpl_macros.get_yaml_list_for_elem(item.options|d(apache__vhost_options))|from_yaml | join(" ") }} - AllowOverride {{ debops__tpl_macros.get_yaml_list_for_elem(item.allow_override|d(apache__vhost_allow_override))|from_yaml | join(" ") }} +Options {{ debops__tpl_macros.get_yaml_list_for_elem(item.options|d(apache__vhost_options))|from_yaml | join(" ") }} +AllowOverride {{ debops__tpl_macros.get_yaml_list_for_elem(item.allow_override|d(apache__vhost_allow_override))|from_yaml | join(" ") }} {% if debops__tpl_macros.get_apache_version() | version_compare("2.4", ">=") %} - Require all granted +Require all granted {% else %} - Order allow,deny - Allow from all +Order allow,deny +Allow from all {% endif %} {% if item.root_directives|d() %} - {{ item.root_directives | indent(4) }} +{{ item.root_directives }} {% endif %} @@ -89,7 +128,7 @@ DocumentRoot {{ item.root|d(item.document_root) | quote }} {% macro get_default_tls_directives(item) %}{# [[[ #} {# Included in server context to provide sane defaults (there might be vhosts -# not controled by this template) and virtual host context to ensure those +# not controled by this template) and in virtual host context to ensure those # settings are appliend and to allow per-vhost changes. # Refer to Applied-Crypto-Hardening_bettercrypto/src/configuration/Webservers/Apache/default-ssl for details. #} @@ -164,8 +203,17 @@ Header always set X-Clacks-Overhead "GNU Terry Pratchett" {% endif %} {% endmacro %}{# ]]] #} -{% macro get_redirect(code, from, to) %}{# [[[ #} -Redirect {{ code|string }} "{{ from }}" "{{ to + ("/" if (to[-1] != "/") else "") }}" +{% macro get_redirect(code, from, to, module) %}{# [[[ #} +{# Prefer the alias module but support the use of the rewrite module in case +other rewrite rules are used in the same context because the rewrite rules are +handled before all the directives from the alias module. +#} +{% set to = to + ("/" if (to[-1] != "/") else "") %} +{% if module == 'alias' %} +Redirect {{ code|string }} "{{ from }}" "{{ to }}" +{% elif module == 'rewrite' %} +RewriteRule "^{{ from }}?(.*)" "{{ to }}$1" [L,R={{ code }},NE] +{% endif %} {% endmacro %}{# ]]] #} {% macro get_alias(url_path, fs_directory) %}{# [[[ #} diff --git a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 index 4dbbde6..e029fca 100644 --- a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 @@ -5,8 +5,8 @@ # Changes to this file should go upstream: FIXME # # Copyright (C) 2014-2016 Maciej Delmanowski -# Copyright (C) 2015-2016 Robin Schneider -# Copyright (C) 2014-2016 DebOps https://debops.org/ +# Copyright (C) 2015-2017 Robin Schneider +# Copyright (C) 2014-2017 DebOps https://debops.org/ # # This file is part of DebOps. # @@ -66,3 +66,13 @@ ansible_local.pki.gnutls_version|d()) else "0.0.0" }} {% endmacro %}{# ]]] #} + +{% macro indent(content, width=4, indentfirst=False) %}{# [[[ #} +{# Fixed version of the `indent` filter which does not insert trailing spaces on empty lines. +## Note that you can not use this macro like filter but have to use it like a regular macro. +## Example: {{ debops__tpl_macros.indent(some_content, 4) }} +## +## Python re.sub seems to default to re.MULTILINE in Ansible. +#} +{{ content | indent(width, indentfirst) | regex_replace("[ \\t\\r\\f\\v]+(\\n|$)", "\\1") }} +{% endmacro %}{# ]]] #} diff --git a/templates/etc/apache2/sites-available/default.conf.j2 b/templates/etc/apache2/sites-available/default.conf.j2 index 6279bfb..28792da 100644 --- a/templates/etc/apache2/sites-available/default.conf.j2 +++ b/templates/etc/apache2/sites-available/default.conf.j2 @@ -2,44 +2,35 @@ # vim: foldmarker=[[[,]]]:foldmethod=marker {% import 'debops__tpl_macros.j2' as debops__tpl_macros with context %} {% import 'apache__tpl_macros.j2' as apache__tpl_macros with context %} +{% set apache__tpl_vhost_http_enabled = True if (apache__tpl_macros.get_listen_sockets(item.listen_http|d([]), apache__http_listen)) else False %} +{% set apache__tpl_vhost_https_enabled = True if (item.https_enabled|d(apache__https_enabled)|bool and apache__tpl_macros.get_listen_sockets(item.listen_https|d([]), apache__https_listen)) else False %} {{ apache__tpl_macros.get_header_comments(item) }} -{% if apache__tpl_macros.get_listen_sockets(item.listen_http|d([]), apache__http_listen) %} +{% if apache__tpl_vhost_http_enabled|bool %} # Virtual host handling HTTP [[[ - {{ apache__tpl_macros.get_server_directives(item) | indent(4) }} - -{% if item.redirect_http|d() %} - {{ apache__tpl_macros.get_redirect( item.redirect_http_code|d(307), "/", item.redirect_http) | indent(4) }} -{% elif item.redirect_to_https|d(True) | bool %} - Redirect {{ item.redirect_to_https_with_code|d("301") }} "/" "https://{{ (debops__tpl_macros.get_yaml_list_for_elem(item.name) | from_yaml)[0] }}/" -{% else %} - {{ apache__tpl_macros.get_content_directives(item) | indent(4) }} -{% endif %} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_server_directives(item), 4) }} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_vhost_content_directives(item, mode='http', https_enabled=apache__tpl_vhost_https_enabled), 4) }} # ]]] {% endif %} -{% if apache__https_enabled|bool and apache__tpl_macros.get_listen_sockets(item.listen_https|d([]), apache__https_listen) %} +{% if apache__tpl_vhost_https_enabled|bool %} # Virtual host handling HTTPS [[[ + - {{ apache__tpl_macros.get_server_directives(item) | indent(4) }} - + {{ debops__tpl_macros.indent(apache__tpl_macros.get_server_directives(item), 4) }} - {{ apache__tpl_macros.get_https_directives(item) | indent(4) }} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_https_directives(item), 4) }} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_http_security_headers(item), 4) }} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_common_headers(item), 4) }} - {{ apache__tpl_macros.get_http_security_headers(item) | indent(4) }} - {{ apache__tpl_macros.get_common_headers(item) | indent(4) }} - -{% if item.redirect_https|d() %} - {{ apache__tpl_macros.get_redirect( item.redirect_https_code|d(307), "/", item.redirect_https) | indent(4) }} -{% else %} - {{ apache__tpl_macros.get_content_directives(item) | indent(4) }} -{% endif %} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_vhost_content_directives(item, mode='https'), 4) }} + # ]]] {% endif %} From dccad54743a87c4ffea8b7d3c1d15e58118305ff Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 17:04:45 +0100 Subject: [PATCH 06/21] Support generic Apache template generation using the IfVersion directive --- CHANGES.rst | 4 ++ defaults/main.yml | 47 +++++++++++++ docs/ansible-integration.rst | 3 - docs/includes/role.rst | 2 + docs/introduction.rst | 3 +- meta/ansigenome.yml | 3 +- templates/etc/ansible/facts.d/apache.fact.j2 | 6 ++ .../sites-available/apache__tpl_macros.j2 | 68 +++++++++++++++++-- .../sites-available/debops__tpl_macros.j2 | 11 ++- .../apache2/sites-available/default.conf.j2 | 1 + 10 files changed, 135 insertions(+), 13 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index bcc221a..39852de 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -31,6 +31,10 @@ Added :envvar:`apache__status_enabled` to ``True`` to enable it and make the status page accessible from localhost. [ypid_] +- Add support for generic Apache template generation using the `Apache IfVersion directive`_. + This feature can be configured by :envvar:`apache__config_use_if_version` and + :envvar:`apache__config_min_version`. [ypid_] + Changed ~~~~~~~ diff --git a/defaults/main.yml b/defaults/main.yml index f74f764..8dd408d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -149,6 +149,53 @@ apache__http_listen: [ 80 ] # List of transport layer ports to listen on for HTTPS connections. # Note that changing this variable is currently not supported. apache__https_listen: [ 443 ] + + # ]]] +# .. envvar:: apache__config_use_if_version [[[ +# +# Should the `Apache IfVersion directive` be used to generate a generic form +# of the Apache configuration? +# +# ``True`` +# Default. +# Use the `Apache IfVersion directive` to generate a configuration which is +# intended to work with as many Apache versions as this role supports. +# +# This has the advantage that if your Apache version does not already support +# all features which this role is able to configure then you can upgrade +# Apache independently of this role and the new features will be used in +# Apache as soon as a recent enough version of Apache starts up. +# +# Note however that it is still recommended to rerun this role against your +# host after version upgrades because if certain features are enabled might +# not depend on the Apache version alone. For example the version of the used +# cryptography library (OpenSSL) is also relevant and checked by this role at +# Ansible role execution. +# +# ``False`` +# The configuration is specifically generated for the Apache version which +# is detected at Ansible role execution time. +# +# This has the advantage that the generated configuration is potentially +# smaller and easier to read. +# +apache__config_use_if_version: True + + # ]]] +# .. envvar:: apache__config_min_version [[[ +# +# Specifies the minimum Apache version to support when +# :envvar:`apache__config_use_if_version` is set to ``True``. +# By default, this defaults to the current Apache major and minor version +# because ``major.minor`` version downgrades are considered uncommon and to +# avoid too much legacy directives. +# +# Supported special strings: +# +# ``current_major_minor`` +# Gets replaced by the currently detected ``major.minor`` version. +# +apache__config_min_version: 'current_major_minor' # ]]] # ]]] # Filesystem access [[[ diff --git a/docs/ansible-integration.rst b/docs/ansible-integration.rst index f75541b..3c8adc1 100644 --- a/docs/ansible-integration.rst +++ b/docs/ansible-integration.rst @@ -8,9 +8,6 @@ Design goals * Try not to modify/replace configuration files which are maintained by Debian. In particular the :file:`/etc/apache2/apache2.conf` is not altered. -* The ``IfVersion`` directive is not used to keep the number of enabled modules - as minimum as possible. Instead the configuration is generated for the - currently detected Apache version. FIXME, version_module is compiled in :) * Most variables which directly correspond to a Apache directive are not masked or otherwise changed (for example using ``True``, ``False`` for directives which expect ``on``, ``off`` is *not* supported). diff --git a/docs/includes/role.rst b/docs/includes/role.rst index 0a59ee0..4570317 100644 --- a/docs/includes/role.rst +++ b/docs/includes/role.rst @@ -32,6 +32,8 @@ .. _Apache MaxRequestWorkers directive documentation: https://httpd.apache.org/docs/current/mod/mpm_common.html#maxrequestworkers .. _Apache mod_status documentation: https://httpd.apache.org/docs/current/mod/mod_status.html .. _Apache mod_status: https://httpd.apache.org/docs/current/mod/mod_status.html +.. _Apache mod_version: https://httpd.apache.org/docs/current/mod/mod_version.html +.. _Apache IfVersion directive: https://httpd.apache.org/docs/current/mod/mod_version.html#ifversion .. _Apache Location directive: https://httpd.apache.org/docs/current/mod/core.html#location .. _Apache Location directives: https://httpd.apache.org/docs/current/mod/core.html#location .. _Apache ExtendedStatus directive documentation: https://httpd.apache.org/docs/current/mod/core.html#extendedstatus diff --git a/docs/introduction.rst b/docs/introduction.rst index f044738..b231921 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -3,7 +3,8 @@ Introduction .. include:: includes/all.rst -The ``debops.apache`` role allows you to setup and mange the `Apache HTTP Server`_. +The ``debops.apache`` role allows you to setup and mange the `Apache HTTP Server`_ +with version 2.4 and above. Installation diff --git a/meta/ansigenome.yml b/meta/ansigenome.yml index 581c3a2..4f8d9a5 100644 --- a/meta/ansigenome.yml +++ b/meta/ansigenome.yml @@ -16,6 +16,7 @@ ansigenome_info: github: 'ypid' synopsis: | - The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server]. + The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server] + with version 2.4 and above. [Apache HTTP Server]: https://en.wikipedia.org/wiki/Apache_HTTP_Server diff --git a/templates/etc/ansible/facts.d/apache.fact.j2 b/templates/etc/ansible/facts.d/apache.fact.j2 index f0b2cd5..80b8893 100644 --- a/templates/etc/ansible/facts.d/apache.fact.j2 +++ b/templates/etc/ansible/facts.d/apache.fact.j2 @@ -10,6 +10,8 @@ import re output = loads('''{{ ({ "enabled": (apache__deploy_state == "present"), "user": apache__user, + "use_if_version": apache__config_use_if_version, + "min_version": apache__config_min_version, }) | to_nice_json }}''') try: @@ -20,4 +22,8 @@ try: except: pass +if output['use_if_version']: + if output['min_version'] == 'current_major_minor': + output['min_version'] = '.'.join(output['version'].split('.')[:2]) + print(dumps(output, sort_keys=True, indent=2)) diff --git a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 index 4a7bcef..a770df0 100644 --- a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 @@ -2,6 +2,65 @@ #} {% import 'debops__tpl_macros.j2' as debops__tpl_macros with context %} +{% macro get_min_version_wrapped(content, version, compare_operator) %}{# [[[ #} +{# Examples: + +{{ get_min_version_wrapped('# 2.3.0 directive', "2.3", ">=") }} +{{ get_min_version_wrapped('# 2.4.0 directive', "2.4", ">=") }} +{{ get_min_version_wrapped('# 2.4.1 directive', "2.4.1", ">=") }} +{{ get_min_version_wrapped('# 2.5.0 directive', "2.5", ">=") }} + +#} +{% set version = '==' if (version == '=') else version %} +{% set apache__tpl_compare_operator_includes_equal = True if (compare_operator in ['>=', '<=', '==']) else False %} +{% if (version | version_compare(debops__tpl_macros.get_apache_min_version(), compare_operator)) + or (version | version_compare(debops__tpl_macros.get_apache_min_version(), ">")) %} +{% if apache__tpl_compare_operator_includes_equal and (version | version_compare(debops__tpl_macros.get_apache_min_version(), "==")) %} +{{ content -}} +{% else %} + + {{ debops__tpl_macros.indent(content, 4) }} + +{% endif %} +{% endif %} +{% endmacro %}{# ]]] #} + +{% macro get_version_wrapped(content, version, compare_operator, fallback_content=False) %}{# [[[ #} +{# This macro has not been extensivly tested yet. If it contains bugs please try to debug it if you need it. + +Examples: + +{{ get_version_wrapped('# 2.3.0 directive', "2.3", ">=", '# Prior to 2.3 directive') }} +{{ get_version_wrapped('# 2.4.0 directive', "2.4", ">=", '# Prior to 2.4 directive') }} +{{ get_version_wrapped('# 2.4.1 directive', "2.4.1", ">=", '# Prior to 2.4.1 directive') }} +{{ get_version_wrapped('# 2.5.0 directive', "2.5", ">=", '# Prior to 2.5 directive') }} + +#} +{% set version = '==' if (version == '=') else version %} +{% set apache__tpl_xor_compare_operator_map = {} %} +{% set apache__tpl_xor_compare_operator_list = [ + ('==', '!='), + ('>=', '<'), + ('<=', '>'), +] %} +{% for compare_operator, xor_compare_operator in apache__tpl_xor_compare_operator_list %} +{% set _ = apache__tpl_xor_compare_operator_map.update({ compare_operator: xor_compare_operator }) %} +{% set _ = apache__tpl_xor_compare_operator_map.update({ xor_compare_operator: compare_operator }) %} +{% endfor %} +{% if apache__config_use_if_version|bool %} +{{ get_min_version_wrapped(content, version, compare_operator) -}} +{% if fallback_content != False %} +{{ get_min_version_wrapped(fallback_content, version, apache__tpl_xor_compare_operator_map[compare_operator]) -}} +{% endif %} +{% else %} +{% if debops__tpl_macros.get_apache_version() | version_compare(version, compare_operator) %} +{{ content -}} +{% elif fallback_content != False %} +{{ fallback_content -}} +{% endif %} +{% endif %} +{% endmacro %}{# ]]] #} + {% macro get_server_name_aliases(name_item) %}{# [[[ #} {% set apache__tpl_names = debops__tpl_macros.get_yaml_list_for_elem(name_item) | from_yaml %} {% if not apache__tpl_names %} @@ -107,12 +166,9 @@ DocumentRoot {{ item.root|d(item.document_root) | quote }} Options {{ debops__tpl_macros.get_yaml_list_for_elem(item.options|d(apache__vhost_options))|from_yaml | join(" ") }} AllowOverride {{ debops__tpl_macros.get_yaml_list_for_elem(item.allow_override|d(apache__vhost_allow_override))|from_yaml | join(" ") }} -{% if debops__tpl_macros.get_apache_version() | version_compare("2.4", ">=") %} -Require all granted -{% else %} -Order allow,deny -Allow from all -{% endif %} +{{ get_version_wrapped('Require all granted', "2.4", ">=", +'Order allow,deny +Allow from all') }} {% if item.root_directives|d() %} {{ item.root_directives }} diff --git a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 index e029fca..522ea77 100644 --- a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 @@ -50,7 +50,14 @@ {{ ansible_local.apache.version if (ansible_local|d() and ansible_local.apache|d() and ansible_local.apache.version|d()) - else "2.4.0" }} + else "2.4.0" -}} +{% endmacro %}{# ]]] #} + +{% macro get_apache_min_version() %}{# [[[ #} +{{ ansible_local.apache.min_version + if (ansible_local|d() and ansible_local.apache|d() and + ansible_local.apache.min_version|d()) + else "2.4.0" -}} {% endmacro %}{# ]]] #} {% macro get_openssl_version() %}{# [[[ #} @@ -74,5 +81,5 @@ ## ## Python re.sub seems to default to re.MULTILINE in Ansible. #} -{{ content | indent(width, indentfirst) | regex_replace("[ \\t\\r\\f\\v]+(\\n|$)", "\\1") }} +{{ content | indent(width, indentfirst) | regex_replace("[ \\t\\r\\f\\v]+(\\n|$)", "\\1") -}} {% endmacro %}{# ]]] #} diff --git a/templates/etc/apache2/sites-available/default.conf.j2 b/templates/etc/apache2/sites-available/default.conf.j2 index 28792da..d3de1f2 100644 --- a/templates/etc/apache2/sites-available/default.conf.j2 +++ b/templates/etc/apache2/sites-available/default.conf.j2 @@ -11,6 +11,7 @@ {{ debops__tpl_macros.indent(apache__tpl_macros.get_server_directives(item), 4) }} + {{ debops__tpl_macros.indent(apache__tpl_macros.get_vhost_content_directives(item, mode='http', https_enabled=apache__tpl_vhost_https_enabled), 4) }} From c6d7cb836d93ad0ab0efab244fa1b17186532117 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 17:05:57 +0100 Subject: [PATCH 07/21] Regen README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ff7b7d9..75c7f83 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ [![Ansible Galaxy](https://img.shields.io/badge/galaxy-debops.apache-660198.svg?style=flat)](https://galaxy.ansible.com/debops/apache) -The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server]. +The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server] +with version 2.4 and above. [Apache HTTP Server]: https://en.wikipedia.org/wiki/Apache_HTTP_Server @@ -47,4 +48,4 @@ License: [GPL-3.0](https://tldrlegal.com/license/gnu-general-public-license-v3-% *** -This role is part of the [DebOps](https://debops.org/) project. README generated by [ansigenome](https://github.com/nickjj/ansigenome/). +This role is part of [DebOps](https://debops.org/). README generated by [ansigenome](https://github.com/nickjj/ansigenome/). From 7cc530d37e6e587f27b2fd1bfe17b8eb1fa04a3d Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 18:41:12 +0100 Subject: [PATCH 08/21] Fix indention of directives applied to the root dir of vhosts --- .../sites-available/apache__tpl_macros.j2 | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 index a770df0..3291601 100644 --- a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 @@ -145,6 +145,19 @@ RewriteRule "^{{ item.status_location|d(apache__status_location) }}" "-" [L] {% endif %} {% endmacro %}{# ]]] #} +{% macro get_document_root_directives(item) %}{# [[[ #} +Options {{ debops__tpl_macros.get_yaml_list_for_elem(item.options|d(apache__vhost_options))|from_yaml | join(" ") }} +AllowOverride {{ debops__tpl_macros.get_yaml_list_for_elem(item.allow_override|d(apache__vhost_allow_override))|from_yaml | join(" ") }} + +{{ get_version_wrapped('Require all granted', "2.4", ">=", +'Order allow,deny +Allow from all') -}} +{% if item.root_directives|d() %} + +{{ item.root_directives }} +{% endif %} +{% endmacro %}{# ]]] #} + {% macro get_content_directives(item) %}{# [[[ #} {% if item.include|d() %} {% for include_file in debops__tpl_macros.get_yaml_list_for_elem(item.include)|from_yaml %} @@ -163,17 +176,7 @@ DocumentRoot {{ item.root|d(item.document_root) | quote }} {{ get_alias(item.alias, item.root|d(item.document_root)) }} {%- endif %} -Options {{ debops__tpl_macros.get_yaml_list_for_elem(item.options|d(apache__vhost_options))|from_yaml | join(" ") }} -AllowOverride {{ debops__tpl_macros.get_yaml_list_for_elem(item.allow_override|d(apache__vhost_allow_override))|from_yaml | join(" ") }} - -{{ get_version_wrapped('Require all granted', "2.4", ">=", -'Order allow,deny -Allow from all') }} -{% if item.root_directives|d() %} - -{{ item.root_directives }} -{% endif %} - + {{ debops__tpl_macros.indent(get_document_root_directives(item), 4) -}} {% endif %} {% if item.raw_content|d() %} From 3f7d6ab551aa42b3bdbcd7b8fff852b52157b52e Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 18:52:10 +0100 Subject: [PATCH 09/21] Fix spelling in docs --- defaults/main.yml | 13 ++++++++++--- docs/ansible-integration.rst | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 8dd408d..0dedbcc 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -47,7 +47,11 @@ apache__dependent_packages: [] # # .. code-block:: shell # -# for file in /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/000-default.conf /etc/apache2/conf-available/security.conf; do dpkg-divert --remove $file; done && rm /etc/apache2 -rf +# for file in /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/000-default.conf /etc/apache2/conf-available/security.conf +# do +# dpkg-divert --remove $file +# done +# rm /etc/apache2 -rf # apache__deploy_state: 'present' # ]]] @@ -168,7 +172,7 @@ apache__https_listen: [ 443 ] # # Note however that it is still recommended to rerun this role against your # host after version upgrades because if certain features are enabled might -# not depend on the Apache version alone. For example the version of the used +# not only depend on the Apache version. For example the version of the used # cryptography library (OpenSSL) is also relevant and checked by this role at # Ansible role execution. # @@ -186,9 +190,12 @@ apache__config_use_if_version: True # # Specifies the minimum Apache version to support when # :envvar:`apache__config_use_if_version` is set to ``True``. -# By default, this defaults to the current Apache major and minor version +# By default, this defaults to the current Apache major and minor version detected # because ``major.minor`` version downgrades are considered uncommon and to # avoid too much legacy directives. +# (You can still do such downgrades if the role supports the Apache version +# you are downgrading to but then you might need to rerun the role so that a +# suitable configuration can be generated.) # # Supported special strings: # diff --git a/docs/ansible-integration.rst b/docs/ansible-integration.rst index 3c8adc1..dbb7c30 100644 --- a/docs/ansible-integration.rst +++ b/docs/ansible-integration.rst @@ -29,7 +29,7 @@ Design goals Alternative roles ----------------- -Has `Ansible Galaxy`_ an impressive number of Ansible roles for Apache to your +`Ansible Galaxy`_ has an impressive number of Ansible roles for Apache at your disposal. A few of them have been checked out before/while writing this role: * `geerlingguy.apache `_ @@ -37,5 +37,5 @@ disposal. A few of them have been checked out before/while writing this role: * And peeked at a few more. However, none of the already existing roles where found to be a suitable start for -Apache support in Debops so this role has been designed and written from scratch. +Apache support in DebOps so this role has been designed and written from scratch. Unfortunately, that workflow is not uncommon considering the quality requirements and standards of DebOps. From 15a1227bed15378f2c8260905ba7f8098f1cbd8d Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 19:20:15 +0100 Subject: [PATCH 10/21] Change `apache__hsts_preload` from `True` to `False` by default --- CHANGES.rst | 7 +++++++ defaults/main.yml | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 39852de..ec112bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -43,6 +43,13 @@ Changed available for this virtual host (either wildcard or SAN) in order to avoid the warning of Apache that the certificate is not valid for the server name. [ypid_] +- Change :envvar:`apache__hsts_preload` from ``True`` to ``False`` by default. + Setting this value to ``True`` alone does not achieve anything and can + actually cause problems if you are not prepared. + Thus it is disabled by default. + If you are ready for the future of HTTPS and TLS only, you are encouraged to + enable it! [ypid_] + Fixed ~~~~~ diff --git a/defaults/main.yml b/defaults/main.yml index 0dedbcc..2f959aa 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -672,10 +672,14 @@ apache__hsts_subdomains: True # ]]] # .. envvar:: apache__hsts_preload [[[ # -# Should the preload parameter be added to the HSTS header? +# Should the ``preload`` parameter be added to the HSTS header? # Refer to the `HSTS Preload List Submission`_ page to make use of this # feature. -apache__hsts_preload: True +# It is disabled by default because setting this to ``True`` alone does +# nothing, it is just one requirement to get included in the preloading list. +# Please feel encouraged to get to know HSTS preloading and enable it when you +# are ready! +apache__hsts_preload: False # ]]] # ]]] # ]]] From 505e6f2915f00a4f3eba1608095b431a84ab1959 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 19:26:06 +0100 Subject: [PATCH 11/21] Fix spelling of apache__snippets type introduced in this branch --- docs/defaults-detailed.rst | 4 ++-- tasks/main.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/defaults-detailed.rst b/docs/defaults-detailed.rst index 9277ff2..d5c6fd8 100644 --- a/docs/defaults-detailed.rst +++ b/docs/defaults-detailed.rst @@ -148,8 +148,8 @@ same filename as the snippet which is diverted away. Note that the ``item.divert_suffix`` is still in affect when using this option. -Type: dont-created -~~~~~~~~~~~~~~~~~~ +Type: dont-create +~~~~~~~~~~~~~~~~~ This special type assumes the snippet file is already present and does not try to create it. diff --git a/tasks/main.yml b/tasks/main.yml index 72a6095..934332a 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -65,7 +65,7 @@ group: 'root' mode: '0644' when: (item.value.state|d("present") != "absent" and - (item.value.type|d("default") not in ["divert", "dont-created"] or item.value.raw|d())) + (item.value.type|d("default") not in ["divert", "dont-create"] or item.value.raw|d())) with_dict: '{{ apache__combined_snippets }}' notify: [ 'Test apache and reload' ] From bbd9061eb3396e7bbec875544d95bd8206bab32c Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Mon, 9 Jan 2017 19:30:18 +0100 Subject: [PATCH 12/21] Use singular apache__ref_vhost_ label as docs anchor s/apache__ref_vhosts_/apache__ref_vhost_/g --- CHANGES.rst | 2 +- defaults/main.yml | 12 ++++++------ docs/defaults-detailed.rst | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ec112bc..4952ce5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -20,7 +20,7 @@ Added - Initial coding and design. [ypid_] - Add/Set the default `Referrer Policy`_ to ``no-referrer`` and made it - configurable via :ref:`item.http_referrer_policy `. + configurable via :ref:`item.http_referrer_policy `. [ypid_] - Add the :envvar:`apache__mpm_max_connections_per_child` variable to allow to diff --git a/defaults/main.yml b/defaults/main.yml index 2f959aa..7137afb 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -701,13 +701,13 @@ apache__http_frame_options: 'SAMEORIGIN' # ]]] # .. envvar:: apache__http_xss_protection [[[ # -# Refer to :ref:`item.http_xss_protection ` for details. +# Refer to :ref:`item.http_xss_protection ` for details. apache__http_xss_protection: '1; mode=block' # ]]] # .. envvar:: apache__http_referrer_policy [[[ # -# Refer to :ref:`item.http_referrer_policy ` for details. +# Refer to :ref:`item.http_referrer_policy ` for details. apache__http_referrer_policy: 'no-referrer' # ]]] @@ -889,7 +889,7 @@ apache__status_vhost_enabled: '{{ apache__status_enabled }}' # Or maybe someone has a workaround which does not involve changing the package # module defaults. # -# Refer to :ref:`item.status_enabled ` for +# Refer to :ref:`item.status_enabled ` for # how to overwrite this for a virtual host. apache__status_for_vhost_enabled: False @@ -898,7 +898,7 @@ apache__status_for_vhost_enabled: False # # The ``Location`` or URL path by which the Apache server status should be # accessible. -# Refer to :ref:`item.status_location ` for +# Refer to :ref:`item.status_location ` for # how to overwrite this for a virtual host. apache__status_location: '/server-status' @@ -907,7 +907,7 @@ apache__status_location: '/server-status' # # Allow access to the Apache server status using the ``Require local`` # directive (refer to the `Apache host Require directive documentation`_). -# Refer to :ref:`item.status_allow_localhost ` for +# Refer to :ref:`item.status_allow_localhost ` for # how to overwrite this for a virtual host. apache__status_allow_localhost: False @@ -916,7 +916,7 @@ apache__status_allow_localhost: False # # Additional directives included into the ``Location`` sections for the Apache # server status configuration. Can be used to customize access for example. -# Refer to :ref:`item.status_directives ` for +# Refer to :ref:`item.status_directives ` for # how to overwrite this for a virtual host. apache__status_directives: '' diff --git a/docs/defaults-detailed.rst b/docs/defaults-detailed.rst index d5c6fd8..a660bd8 100644 --- a/docs/defaults-detailed.rst +++ b/docs/defaults-detailed.rst @@ -227,7 +227,7 @@ Common role options host configuration. Templates can extend other templates. -.. _apache__ref_vhosts_common_webserver_options: +.. _apache__ref_vhost_common_webserver_options: Common webserver options ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -412,7 +412,7 @@ HTTP security headers determines the Content-Security-Policy header set in server responses. Refer to the `Content Security Policy Reference`_. -.. _apache__ref_vhosts_http_xss_protection: +.. _apache__ref_vhost_http_xss_protection: ``http_xss_protection`` Optional, string. Value of the ``X-XSS-Protection`` HTTP header field. Set to @@ -432,7 +432,7 @@ HTTP security headers “X-XSS-Protection”? `_. -.. _apache__ref_vhosts_http_referrer_policy: +.. _apache__ref_vhost_http_referrer_policy: ``http_referrer_policy`` Optional, string. Value of the ``Referrer-Policy`` HTTP header field. Set to @@ -442,18 +442,18 @@ HTTP security headers browsers. -.. _apache__ref_vhosts_apache_status: +.. _apache__ref_vhost_apache_status: Apache status ~~~~~~~~~~~~~ -.. _apache__ref_vhosts_status_enabled: +.. _apache__ref_vhost_status_enabled: ``status_enabled`` Optional, boolean. Should the Apache server status be enabled? Defaults to :envvar:`apache__status_enabled`. -.. _apache__ref_vhosts_status_location: +.. _apache__ref_vhost_status_location: ``status_location`` Optional, string. @@ -461,7 +461,7 @@ Apache status accessible. Defaults to :envvar:`apache__status_location`. -.. _apache__ref_vhosts_status_allow_localhost: +.. _apache__ref_vhost_status_allow_localhost: ``status_allow_localhost`` Optional, boolean. @@ -469,7 +469,7 @@ Apache status directive. Defaults to :envvar:`apache__status_allow_localhost`. -.. _apache__ref_vhosts_status_directives: +.. _apache__ref_vhost_status_directives: ``status_directives`` Optional, string. From 2a0c2b679300a96d9e1937fa8e12fcf781aa4e0a Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Fri, 13 Jan 2017 10:55:10 +0100 Subject: [PATCH 13/21] Fix role run with `apache__deploy_state: absent` after `present` was set --- CHANGES.rst | 3 +++ defaults/main.yml | 1 + tasks/main.yml | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4952ce5..962edee 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -65,3 +65,6 @@ Fixed - Fix ``item.https_enabled`` support for virtual hosts. This variable was ignored previously using the global default (``True``) directly. [ypid_] + +- Fix role run with ``apache__deploy_state == "absent"`` after the role has + been run with ``present`` before. [ypid_] diff --git a/defaults/main.yml b/defaults/main.yml index 7137afb..ba24f7a 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -967,6 +967,7 @@ apache__ferm__dependent_rules: by_role: 'debops.apache' name: 'http_https' multiport: True + rule_state: '{{ apache__deploy_state }}' # ]]] # ]]] # ]]] diff --git a/tasks/main.yml b/tasks/main.yml index 934332a..38ee045 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -33,7 +33,9 @@ else item.value) | bool | ternary("present", "absent") }}' force: '{{ item.value.force|d(False) | bool }}' notify: [ 'Test apache and reload' ] - when: (item.key in apache__tpl_available_modules and item.value.enabled|d(True) != omit) + when: (item.key in apache__tpl_available_modules + and item.value.enabled|d(True) != omit + and apache__deploy_state == "present") with_dict: '{{ apache__combined_modules }}' tags: [ 'role::apache:modules' ] From e7e00ba2f5ff23275dc12d6f966eff5ed751a83f Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 17 Jan 2017 11:24:41 +0100 Subject: [PATCH 14/21] Add Ansible tags for env roles --- CHANGES.rst | 3 +++ docs/playbooks/apache.yml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 962edee..2450d1a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -35,6 +35,9 @@ Added This feature can be configured by :envvar:`apache__config_use_if_version` and :envvar:`apache__config_min_version`. [ypid_] +- Add Ansible tags for env roles. To only prepare the Apache role + environment, you can use the ``role::apache:env`` tag. [ypid_] + Changed ~~~~~~~ diff --git a/docs/playbooks/apache.yml b/docs/playbooks/apache.yml index 0f47b1d..edd640d 100644 --- a/docs/playbooks/apache.yml +++ b/docs/playbooks/apache.yml @@ -11,7 +11,7 @@ roles: - role: debops.apache/env - tags: [ 'role::apache' ] + tags: [ 'role::apache', 'role::apache:env' ] - role: debops.ferm tags: [ 'role::ferm' ] From 5e76849c58b0c2439c7d3d0cf9a912cfec68ad14 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Wed, 1 Feb 2017 13:19:57 +0100 Subject: [PATCH 15/21] Add missing filename suffixes in docs --- defaults/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index ba24f7a..c65c4e3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -424,12 +424,13 @@ apache__role_snippets: raw: | # This file exists here to make Debian package scripts happy. # For the actual security directives enabled in server context refer to - # the `local-debops_apache` file. + # the `local-debops_apache.conf` file. # # `postinst` of the `apache2` package normally tries to enable the # `security` snippet in server context without checking if it is actually - # there. The package provided `security` snippet has been diverted to - # `package-security`. + # there. The package provided `security.conf` snippet has been diverted + # to `package-security.conf` and is not enabled to allow `debops.apache` + # to configure and change security related settings. divert_filename: 'package-security' divert_suffix: '' From 9354f6daae743af1b02ca3273e4de85ee26b4854 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 17:29:31 +0100 Subject: [PATCH 16/21] Fix spelling --- README.md | 2 +- docs/introduction.rst | 2 +- meta/ansigenome.yml | 2 +- templates/etc/apache2/sites-available/debops__tpl_macros.j2 | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 75c7f83..494fc77 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Ansible Galaxy](https://img.shields.io/badge/galaxy-debops.apache-660198.svg?style=flat)](https://galaxy.ansible.com/debops/apache) -The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server] +The ``debops.apache`` role allows you to setup and manage the [Apache HTTP Server] with version 2.4 and above. [Apache HTTP Server]: https://en.wikipedia.org/wiki/Apache_HTTP_Server diff --git a/docs/introduction.rst b/docs/introduction.rst index b231921..bacadeb 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -3,7 +3,7 @@ Introduction .. include:: includes/all.rst -The ``debops.apache`` role allows you to setup and mange the `Apache HTTP Server`_ +The ``debops.apache`` role allows you to setup and manage the `Apache HTTP Server`_ with version 2.4 and above. diff --git a/meta/ansigenome.yml b/meta/ansigenome.yml index 4f8d9a5..21e7af0 100644 --- a/meta/ansigenome.yml +++ b/meta/ansigenome.yml @@ -16,7 +16,7 @@ ansigenome_info: github: 'ypid' synopsis: | - The ``debops.apache`` role allows you to setup and mange the [Apache HTTP Server] + The ``debops.apache`` role allows you to setup and manage the [Apache HTTP Server] with version 2.4 and above. [Apache HTTP Server]: https://en.wikipedia.org/wiki/Apache_HTTP_Server diff --git a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 index 522ea77..6d70bb8 100644 --- a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 @@ -76,7 +76,7 @@ {% macro indent(content, width=4, indentfirst=False) %}{# [[[ #} {# Fixed version of the `indent` filter which does not insert trailing spaces on empty lines. -## Note that you can not use this macro like filter but have to use it like a regular macro. +## Note that you can not use this macro like a filter but have to use it like a regular macro. ## Example: {{ debops__tpl_macros.indent(some_content, 4) }} ## ## Python re.sub seems to default to re.MULTILINE in Ansible. From 185e1bff16058fa6a899d0c4f02e166dfc7a7d55 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 18:34:34 +0100 Subject: [PATCH 17/21] Fix missing newline in configuration which produced invalid syntax Thanks to: @muelli Ref: https://github.com/debops/ansible-apache/pull/8#discussion_r99835270 --- templates/etc/apache2/sites-available/apache__tpl_macros.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 index 3291601..2dacea1 100644 --- a/templates/etc/apache2/sites-available/apache__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/apache__tpl_macros.j2 @@ -176,7 +176,7 @@ DocumentRoot {{ item.root|d(item.document_root) | quote }} {{ get_alias(item.alias, item.root|d(item.document_root)) }} {%- endif %} - {{ debops__tpl_macros.indent(get_document_root_directives(item), 4) -}} + {{ debops__tpl_macros.indent(get_document_root_directives(item), 4) }} {% endif %} {% if item.raw_content|d() %} From b1231f7f3ea7905b877cfe651b7d82c462c4cc88 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 18:47:10 +0100 Subject: [PATCH 18/21] Improve spelling and indention --- defaults/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index c65c4e3..91de4c2 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -72,9 +72,9 @@ apache__fqdn: '{{ ansible_local.core.fqdn # # The domain name of the host running Apache. apache__domain: '{{ ansible_local.core.domain - if (ansible_local|d() and ansible_local.core|d() and - ansible_local.core.domain|d()) - else ansible_domain }}' + if (ansible_local|d() and ansible_local.core|d() and + ansible_local.core.domain|d()) + else ansible_domain }}' # ]]] # .. envvar:: apache__config_path [[[ @@ -174,7 +174,7 @@ apache__https_listen: [ 443 ] # host after version upgrades because if certain features are enabled might # not only depend on the Apache version. For example the version of the used # cryptography library (OpenSSL) is also relevant and checked by this role at -# Ansible role execution. +# Ansible role execution time. # # ``False`` # The configuration is specifically generated for the Apache version which From 5f0bebb382b22aca0beeaa8c8d156c7a3b603933 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 19:20:39 +0100 Subject: [PATCH 19/21] Ensure that the rewrite module is loaded when required by the role --- CHANGES.rst | 5 ++++- defaults/main.yml | 5 +++++ tasks/apache_module_state.yml | 16 ++++++++++++++++ tasks/main.yml | 27 +++++++++++++-------------- 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 tasks/apache_module_state.yml diff --git a/CHANGES.rst b/CHANGES.rst index 2450d1a..34d6b42 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,7 +12,7 @@ The current role maintainer_ is ypid_. debops.apache v0.1.0 - unreleased ----------------------------------------- +--------------------------------- Added ~~~~~ @@ -66,6 +66,9 @@ Fixed for :envvar:`apache__ocsp_stapling_cache`. Before, the ``socache_shmcb`` module was implicitly loaded by the ``ssl`` module. [ypid_] +- Ensure that the rewrite module is loaded when it is used by the configuration + generated by the role. [ypid_] + - Fix ``item.https_enabled`` support for virtual hosts. This variable was ignored previously using the global default (``True``) directly. [ypid_] diff --git a/defaults/main.yml b/defaults/main.yml index 91de4c2..c0b573b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -333,6 +333,11 @@ apache__role_modules: enabled: '{{ True if (apache__status_enabled|bool and apache__status_allow_localhost) + else omit }}' + 'rewrite': + enabled: '{{ True + if (apache__register_mod_rewrite_used is defined and + apache__register_mod_rewrite_used.rc|d(1) == 0) else omit }}' # ]]] diff --git a/tasks/apache_module_state.yml b/tasks/apache_module_state.yml new file mode 100644 index 0000000..27ad944 --- /dev/null +++ b/tasks/apache_module_state.yml @@ -0,0 +1,16 @@ +--- +# vim: foldmarker=[[[,]]]:foldmethod=marker + +- name: Enable/disable Apache modules + apache2_module: + name: '{{ item.key }}' + state: '{{ (item.value.enabled + if (item.value is mapping) + else item.value) | bool | ternary("present", "absent") }}' + force: '{{ item.value.force|d(False) | bool }}' + notify: [ 'Test apache and reload' ] + when: (item.key in apache__tpl_available_modules + and item.value.enabled|d(True) != omit + and apache__deploy_state == "present") + with_dict: '{{ apache__combined_modules }}' + tags: [ 'role::apache:modules' ] diff --git a/tasks/main.yml b/tasks/main.yml index 38ee045..710f053 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -11,7 +11,6 @@ - '{{ apache__dependent_packages }}' # Manage Apache modules [[[1 - - name: Get list of available modules find: file_type: 'file' @@ -25,19 +24,7 @@ apache__tpl_available_modules: '{{ apache__register_mods_available.files|d({}) | map(attribute="path") | map("replace", apache__config_path + "/mods-available/", "") | map("regex_replace", "\.load$", "") | list }}' tags: [ 'role::apache:modules' ] -- name: Enable/disable Apache modules - apache2_module: - name: '{{ item.key }}' - state: '{{ (item.value.enabled - if (item.value is mapping) - else item.value) | bool | ternary("present", "absent") }}' - force: '{{ item.value.force|d(False) | bool }}' - notify: [ 'Test apache and reload' ] - when: (item.key in apache__tpl_available_modules - and item.value.enabled|d(True) != omit - and apache__deploy_state == "present") - with_dict: '{{ apache__combined_modules }}' - tags: [ 'role::apache:modules' ] +- include: apache_module_state.yml # Manage Apache configuration snippets [[[1 - name: Divert conf-available configuration @@ -137,3 +124,15 @@ when: (item.type|d(apache__vhost_type) not in ["divert"]) with_flattened: '{{ apache__combined_vhosts }}' tags: [ 'role::apache:vhosts' ] + + +# Manage Apache modules, part 2 [[[1 +- name: Detect if the rewrite module has been used in the active configuration + shell: grep --ignore-case '^\s*RewriteEngine On' {{ apache__config_path | quote }}/sites-enabled/* {{ apache__config_path | quote }}/conf-enabled/* + register: apache__register_mod_rewrite_used + always_run: True + failed_when: apache__register_mod_rewrite_used.rc not in [ 0, 1 ] + changed_when: False + when: apache__register_mod_rewrite_used is undefined + +- include: apache_module_state.yml From 04d02e33aec2449e8bd922d82f420bbee44431a3 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 20:12:59 +0100 Subject: [PATCH 20/21] Incorporate review by @drybjed, thanks! --- CHANGES.rst | 2 +- defaults/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 34d6b42..d5a0e55 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -42,7 +42,7 @@ Changed ~~~~~~~ - Change default virtual host server name from ``000-default`` to ``default.{{ - apache__domain }}`` to increase the changes that a valid certificate is + apache__domain }}`` to increase the chances that a valid certificate is available for this virtual host (either wildcard or SAN) in order to avoid the warning of Apache that the certificate is not valid for the server name. [ypid_] diff --git a/defaults/main.yml b/defaults/main.yml index c0b573b..d7feb4f 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -74,7 +74,7 @@ apache__fqdn: '{{ ansible_local.core.fqdn apache__domain: '{{ ansible_local.core.domain if (ansible_local|d() and ansible_local.core|d() and ansible_local.core.domain|d()) - else ansible_domain }}' + else (ansible_domain if ansible_domain else ansible_hostname) }}' # ]]] # .. envvar:: apache__config_path [[[ From 22d4718340c69c246683ca11125c0ec84888d722 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Tue, 7 Feb 2017 22:46:54 +0100 Subject: [PATCH 21/21] Prepare debops__tpl_macros.j2 upstreaming --- .../sites-available/debops__tpl_macros.j2 | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 index 6d70bb8..f2c6f9a 100644 --- a/templates/etc/apache2/sites-available/debops__tpl_macros.j2 +++ b/templates/etc/apache2/sites-available/debops__tpl_macros.j2 @@ -1,10 +1,12 @@ {# vim: foldmarker=[[[,]]]:foldmethod=marker -# Copyright [[[ # Commonly used set of macros in DebOps. # It can be included in repositories as needed. -# Changes to this file should go upstream: FIXME +# Changes to this file should go upstream: https://github.com/debops/debops-playbooks/blob/master/templates/debops__tpl_macros.j2 +# +# Copyright [[[ +# ============= # -# Copyright (C) 2014-2016 Maciej Delmanowski +# Copyright (C) 2014-2017 Maciej Delmanowski # Copyright (C) 2015-2017 Robin Schneider # Copyright (C) 2014-2017 DebOps https://debops.org/ # @@ -21,6 +23,27 @@ # # You should have received a copy of the GNU General Public License # along with DebOps. If not, see https://www.gnu.org/licenses/. +# +# ]]] +# +# Usage [[[ +# ========= +# +# Copy the template file into your ./templates/ path of a role where it fits +# best. You can/might need to use symlinks to make the macros available from +# different paths in your ./templates/ hierarchy. +# +# Make sure to retain the filename of this file so that automatic updates of +# this file can be implemented. +# +# To use the macros in your own template, this file needs to be included like so: +# +# {% import 'debops__tpl_macros.j2' as debops__tpl_macros with context %} +# +# Then you can start using the macros like this: +# +# {{ debops__tpl_macros.indent(some_content, 4) }} +# # ]]] #} {% macro get_yaml_list_for_elem(list_or_elem) %}{# [[[ #}