-
Notifications
You must be signed in to change notification settings - Fork 1
/
configure.yml
317 lines (250 loc) · 9 KB
/
configure.yml
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
- hosts: all
remote_user: ubuntu
become: true
gather_facts: yes
vars_files:
- variables.yml
vars:
kibana_basic_auth: "{{ attendee_user }}:{{ attendee_password }}"
tasks:
# System
- name: Update and upgrade apt packages
apt: upgrade=dist force_apt_get=yes update_cache=yes
- name: Install NTP to avoid time drift and PIP to manage Python dependencies plus its build tools
apt:
name: [ 'ntp', 'ntpdate', 'python3-pip', 'build-essential', 'libssl-dev', 'libffi-dev', 'whois' ]
- name: Install the pyOpenSSL library, so Ansible can use it to check TLS certificates
pip: name=pyopenssl
- name: Set the Elasticsearch password for Beats
lineinfile:
dest: /tmp/cred
line: "{{ elasticsearch_password }}"
state: present
create: yes
mode: 0600
- name: Get the Beats
apt: deb={{ elastic_download }}/downloads/beats/{{ item }}/{{ item }}-{{ elastic_version }}-amd64.deb
loop:
- auditbeat
- filebeat
- heartbeat
- metricbeat
- packetbeat
- name: Change the Beats configuration
template: "src=templates/{{ item }}.yml dest=/etc/{{ item }}/{{ item }}.yml"
loop:
- auditbeat
- filebeat
- heartbeat
- metricbeat
- packetbeat
- name: Create the Beats keystores
command: "{{ item }} keystore create --force"
loop:
- auditbeat
- filebeat
- heartbeat
- metricbeat
- packetbeat
- name: Set the password in the Beats keystore files
shell: cat /tmp/cred | {{ item }} keystore add ES_PWD --stdin --force
loop:
- auditbeat
- filebeat
- heartbeat
- metricbeat
- packetbeat
- name: Remove the password file
file:
path: /tmp/cred
state: absent
- name: Run the setup for all the beats (except Heartbeat — not needed)
shell: "{{ item }} setup"
loop:
- auditbeat
- filebeat
- metricbeat
- packetbeat
- name: Restart and make sure the Beats autostart
service: name={{ item }} state=restarted enabled=yes
loop:
- auditbeat
- filebeat
- heartbeat-elastic
- metricbeat
- packetbeat
- name: Wait if the Beats are actually running
pause: minutes=1
- name: Get the state of all services and check the status of Auditbeat
service_facts: ~
failed_when: ansible_facts.services.auditbeat.state != "running"
- name: Get the state of all services and check the status of Filebeat
service_facts: ~
failed_when: ansible_facts.services.filebeat.state != "running"
- name: Get the state of all services and check the status of Heartbeat
service_facts: ~
failed_when: ansible_facts.services["heartbeat-elastic"].state != "running"
- name: Get the state of all services and check the status of Metricbeat
service_facts: ~
failed_when: ansible_facts.services.metricbeat.state != "running"
- name: Get the state of all services and check the status of Packetbeat
service_facts: ~
failed_when: ansible_facts.services.packetbeat.state != "running"
# MySQL
- name: Install the DEB packages required for Ansible's MySQL modules
apt:
name: ['python3-dev', 'libmysqlclient-dev']
- name: Install the Python package required for Ansible's MySQL modules
pip: name=mysqlclient
- name: Install MySQL
apt: name=mysql-server
- name: Removes all anonymous user accounts
mysql_user:
name: ""
host_all: yes
state: absent
no_log: true
- name: Create database user and password with all database privileges
mysql_user:
name: "{{ mysql_root_user }}"
password: "{{ mysql_root_password }}"
priv: "*.*:ALL"
host: "%"
state: present
no_log: true
- name: Create database user and password with read and insert privileges
mysql_user:
name: "{{ mysql_user_user }}"
password: "{{ mysql_user_password }}"
priv: "*.*:INSERT,SELECT"
host: "%"
state: present
no_log: true
- name: Restart MySQL and make sure it autostarts
service: name=mysql state=restarted enabled=yes
# PHP
- name: Install PHP
apt:
name: ['php-fpm', 'php-mysql']
- name: Configure PHP
lineinfile:
dest: "/etc/php/{{ php_version }}/fpm/php.ini"
line: "{{ item.key }} = {{ item.value }}"
regexp: "^\\s*(;\\s*)?{{ item.key }}"
with_items:
- { key: 'display_errors', value: 'Off' }
- { key: 'date.timezone', value: 'Europe/Vienna' }
- name: Enable the PHP status page
lineinfile:
dest: "/etc/php/{{ php_version }}/fpm/pool.d/www.conf"
regexp: '^;pm.status_path'
line: pm.status_path = /status
- name: Restart PHP and make sure it autostarts
service: name="php{{ php_version }}-fpm" state=restarted enabled=yes
# nginx
- name: Install nginx
apt: name=nginx
- name: Stop nginx so that Certbot can bind to port 80
service: name=nginx state=stopped
- name: Install certbot
apt: name=python3-certbot-nginx
- name: Add domains to the certificate
set_fact:
certificates:
- "{{ inventory_hostname }}"
- "{{ domain }}"
- "www.{{ domain }}"
- "kibana.{{ domain }}"
- "dashboard.{{ domain }}"
- name: Create the certificate
command: >
certbot certonly --non-interactive --standalone
--agree-tos --email admin@{{ domain }}
-d {{ certificates | join(',') }}
creates=/etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem
- name: Add crontab to renew certificates every second month on Sunday night
cron:
name: Refresh the certificate
minute: "30"
hour: "3"
weekday: "0"
month: "*/2"
job: service nginx stop && certbot renew >> /var/log//var/log/letsencrypt/renew.log && service nginx start
- name: Generate strong dhparams, but only if the file doesn't exist
command: openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 creates=/etc/ssl/certs/dhparam.pem
- name: Set a global TLS configuration
template: src=templates/tls.conf dest=/etc/nginx/tls.conf
- name: Change the nginx configuration
template: src=templates/nginx.conf dest=/etc/nginx/sites-available/default
- name: Restart nginx and make sure it autostarts
service: name=nginx state=restarted enabled=yes
- name: Check HTTP
uri:
url: "http://{{ inventory_hostname }}"
follow_redirects: none
status_code: 301
register: response
retries: 3
delay: 2
delegate_to: 127.0.0.1
become: false
- name: Fail if HTTP is not being redirected to HTTPS
fail:
when: response.status != 301
- name: Get HTTPS
openssl_certificate_info:
path: /etc/letsencrypt/live/{{ inventory_hostname }}/fullchain.pem
valid_at:
point_1: "+1w"
register: apex
- name: Check HTTPS
assert:
that:
- apex.valid_at.point_1
# Apache
- name: Install Apache
apt: name=apache2
- name: Install PHP for Apache
apt:
name: ['php', 'libapache2-mod-php']
- name: Enable the modules for TLS
shell: a2enmod ssl && a2enmod headers && a2ensite default-ssl
- name: Configure Apache to use port 8080
lineinfile:
dest: /etc/apache2/ports.conf
regexp: '^Listen 80'
line: Listen 8080
- name: Change TLS ports in Apache to avoid a collision with nginx
replace:
path: /etc/apache2/ports.conf
regexp: 'Listen 443'
replace: 'Listen 8443'
- name: Change the Apache configuration
template: src=templates/apache.conf dest=/etc/apache2/sites-enabled/000-default.conf
- name: Enable the Apache status page globally
template: src=templates/status.conf dest=/etc/apache2/mods-enabled/status.conf
- name: Install ModSecurity
apt: name=libapache2-mod-security2
- name: Activate the ModSecurity config
copy:
src: /etc/modsecurity/modsecurity.conf-recommended
dest: /etc/modsecurity/modsecurity.conf
remote_src: yes
- name: Turn On SecRuleEngine rather than DetectionOnly
lineinfile:
dest: /etc/modsecurity/modsecurity.conf
regexp: '^SecRuleEngine'
line: SecRuleEngine On
- name: Change the logging format to JSON
lineinfile:
dest: /etc/modsecurity/modsecurity.conf
regexp: '^SecAuditLogFormat'
line: SecAuditLogFormat JSON
- name: Add a custom mod_security rule
template: src=templates/modsecurity_custom_rules.conf dest=/etc/modsecurity/modsecurity_custom_rules.conf
- name: Remove the default index page so we can use our own code
file:
path: /var/www/html/index.html
state: absent
- name: Restart Apache and make sure it autostarts
service: name=apache2 state=restarted enabled=yes