Skip to content

Commit 8486693

Browse files
committed
add support for optional web.xml parameters, stamp it as it changes between versions but we sometimes modify it
1 parent abc9333 commit 8486693

2 files changed

Lines changed: 171 additions & 2 deletions

File tree

defaults/main.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ tomcat_packages:
2323
- "tomcat{{ tomcat_major_version }}"
2424

2525
tomcat_secure_http_headers: true
26+
tomcat_secure_session_cookie: true
27+
28+
# Refresh CATALINA_BASE/conf/web.xml from the installed distribution's stock
29+
# descriptor whenever that descriptor changes (i.e. on a Tomcat upgrade).
30+
# Without this, conf/web.xml keeps whatever base it had when the host was first
31+
# provisioned, since the conf.dist copy only runs on initial provisioning.
32+
tomcat_manage_webxml_baseline: true
2633

2734
tomcat_connection_timeout: 20000
2835

@@ -82,6 +89,18 @@ tomcat_shutdown_wait: 20
8289
tomcat_start_service: false
8390

8491
tomcat_contexts: []
92+
# Additional servlet filters to declare in CATALINA_BASE/conf/web.xml. Only
93+
# `name` and `class` are required. Emptying the list removes the managed block.
94+
# The filter class must already be on the shared classpath -- conf/web.xml is
95+
# the global descriptor, so an unloadable class fails every context on startup.
96+
# - name: myFilter
97+
# class: com.example.MyFilter
98+
# url_pattern: '/*' # default '/*'
99+
# dispatchers: ['REQUEST'] # default ['REQUEST']
100+
# init_params:
101+
# - name: someOption
102+
# value: someValue
103+
tomcat_extra_filters: []
85104
tomcat_extra_loggers: []
86105
tomcat_global_context:
87106
jdbc_resources: []

tasks/main.yml

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,27 @@
2727
when: tomcat_add_user_to_group
2828
tags: ['tomcat']
2929

30-
- set_fact:
30+
# Without this, the set_fact below mints a new random value on every run, so
31+
# server.xml is rewritten every time (and the on-disk value drifts from the
32+
# running one, since nothing restarts tomcat for a server.xml change).
33+
- name: read any existing tomcat shutdown value
34+
ansible.builtin.command:
35+
cmd: sed -n 's/.*<Server[^>]*shutdown="\([^"]*\)".*/\1/p' {{ _tomcat_catalina_base }}/conf/server.xml
36+
register: tomcat_shutdown_existing
37+
changed_when: false
38+
failed_when: false
39+
check_mode: false
40+
tags: ['tomcat']
41+
42+
- name: preserve the existing tomcat shutdown value
43+
ansible.builtin.set_fact:
44+
tomcat_shutdown_value: "{{ tomcat_shutdown_existing.stdout_lines | first }}"
45+
when:
46+
- tomcat_shutdown_value == "SETME"
47+
- tomcat_shutdown_existing.stdout_lines | default([]) | length > 0
48+
tags: ['tomcat']
49+
50+
- set_fact:
3151
tomcat_shutdown_value: "{{ lookup('password', '/dev/null length=20 chars=ascii_letters') }}"
3252
when: tomcat_shutdown_value == "SETME"
3353
tags: ['tomcat']
@@ -68,6 +88,70 @@
6888
when: tomcat_conf_found.stat.exists == false
6989
tags: ['tomcat']
7090

91+
# The conf.dist copy above only runs on initial provisioning, so conf/web.xml
92+
# would otherwise keep its original base forever and drift from the installed
93+
# Tomcat version. Stamping with conf.dist's checksum (rather than
94+
# tomcat_version) keeps this correct even if the stamp and the installed
95+
# distribution get out of step. Skipped for rpm installs, which have no
96+
# conf.dist.
97+
- name: check for the tomcat distribution's stock web.xml
98+
ansible.builtin.stat:
99+
path: "{{ _tomcat_catalina_home }}/conf.dist/web.xml"
100+
checksum_algorithm: sha1
101+
register: tomcat_webxml_dist
102+
when: tomcat_manage_webxml_baseline
103+
tags: ['tomcat']
104+
105+
- name: check whether catalina base web.xml is present
106+
ansible.builtin.stat:
107+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
108+
register: tomcat_webxml_current
109+
when: tomcat_manage_webxml_baseline
110+
tags: ['tomcat']
111+
112+
- name: check the web.xml baseline stamp
113+
ansible.builtin.command:
114+
cmd: grep -q "ANSIBLE MANAGED WEBXML BASELINE {{ tomcat_webxml_dist.stat.checksum }}" {{ _tomcat_catalina_base }}/conf/web.xml
115+
register: tomcat_webxml_stamp
116+
changed_when: false
117+
failed_when: false
118+
check_mode: false
119+
when:
120+
- tomcat_manage_webxml_baseline
121+
- tomcat_webxml_dist.stat.exists | default(false)
122+
- tomcat_webxml_current.stat.exists | default(false)
123+
tags: ['tomcat']
124+
125+
- name: refresh web.xml from the tomcat distribution
126+
ansible.builtin.copy:
127+
src: "{{ _tomcat_catalina_home }}/conf.dist/web.xml"
128+
remote_src: true
129+
dest: "{{ _tomcat_catalina_base }}/conf/web.xml"
130+
owner: "{{ tomcat_user }}"
131+
group: "{{ tomcat_group }}"
132+
mode: '0640'
133+
when:
134+
- tomcat_manage_webxml_baseline
135+
- tomcat_webxml_dist.stat.exists | default(false)
136+
- tomcat_webxml_current.stat.exists | default(false)
137+
- tomcat_webxml_stamp.rc | default(1) != 0
138+
tags: ['tomcat']
139+
140+
- name: stamp web.xml with its baseline checksum
141+
ansible.builtin.lineinfile:
142+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
143+
insertbefore: "</web-app>"
144+
line: "<!-- ANSIBLE MANAGED WEBXML BASELINE {{ tomcat_webxml_dist.stat.checksum }} -->"
145+
owner: "{{ tomcat_user }}"
146+
group: "{{ tomcat_group }}"
147+
mode: '0640'
148+
when:
149+
- tomcat_manage_webxml_baseline
150+
- tomcat_webxml_dist.stat.exists | default(false)
151+
- tomcat_webxml_current.stat.exists | default(false)
152+
- tomcat_webxml_stamp.rc | default(1) != 0
153+
tags: ['tomcat']
154+
71155
- name: Add HTTP Header Security Filter to web.xml
72156
ansible.builtin.blockinfile:
73157
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
@@ -90,7 +174,73 @@
90174
when: tomcat_secure_http_headers
91175
tags: ['tomcat']
92176

93-
- name: secure catalina base config files
177+
# Declared after the httpHeaderSecurity block so that filter keeps precedence in
178+
# the chain. `state` is driven by the list so emptying it removes the block
179+
# rather than orphaning it. Registered (rather than notifying a handler) so
180+
# consumers can decide whether a web.xml change warrants a restart.
181+
- name: manage extra web.xml filters
182+
ansible.builtin.blockinfile:
183+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
184+
insertbefore: "</web-app>"
185+
marker: "<!-- {mark} ANSIBLE MANAGED EXTRA FILTERS -->"
186+
state: "{{ 'present' if tomcat_extra_filters else 'absent' }}"
187+
owner: "{{ tomcat_user }}"
188+
group: "{{ tomcat_group }}"
189+
mode: '0640'
190+
block: |
191+
{% for f in tomcat_extra_filters %}
192+
<filter>
193+
<filter-name>{{ f.name }}</filter-name>
194+
<filter-class>{{ f.class }}</filter-class>
195+
{% for p in f.init_params | default([]) %}
196+
<init-param>
197+
<param-name>{{ p.name }}</param-name>
198+
<param-value>{{ p.value }}</param-value>
199+
</init-param>
200+
{% endfor %}
201+
</filter>
202+
<filter-mapping>
203+
<filter-name>{{ f.name }}</filter-name>
204+
<url-pattern>{{ f.url_pattern | default('/*') }}</url-pattern>
205+
{% for d in f.dispatchers | default(['REQUEST']) %}
206+
<dispatcher>{{ d }}</dispatcher>
207+
{% endfor %}
208+
</filter-mapping>
209+
{% endfor %}
210+
register: tomcat_extra_filters_webxml
211+
tags: ['tomcat']
212+
213+
- name: Ensure cookie-config element exists in session-config
214+
community.general.xml:
215+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
216+
xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config
217+
namespaces:
218+
javaee: http://xmlns.jcp.org/xml/ns/javaee
219+
state: present
220+
when: tomcat_secure_session_cookie
221+
tags: ['tomcat']
222+
223+
- name: Set http-only flag on session cookie
224+
community.general.xml:
225+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
226+
xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config/javaee:http-only
227+
namespaces:
228+
javaee: http://xmlns.jcp.org/xml/ns/javaee
229+
value: "true"
230+
when: tomcat_secure_session_cookie
231+
tags: ['tomcat']
232+
233+
- name: Set secure flag on session cookie
234+
community.general.xml:
235+
path: "{{ _tomcat_catalina_base }}/conf/web.xml"
236+
xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config/javaee:secure
237+
namespaces:
238+
javaee: http://xmlns.jcp.org/xml/ns/javaee
239+
value: "true"
240+
when: tomcat_secure_session_cookie
241+
tags: ['tomcat']
242+
243+
- name: secure catalina base config files
94244
file:
95245
path: '{{ _tomcat_catalina_base }}/conf/{{ item }}'
96246
owner: '{{ tomcat_user }}'

0 commit comments

Comments
 (0)