|
27 | 27 | when: tomcat_add_user_to_group |
28 | 28 | tags: ['tomcat'] |
29 | 29 |
|
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: |
31 | 51 | tomcat_shutdown_value: "{{ lookup('password', '/dev/null length=20 chars=ascii_letters') }}" |
32 | 52 | when: tomcat_shutdown_value == "SETME" |
33 | 53 | tags: ['tomcat'] |
|
68 | 88 | when: tomcat_conf_found.stat.exists == false |
69 | 89 | tags: ['tomcat'] |
70 | 90 |
|
| 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 | + |
71 | 155 | - name: Add HTTP Header Security Filter to web.xml |
72 | 156 | ansible.builtin.blockinfile: |
73 | 157 | path: "{{ _tomcat_catalina_base }}/conf/web.xml" |
|
90 | 174 | when: tomcat_secure_http_headers |
91 | 175 | tags: ['tomcat'] |
92 | 176 |
|
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 | +# community.general.xml runs on the target and needs lxml there. Package name |
| 214 | +# differs because CentOS 6/7 hosts run ansible under python2. |
| 215 | +- name: ensure lxml is available for the web.xml session-config edits |
| 216 | + ansible.builtin.package: |
| 217 | + name: "{{ 'python3-lxml' if ansible_python_version is version('3', '>=') else 'python-lxml' }}" |
| 218 | + state: present |
| 219 | + when: tomcat_secure_session_cookie |
| 220 | + tags: ['tomcat'] |
| 221 | + |
| 222 | +- name: Ensure cookie-config element exists in session-config |
| 223 | + community.general.xml: |
| 224 | + path: "{{ _tomcat_catalina_base }}/conf/web.xml" |
| 225 | + xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config |
| 226 | + namespaces: |
| 227 | + javaee: http://xmlns.jcp.org/xml/ns/javaee |
| 228 | + state: present |
| 229 | + when: tomcat_secure_session_cookie |
| 230 | + tags: ['tomcat'] |
| 231 | + |
| 232 | +- name: Set http-only flag on session cookie |
| 233 | + community.general.xml: |
| 234 | + path: "{{ _tomcat_catalina_base }}/conf/web.xml" |
| 235 | + xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config/javaee:http-only |
| 236 | + namespaces: |
| 237 | + javaee: http://xmlns.jcp.org/xml/ns/javaee |
| 238 | + value: "true" |
| 239 | + when: tomcat_secure_session_cookie |
| 240 | + tags: ['tomcat'] |
| 241 | + |
| 242 | +- name: Set secure flag on session cookie |
| 243 | + community.general.xml: |
| 244 | + path: "{{ _tomcat_catalina_base }}/conf/web.xml" |
| 245 | + xpath: /javaee:web-app/javaee:session-config/javaee:cookie-config/javaee:secure |
| 246 | + namespaces: |
| 247 | + javaee: http://xmlns.jcp.org/xml/ns/javaee |
| 248 | + value: "true" |
| 249 | + when: tomcat_secure_session_cookie |
| 250 | + tags: ['tomcat'] |
| 251 | + |
| 252 | +- name: secure catalina base config files |
94 | 253 | file: |
95 | 254 | path: '{{ _tomcat_catalina_base }}/conf/{{ item }}' |
96 | 255 | owner: '{{ tomcat_user }}' |
|
0 commit comments