forked from debops/ansible-apache
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapache__tpl_macros.j2
More file actions
280 lines (249 loc) · 12.7 KB
/
Copy pathapache__tpl_macros.j2
File metadata and controls
280 lines (249 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
{# vim: foldmarker=[[[,]]]:foldmethod=marker
#}
{% 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 %}
<IfVersion {{ compare_operator }} {{ version }}>
{{ debops__tpl_macros.indent(content, 4) }}
</IfVersion>
{% 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 %}
{% set apache__tpl_names = [ apache__server_name ] %}
{% endif %}
ServerName {{ apache__tpl_names[0] | quote }}
{% if apache__tpl_names|length > 1 %}
ServerAlias {{ apache__tpl_names[1:] | map("quote") | join(" ") }}
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_listen_sockets(item_listen_list, server_port_listen_list) %}{# [[[ #}
{% set apache__tpl_listen_sockets = [] %}
{% if item_listen_list|length == 0 %}
{% set item_listen_list = server_port_listen_list %}
{% endif %}
{% for item_listen in item_listen_list %}
{% if ':' not in item_listen|string %}
{# {% if item_listen in server_port_listen_list %}
## Apperently, this is not even needed for Apache to (re)start without issues. #}
{% set _ = apache__tpl_listen_sockets.append("*:" + item_listen|string) %}
{% else %}
{% set _ = apache__tpl_listen_sockets.append(item_listen|string) %}
{% endif %}
{% endfor %}
{{ apache__tpl_listen_sockets | join(" ") -}}
{% endmacro %}{# ]]] #}
{% macro get_header_comments(item) %}{# [[[ #}
{% if item.by_role|d() %}
# Generated by Ansible role: {{ item.by_role }}
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_server_directives(item) %}{# [[[ #}
{% set sanitized_name = (debops__tpl_macros.get_yaml_list_for_elem(item.filename|d(item.name)) | from_yaml)[0] | replace(".", "_") %}
{% if item.name|d([]) %}
{{ get_server_name_aliases(item.name|d([])) }}
{% endif %}
ServerAdmin {{ item.server_admin|d(apache__server_admin) | quote }}
CustomLog ${APACHE_LOG_DIR}/{{ sanitized_name }}_access.log {{ apache__access_log_format }}
ErrorLog ${APACHE_LOG_DIR}/{{ sanitized_name }}_error.log
{% endmacro %}{# ]]] #}
{% macro get_server_status_directives(item, enabled) %}{# [[[ #}
{% if enabled|bool %}
<Location {{ item.status_location|d(apache__status_location) | quote }}>
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 %}
</Location>
{% 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(apache__redirect_to_https) | 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(apache__redirect_to_https) | 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_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 %}
Include {{ include_file | quote }}
{% endfor %}
{% endif %}
{% if item.include_optional|d() %}
{% for include_optional_file in debops__tpl_macros.get_yaml_list_for_elem(item.include_optional)|from_yaml %}
IncludeOptional {{ include_optional_file | quote }}
{% endfor %}
{% endif %}
{% if item.root|d(item.document_root|d()) %}
DocumentRoot {{ item.root|d(item.document_root) | quote }}
{% if item.alias|d() %}
{{ get_alias(item.alias, item.root|d(item.document_root)) }}
{%- endif %}
<Directory {{ item.root|d(item.document_root) | quote }}>
{{ debops__tpl_macros.indent(get_document_root_directives(item), 4) }}
</Directory>
{% endif %}
{% if item.raw_content|d() %}
{{ item.raw_content }}
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_default_tls_directives(item) %}{# [[[ #}
{# Included in server context to provide sane defaults (there might be vhosts
# 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.
#}
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
# TLS cipher suites set: {{ item.tls_cipher_suite_set_name|d(apache__tls_cipher_suite_set_name) | quote }}
SSLCipherSuite {{ apache__tls_cipher_suite_sets[item.tls_cipher_suite_set_name|d(apache__tls_cipher_suite_set_name)] | quote }}
SSLProtocol {{ item.tls_protocols|d(apache__tls_protocols) | join(" ") }}
SSLHonorCipherOrder {{ item.tls_honor_cipher_order|d(apache__tls_honor_cipher_order) | quote }}
SSLCompression {{ item.tls_compression|d(apache__tls_compression) | quote }}
{#
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html
# https://github.com/sovereign/sovereign/issues/373
#}
{% if debops__tpl_macros.get_apache_version()|version_compare("2.4.8", ">=") and debops__tpl_macros.get_openssl_version()|version_compare("1.0.2", ">=") %}
# SSLOpenSSLConfCmd DHParameters {{ item.tls_dhparam_file|d(apache__tls_dhparam_file) | quote }}
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_https_directives(item) %}{# [[[ #}
SSLEngine on
{{ get_default_tls_directives(item) }}
{% set apache__tpl_pki_realm = item.pki_realm | d((debops__tpl_macros.get_realm_yaml_list(item.name, apache__pki_realm) | from_yaml)[0]) %}
{% set apache__tpl_pki_realm_path = apache__pki_realm_path + "/" + apache__tpl_pki_realm %}
SSLCertificateFile {{ item.tls_crt | d(apache__tpl_pki_realm_path + "/" + (item.pki_crt|d(apache__pki_crt_filename))) | quote }}
SSLCertificateKeyFile {{ item.tls_key | d(apache__tpl_pki_realm_path + "/" + (item.pki_key|d(apache__pki_key_filename))) | quote }}
{% if item.ocsp_stapling_enabled|d(apache__ocsp_stapling_enabled)|bool and debops__tpl_macros.get_openssl_version()|version_compare("0.9.8h", ">=") %}
SSLUseStapling on
{% endif %}
{% if item.hsts_enabled|d(apache__hsts_enabled) | bool %}
Header always set Strict-Transport-Security "max-age={{ item.hsts_max_age|d(apache__hsts_max_age) }}{{ "; includeSubDomains" if item.hsts_subdomains|d(apache__hsts_subdomains) | bool else "" }}{{ "; preload" if ((item.hsts_preload|d(apache__hsts_preload)) | bool) else "" }}"
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_http_security_headers(item) %}{# [[[ #}
{% set apache__tpl_directive_options = debops__tpl_macros.get_yaml_list_for_elem(item.http_sec_headers_directive_options|d(apache__http_sec_headers_directive_options)) | from_yaml | map("quote") | join(" ") %}
{% if apache__http_frame_options|d(item.http_frame_options) %}
Header {{ apache__tpl_directive_options }} X-Frame-Options "{{ apache__http_frame_options|d(item.http_frame_options) }}"
{% endif %}
{% if apache__http_frame_options|d(item.http_frame_options) != omit %}
Header {{ apache__tpl_directive_options }} X-XSS-Protection "{{ item.http_xss_protection|d(apache__http_xss_protection) }}"
{% endif %}
{% if apache__http_referrer_policy|d(item.http_referrer_policy) != omit %}
Header {{ apache__tpl_directive_options }} Referrer-Policy "{{ apache__http_referrer_policy|d(item.http_referrer_policy) }}"
{% endif %}
{% if apache__http_frame_options|d(item.http_frame_options) %}
Header {{ apache__tpl_directive_options }} X-Content-Type-Options "{{ item.http_content_type_options|d(apache__http_content_type_options) }}"
{% endif %}
{% endmacro %}{# ]]] #}
{% macro get_common_headers(item) %}{# [[[ #}
{% if item.http_clacks_overhead|d(apache__http_clacks_overhead|d(True)) | bool %}
{#
# Respect the will of the DebOps Creator.
# Ref: https://github.com/debops/ansible-nginx/commit/d6cd455c68a7584b2592053fd98d3e539054e09a
#}
Header always set X-Clacks-Overhead "GNU Terry Pratchett"
{% endif %}
{% endmacro %}{# ]]] #}
{% 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) %}{# [[[ #}
Alias {{ url_path | quote }} {{ (fs_directory + ("/" if (fs_directory[-1] != "/") else "")) | quote }}
{% endmacro %}{# ]]] #}