FIX: disable kdump service
[ta/infra-ansible.git] / roles / ops-hardening / tasks / main.yaml
1 ---
2
3 # Copyright 2019 Nokia
4
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 #
18 # Linux password hardening
19 #
20
21 - name: "Set Password Strength Minimum Digit Characters."
22   lineinfile:
23     path: /etc/security/pwquality.conf
24     regexp: '^[#\s]*dcredit'
25     line: 'dcredit = -1'
26
27 - name: "Set Password Minimum Length."
28   lineinfile:
29     path: /etc/security/pwquality.conf
30     regexp: '^[#\s]*minlen'
31     line: 'minlen = 8'
32
33 - name: "Set Password Strength Minimum Uppercase Characters."
34   lineinfile:
35     path: /etc/security/pwquality.conf
36     regexp: '^[#\s]*ucredit'
37     line: 'ucredit = -1'
38
39 - name: "Set Password Strength Minimum Special Characters."
40   lineinfile:
41     path: /etc/security/pwquality.conf
42     regexp: '^[#\s]*ocredit'
43     line: 'ocredit = -1'
44
45 - name: "Set Password Strength Minimum Lowercase Characters."
46   lineinfile:
47     path: /etc/security/pwquality.conf
48     regexp: '^[#\s]*lcredit'
49     line: 'lcredit = -1'
50
51 - name: "Set Password Strength Minimum Different Categories."
52   lineinfile:
53     path: /etc/security/pwquality.conf
54     regexp: '^[#\s]*minclass'
55     line: 'minclass = 3'
56
57 - name: "Set Password Minimum Length in login.defs"
58   lineinfile:
59     path: /etc/login.defs
60     regexp: '^PASS_MIN_LEN[\s]*[0-9]*$'
61     line: 'PASS_MIN_LEN   8'
62
63 - name: "Set Password Minimum Age"
64   lineinfile:
65     path: /etc/login.defs
66     regexp: '^PASS_MIN_DAYS[\s]*[0-9]*$'
67     line: 'PASS_MIN_DAYS   0'
68
69 - name: "Set password hash to SHA512"
70   lineinfile:
71     path: /etc/login.defs
72     regexp: '^ENCRYPT_METHOD[\s]*[a-z0-9]*$'
73     line: 'ENCRYPT_METHOD   SHA512'
74
75 - name: "Set minimum number of password hash rounds"
76   lineinfile:
77     path: /etc/login.defs
78     regexp: '^SHA_CRYPT_MIN_ROUNDS[\s]*[0-9]*$'
79     line: 'SHA_CRYPT_MIN_ROUNDS   5000'
80
81 #
82 # Linux Failed password attempts
83 #
84 - name: "Ensure authconfig is properly configured"
85   command: authconfig --updateall
86   with_items:
87     - /etc/pam.d/system-auth-ac
88     - /etc/pam.d/password-auth-ac
89   when: not (item|exists and item|is_file)
90   tags:
91     - REC-443
92
93 - name: "Set Deny for failed password attempts 1"
94   lineinfile:
95     path: "{{item}}"
96     insertbefore: '^auth[\s]*sufficient[\s]*pam_unix.so'
97     line: 'auth        required      pam_faillock.so preauth silent audit deny=3 unlock_time=3600 fail_interval=900'
98   with_items:
99     - /etc/pam.d/system-auth-ac
100     - /etc/pam.d/password-auth-ac
101   tags:
102     - REC-443
103
104 - name: "Set Deny for failed password attempts 2"
105   lineinfile:
106     path: "{{item}}"
107     insertafter: '^auth[\s]*sufficient[\s]*pam_unix.so'
108     line: 'auth        [default=die]  pam_faillock.so authfail audit deny=3 unlock_time=3600 fail_interval=900'
109   with_items:
110     - /etc/pam.d/system-auth-ac
111     - /etc/pam.d/password-auth-ac
112   tags:
113     - REC-443
114
115 - name: "Set Deny for failed password attempts 3"
116   lineinfile:
117     path: "{{item}}"
118     insertbefore: '^account[\s]*required[\s]*pam_unix.so'
119     line: 'account     required      pam_faillock.so'
120   with_items:
121     - /etc/pam.d/system-auth-ac
122     - /etc/pam.d/password-auth-ac
123   tags:
124     - REC-443
125
126 - name: "Set Account expiration following inactivity"
127   lineinfile:
128     create: yes
129     path: "/etc/default/useradd"
130     regexp: "^INACTIVE"
131     line: "INACTIVE=35"
132   tags:
133     - REC-443
134
135 #
136 # YUM config
137 #
138
139 - name: "Ensure YUM Removes Previous Package Versions"
140   lineinfile:
141     path: /etc/yum.conf
142     insertafter: '^[#\s]*\[main\]'
143     line: 'clean_requirements_on_remove = 1'
144
145 - name: "Ensure gpgcheck Enabled for Local Packages"
146   lineinfile:
147     path: /etc/yum.conf
148     insertafter: '^[#\s]*\[main\]'
149     line: 'localpkg_gpgcheck = 1'
150
151 #
152 # Setting Ctrl-Alt-Del action
153 #
154
155 - name: "Disable Ctrl-Alt-Del Burst Action"
156   lineinfile:
157     path: /etc/systemd/system.conf
158     insertafter: '^[#\s]*CtrlAltDelBurstAction'
159     line: 'CtrlAltDelBurstAction=none'
160
161 - name: "Disable Ctrl-Alt-Del Reboot Activation"
162   command: systemctl mask ctrl-alt-del.target
163
164 #
165 # Configure kernel modules
166 #
167
168 - name: "kernel module setting"
169   lineinfile:
170     create=yes
171     dest="/etc/modprobe.d/{{item}}.conf"
172     regexp="{{item}}"
173     line="install {{item}} /bin/true"
174   with_items:
175     - bluetooth
176     - dccp
177     - squashfs
178     - hfsplus
179     - hfs
180     - jffs2
181     - freevxfs
182     - cramfs
183     - usb-storage
184     - udf
185     - nfsd
186
187 #
188 # Disable interactive boot
189 #
190
191 - name:  Verify that Interactive Boot is Disabled GRUB_CMDLINE_LINUX Setting
192   lineinfile:
193     path: /etc/default/grub
194     backrefs: yes
195     regexp: '^GRUB_CMDLINE_LINUX=(.*)systemd\.confirm_spawn=(1|yes|true|on)\s*(.*)$'
196     line: 'GRUB_CMDLINE_LINUX=\1\3'
197
198 - name:  Verify that Interactive Boot is Disabled GRUB_CMDLINE_LINUX_DEFAULT Setting
199   lineinfile:
200     path: /etc/default/grub
201     backrefs: yes
202     regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=(.*)systemd\.confirm_spawn=(1|yes|true|on)\s*(.*)$'
203     line: 'GRUB_CMDLINE_LINUX_DEFAULT=\1\3'
204
205 #
206 # Set file permissions
207 #
208
209 - name: "Check files exist to determine the proper location of grub.cfg on UEFI systems"
210   stat: path={{item}}
211   with_items:
212     - /boot/efi/EFI/centos/grub.cfg
213     - /boot/grub2/grub.cfg
214     - /var/log/boot.log
215     - /var/log/cron
216   register: file_stat
217
218 - name: "Set the 600 file permissions"
219   file:
220     path: "{{item.item}}"
221     state: touch
222     mode: "600"
223   with_items: "{{ file_stat.results }}"
224   when:
225     - item.stat.exists == true
226
227 #
228 # Disable direct root login
229 #
230
231 - name: "Direct root Logins Not Allowed"
232   shell: echo > /etc/securetty
233
234 - name: Change 'root' shell to nologin
235   user:
236     name: root
237     shell: /sbin/nologin
238
239 - name: Lock 'root' password
240   user:
241     name: root
242     password: '!!'
243
244 #
245 # Configure IPv6
246 #
247
248 - name: Disable ipv6 support if the ipv6 is not needed
249   when: ansible_default_ipv6|length == 0
250   sysctl:
251     name: net.ipv6.conf.all.disable_ipv6
252     value: 1
253     state: present
254     reload: yes
255
256 - name: Disable Support for udp6
257   when: ansible_default_ipv6|length == 0
258   lineinfile:
259     path: /etc/netconfig
260     state: absent
261     regexp: '^udp6.*'
262
263 - name: Disable Support for tcp6
264   when: ansible_default_ipv6|length == 0
265   lineinfile:
266     path: /etc/netconfig
267     state: absent
268     regexp: '^tcp6.*'
269
270 - name: Disable automatic ipv6 configuration
271   when: ansible_default_ipv6|length > 0
272   sysctl:
273     name: "{{ item.name }}"
274     value: "{{ item.value }}"
275     state: present
276     reload: yes
277   with_items:
278     - { name: 'net.ipv6.conf.all.accept_source_route', value: 0 }
279     - { name: 'net.ipv6.conf.all.accept_ra', value: 0 }
280     - { name: 'net.ipv6.conf.default.accept_ra', value: 0 }
281     - { name: 'net.ipv6.conf.all.accept_redirects', value: 0 }
282     - { name: 'net.ipv6.conf.default.accept_redirects', value: 0 }
283     - { name: 'net.ipv6.conf.default.accept_source_route', value: 0 }
284     - { name: 'net.ipv6.conf.all.forwarding', value: 0 }
285
286 #
287 # Configure kernel parameters
288 #
289
290 - name: Configure the kernel parameters
291   sysctl:
292     name: "{{ item.name }}"
293     value: "{{ item.value }}"
294     state: present
295     reload: yes
296   with_items:
297     - { name: 'net.ipv4.conf.default.send_redirects', value: 0 }
298     - { name: 'net.ipv4.conf.all.send_redirects', value: 0 }
299     - { name: 'net.ipv4.ip_forward', value: 0 }
300     - { name: 'net.ipv4.conf.all.accept_redirects', value: 0 }
301     - { name: 'net.ipv4.conf.all.secure_redirects', value: 0 }
302     - { name: 'net.ipv4.conf.all.log_martians', value: 1 }
303     - { name: 'net.ipv4.conf.default.log_martians', value: 1 }
304     - { name: 'net.ipv4.conf.default.accept_redirects', value: 0 }
305     - { name: 'net.ipv4.conf.default.secure_redirects', value: 0 }
306     - { name: 'net.ipv4.icmp_echo_ignore_broadcasts', value: 1 }
307     - { name: 'net.ipv4.icmp_ignore_bogus_error_responses', value: 1 }
308     - { name: 'net.ipv4.tcp_syncookies', value: 1 }
309     - { name: 'fs.suid_dumpable', value: 0 }
310     - { name: 'kernel.dmesg_restrict', value: 1 }
311     - { name: 'kernel.core_uses_pid', value: 1 }
312     - { name: 'kernel.randomize_va_space', value: 2 }
313     - { name: 'kernel.core_pattern', value: '/var/core/core'}
314     - { name: 'kernel.kptr_restrict', value: 2 }
315
316 #
317 # Configure core dump
318 #
319
320 - name: "Disable core dump for all user"
321   lineinfile:
322     path: /etc/security/limits.conf
323     insertbefore: '^[a-z].*'
324     line: '*               hard    core            0'
325
326 - name: "Configure systemd not to store core dumps"
327   lineinfile:
328     path: /etc/systemd/coredump.conf
329     insertafter: '^\[Coredump\]'
330     line: 'Storage=none'
331
332 #
333 # Confingure kernel dump
334 - name: "Disable kernel dump service"
335   shell: systemctl stop kdump.service
336
337 - name: "Disable kernel dump service"
338   shell: systemctl disable kdump.service
339
340 # Configure syslog
341 #
342 - name: "Stop rsyslog Service"
343   shell: systemctl stop rsyslog.service
344
345 - name: "Disable rsyslog Service"
346   shell: systemctl disable rsyslog.service
347
348 - name: "Ensure the /var/log/boot.log Rotated by logrotate"
349   lineinfile:
350     path: /etc/logrotate.d/syslog
351     insertbefore: 'cron$'
352     line: /var/log/boot.log
353
354 - name: "Set the umasks by profile file"
355   lineinfile:
356     path: /etc/profile
357     regexp: '{{ item.old }}'
358     line: '{{ item.new }}'
359   with_items:
360     - { old: 'umask 002', new: umask 027 }
361     - { old: 'umask 022', new: umask 077 }
362
363 #
364 # Keystone config
365 #
366
367 - name: Set the max_request_body_size in the keystone.conf
368   lineinfile:
369     path: /etc/keystone/keystone.conf
370     insertafter: 'DEFAULT'
371     line: "# enforced by optional sizelimit middleware (keystone.middleware:RequestBodySizeLimiter)\nmax_request_body_size = 114688\n"
372
373 - name: Set the insecure_debug in the keystone.conf
374   lineinfile:
375     path: /etc/keystone/keystone.conf
376     insertafter: 'DEFAULT'
377     line: "# If set to true, then the server will return information in HTTP responses\n# that may allow an unauthenticated or authenticated user to get more\n# information than normal, such as additional details about why authentication\n# failed. This may be useful for debugging but is insecure. (boolean value)\ninsecure_debug = false\n"
378
379 #
380 #Setting bootloader password
381 #
382 - name: set host os variable
383   when: host_os is defined
384   set_fact:
385     grub2_pass: "{{  host_os.grub2_password | default('Empty')  }}"
386
387 - name: protect grub with root password
388   when: grub2_pass is defined and grub2_pass != 'Empty'
389   blockinfile:
390     dest: /etc/grub.d/40_custom
391     state: present
392     insertafter: 'EOF'
393     content: |
394       # define superusers
395       set superusers="root"
396       #define users
397       password_pbkdf2 root "{{ grub2_pass }}"
398
399 - name: check whether grub-efi exists
400   stat:
401     path: /boot/efi/EFI/centos/grub.cfg
402   register: grub_efi_file_stat
403
404 - name: generate grub config
405   when: grub2_pass is defined and grub2_pass != 'Empty'
406   command: /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
407
408 - name: generate grub-efi config
409   command: /usr/sbin/grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
410   when:
411     - grub2_pass is defined and grub2_pass != 'Empty'
412     - grub_efi_file_stat.stat.exists == true
413
414 #
415 #Setting the noexec option to the /dev/shm mount dir
416 #
417
418 - name: get back device associated to mountpoint
419   shell: mount | grep ' /dev/shm ' |cut -d ' ' -f 1
420   register: device_name
421   check_mode: no
422
423 - name: get back device previous mount option
424   shell: mount | grep ' /dev/shm ' | sed -re 's:.*\((.*)\):\1:'
425   register: device_cur_mountoption
426   check_mode: no
427
428 - name: get back device fstype
429   shell: mount | grep ' /dev/shm ' | cut -d ' ' -f 5
430   register: device_fstype
431   check_mode: no
432
433 - name: Ensure permission noexec are set on /dev/shm
434   mount:
435     path: "/dev/shm"
436     src: "{{device_name.stdout}}"
437     opts: "{{device_cur_mountoption.stdout}},noexec"
438     state: "mounted"
439     fstype: "{{device_fstype.stdout}}"
440
441 #
442 # Disable NFS service
443 #
444
445 - name: disable NFS related services
446   service:
447     name: "{{ item }}"
448     enabled: no
449     state: stopped
450   ignore_errors: yes
451   with_items:
452     - nfslock
453     - rpcgssd
454     - rpcidmapd
455     - nfs-idmap
456     - nfs-server
457     - nfs
458
459 - name: remove nfs-utils package
460   yum:
461     name: nfs-utils
462     state: absent
463
464 #
465 # tighten USB permissions
466 #
467 - name: Set USBGuard RestoreControllerDeviceState to false
468   lineinfile:
469     path: /etc/usbguard/usbguard-daemon.conf
470     regexp: '^[#\s]*RestoreControllerDeviceState\s*=\s*[a-z\-]*\s*$'
471     line: 'RestoreControllerDeviceState=false'
472
473 - name: Set USBGuard ImplicitPolicyTarget to block
474   lineinfile:
475     path: /etc/usbguard/usbguard-daemon.conf
476     regexp: '^[#\s]*ImplicitPolicyTarget\s*=\s*[a-z\-]*\s*$'
477     line: 'ImplicitPolicyTarget=block'
478
479 - name: Apply USBGuard policy in all cases
480   lineinfile:
481     path: /etc/usbguard/usbguard-daemon.conf
482     regexp: "^[#\\s]*{{ item }}\\s*=\\s*[a-z\\-]*\\s*$"
483     line: "{{ item }}=apply-policy"
484   with_items:
485     - PresentControllerPolicy
486     - PresentDevicePolicy
487     - InsertedDevicePolicy
488
489 - name: Limit USBGuard IPC to root
490   lineinfile:
491     path: /etc/usbguard/usbguard-daemon.conf
492     regexp: "^[#\\s]*IPCAllowed{{item}}\\s*="
493     line: "IPCAllowed{{item}}=root"
494   with_items:
495     - Users
496     - Groups
497
498 - Name: Ban suspect USB devices
499   blockinfile:
500     # this isn't the optimal way to do this, i know, but i don't
501     # want to create a whole new template tree just to add this.
502     path: /etc/usbguard/rules.conf
503     create: yes
504     owner: root
505     group: root
506     mode: 0700
507     insertbefore: BOF
508     # rules.conf doesn't seem to allow comments
509     marker: ''
510     block: |
511      # the akraino REC is targeted at server installs; as such
512      # we're liberal about allowing standard devices on the
513      # assumption we will be deployed in a relatively secure
514      # environment.  The values below were chosen based on the
515      # devices that appear on a nokia OE19 with the virtual console
516      # enabled:
517      # xHCI controller/hub
518      allow with-interface equals { 09:00:00 }
519      # mass media — sites may want to consider restricting
520      # this to 08:06:50 to just get the virtual CDROM and ban
521      # other USB media
522      allow with-interface equals { 08:*:* }
523      # ethernet
524      allow with-interface equals { 02:02:ff }
525      # keyboard/mouse
526      allow with-interface one-of { 03:00:01 03:01:01 }
527      # per usbguard-rules.conf manpage: ban keyboard devices
528      # that expose other, suspicious, interfaces
529      reject with-interface all-of { 08:*:* 03:00:* }
530      reject with-interface all-of { 08:*:* 03:01:* }
531      reject with-interface all-of { 08:*:* e0:*:* }
532      reject with-interface all-of { 08:*:* 02:*:* }
533
534 # Setting file permissions
535 #
536
537 #- name: "Remove the other user write permission from the system directorys"
538 #  command: find / -xdev \( -perm -0002 -a ! -perm -1000 \) -type d -exec chmod o-w {} \;
539 #
540 #- name: "Remove the other user write permission from the system files"
541 #  command: find / -xdev -perm -0002 -type f -exec chmod o-w {} \;
542 #
543 #- name: "Modified the unauthorized SUID/SGID system executables"
544 #  command: sudo chmod -s $(sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | grep -v sudo)