Ensure authconfig is properly configured
[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 #
70 # Linux Failed password attempts
71 #
72 - name: "Ensure authconfig is properly configured"
73   command: authconfig --updateall
74   with_items:
75     - /etc/pam.d/system-auth-ac
76     - /etc/pam.d/password-auth-ac
77   when: not (item|exists and item|is_file)
78   tags:
79     - REC-443
80
81 - name: "Set Deny for failed password attempts 1"
82   lineinfile:
83     path: "{{item}}"
84     insertbefore: '^auth[\s]*sufficient[\s]*pam_unix.so'
85     line: 'auth        required      pam_faillock.so preauth silent audit deny=3 unlock_time=3600 fail_interval=900'
86   with_items:
87     - /etc/pam.d/system-auth-ac
88     - /etc/pam.d/password-auth-ac
89   tags:
90     - REC-443
91
92 - name: "Set Deny for failed password attempts 2"
93   lineinfile:
94     path: "{{item}}"
95     insertafter: '^auth[\s]*sufficient[\s]*pam_unix.so'
96     line: 'auth        [default=die]  pam_faillock.so authfail audit deny=3 unlock_time=3600 fail_interval=900'
97   with_items:
98     - /etc/pam.d/system-auth-ac
99     - /etc/pam.d/password-auth-ac
100   tags:
101     - REC-443
102
103 - name: "Set Deny for failed password attempts 3"
104   lineinfile:
105     path: "{{item}}"
106     insertbefore: '^account[\s]*required[\s]*pam_unix.so'
107     line: 'account     required      pam_faillock.so'
108   with_items:
109     - /etc/pam.d/system-auth-ac
110     - /etc/pam.d/password-auth-ac
111   tags:
112     - REC-443
113
114 - name: "Set Account expiration following inactivity"
115   lineinfile:
116     create: yes
117     path: "/etc/default/useradd"
118     regexp: "^INACTIVE"
119     line: "INACTIVE=35"
120   tags:
121     - REC-443
122
123 #
124 # YUM config
125 #
126
127 - name: "Ensure YUM Removes Previous Package Versions"
128   lineinfile:
129     path: /etc/yum.conf
130     insertafter: '^[#\s]*\[main\]'
131     line: 'clean_requirements_on_remove = 1'
132
133 - name: "Ensure gpgcheck Enabled for Local Packages"
134   lineinfile:
135     path: /etc/yum.conf
136     insertafter: '^[#\s]*\[main\]'
137     line: 'localpkg_gpgcheck = 1'
138
139 #
140 # Setting Ctrl-Alt-Del action
141 #
142
143 - name: "Disable Ctrl-Alt-Del Burst Action"
144   lineinfile:
145     path: /etc/systemd/system.conf
146     insertafter: '^[#\s]*CtrlAltDelBurstAction'
147     line: 'CtrlAltDelBurstAction=none'
148
149 - name: "Disable Ctrl-Alt-Del Reboot Activation"
150   command: systemctl mask ctrl-alt-del.target
151
152 #
153 # Configure kernel modules
154 #
155
156 - name: "kernel module setting"
157   lineinfile:
158     create=yes
159     dest="/etc/modprobe.d/{{item}}.conf"
160     regexp="{{item}}"
161     line="install {{item}} /bin/true"
162   with_items:
163     - bluetooth
164     - dccp
165     - squashfs
166     - hfsplus
167     - hfs
168     - jffs2
169     - freevxfs
170     - cramfs
171     - usb-storage
172     - udf
173     - nfsd
174
175 #
176 # Disable interactive boot
177 #
178
179 - name:  Verify that Interactive Boot is Disabled GRUB_CMDLINE_LINUX Setting
180   lineinfile:
181     path: /etc/default/grub
182     backrefs: yes
183     regexp: '^GRUB_CMDLINE_LINUX=(.*)systemd\.confirm_spawn=(1|yes|true|on)\s*(.*)$'
184     line: 'GRUB_CMDLINE_LINUX=\1\3'
185
186 - name:  Verify that Interactive Boot is Disabled GRUB_CMDLINE_LINUX_DEFAULT Setting
187   lineinfile:
188     path: /etc/default/grub
189     backrefs: yes
190     regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=(.*)systemd\.confirm_spawn=(1|yes|true|on)\s*(.*)$'
191     line: 'GRUB_CMDLINE_LINUX_DEFAULT=\1\3'
192
193 #
194 # Set file permissions
195 #
196
197 - name: "Check files exist to determine the proper location of grub.cfg on UEFI systems"
198   stat: path={{item}}
199   with_items:
200     - /boot/efi/EFI/centos/grub.cfg
201     - /boot/grub2/grub.cfg
202     - /var/log/boot.log
203     - /var/log/cron
204   register: file_stat
205
206 - name: "Set the 600 file permissions"
207   file:
208     path: "{{item.item}}"
209     state: touch
210     mode: "600"
211   with_items: "{{ file_stat.results }}"
212   when:
213     - item.stat.exists == true
214
215 #
216 # Disable direct root login
217 #
218
219 - name: "Direct root Logins Not Allowed"
220   shell: echo > /etc/securetty
221
222 - name: Change 'root' shell to nologin
223   user:
224     name: root
225     shell: /sbin/nologin
226
227 - name: Lock 'root' password
228   user:
229     name: root
230     password: '!!'
231
232 #
233 # Configure IPv6
234 #
235
236 - name: Disable ipv6 support if the ipv6 is not needed
237   when: ansible_default_ipv6|length == 0
238   sysctl:
239     name: net.ipv6.conf.all.disable_ipv6
240     value: 1
241     state: present
242     reload: yes
243
244 - name: Disable Support for udp6
245   when: ansible_default_ipv6|length == 0
246   lineinfile:
247     path: /etc/netconfig
248     state: absent
249     regexp: '^udp6.*'
250
251 - name: Disable Support for tcp6
252   when: ansible_default_ipv6|length == 0
253   lineinfile:
254     path: /etc/netconfig
255     state: absent
256     regexp: '^tcp6.*'
257
258 - name: Disable automatic ipv6 configuration
259   when: ansible_default_ipv6|length > 0
260   sysctl:
261     name: "{{ item.name }}"
262     value: "{{ item.value }}"
263     state: present
264     reload: yes
265   with_items:
266     - { name: 'net.ipv6.conf.all.accept_source_route', value: 0 }
267     - { name: 'net.ipv6.conf.all.accept_ra', value: 0 }
268     - { name: 'net.ipv6.conf.default.accept_ra', value: 0 }
269     - { name: 'net.ipv6.conf.all.accept_redirects', value: 0 }
270     - { name: 'net.ipv6.conf.default.accept_redirects', value: 0 }
271     - { name: 'net.ipv6.conf.default.accept_source_route', value: 0 }
272     - { name: 'net.ipv6.conf.all.forwarding', value: 0 }
273
274 #
275 # Configure kernel parameters
276 #
277
278 - name: Configure the kernel parameters
279   sysctl:
280     name: "{{ item.name }}"
281     value: "{{ item.value }}"
282     state: present
283     reload: yes
284   with_items:
285     - { name: 'net.ipv4.conf.default.send_redirects', value: 0 }
286     - { name: 'net.ipv4.conf.all.send_redirects', value: 0 }
287     - { name: 'net.ipv4.ip_forward', value: 0 }
288     - { name: 'net.ipv4.conf.all.accept_redirects', value: 0 }
289     - { name: 'net.ipv4.conf.all.secure_redirects', value: 0 }
290     - { name: 'net.ipv4.conf.all.log_martians', value: 1 }
291     - { name: 'net.ipv4.conf.default.log_martians', value: 1 }
292     - { name: 'net.ipv4.conf.default.accept_redirects', value: 0 }
293     - { name: 'net.ipv4.conf.default.secure_redirects', value: 0 }
294     - { name: 'net.ipv4.icmp_echo_ignore_broadcasts', value: 1 }
295     - { name: 'net.ipv4.icmp_ignore_bogus_error_responses', value: 1 }
296     - { name: 'net.ipv4.tcp_syncookies', value: 1 }
297     - { name: 'fs.suid_dumpable', value: 0 }
298     - { name: 'kernel.dmesg_restrict', value: 1 }
299     - { name: 'kernel.core_uses_pid', value: 1 }
300     - { name: 'kernel.randomize_va_space', value: 2 }
301     - { name: 'kernel.core_pattern', value: '/var/core/core'}
302
303 #
304 # Configure core dump
305 #
306
307 - name: "Disable core dump for all user"
308   lineinfile:
309     path: /etc/security/limits.conf
310     insertbefore: '^[a-z].*'
311     line: '*               hard    core            0'
312
313 - name: "Configure systemd not to store core dumps"
314   lineinfile:
315     path: /etc/systemd/coredump.conf
316     insertafter: '^\[Coredump\]'
317     line: 'Storage=none'
318
319 #
320 # Configure syslog
321 #
322 - name: "Stop rsyslog Service"
323   shell: systemctl stop rsyslog.service
324
325 - name: "Disable rsyslog Service"
326   shell: systemctl disable rsyslog.service
327
328 - name: "Ensure the /var/log/boot.log Rotated by logrotate"
329   lineinfile:
330     path: /etc/logrotate.d/syslog
331     insertbefore: 'cron$'
332     line: /var/log/boot.log
333
334 - name: "Set the umasks by profile file"
335   lineinfile:
336     path: /etc/profile
337     regexp: '{{ item.old }}'
338     line: '{{ item.new }}'
339   with_items:
340     - { old: 'umask 002', new: umask 027 }
341     - { old: 'umask 022', new: umask 077 }
342
343 #
344 # Keystone config
345 #
346
347 - name: Set the max_request_body_size in the keystone.conf
348   lineinfile:
349     path: /etc/keystone/keystone.conf
350     insertafter: 'DEFAULT'
351     line: "# enforced by optional sizelimit middleware (keystone.middleware:RequestBodySizeLimiter)\nmax_request_body_size = 114688\n"
352
353 - name: Set the insecure_debug in the keystone.conf
354   lineinfile:
355     path: /etc/keystone/keystone.conf
356     insertafter: 'DEFAULT'
357     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"
358
359 #
360 #Setting bootloader password
361 #
362 - name: set host os variable
363   when: host_os is defined
364   set_fact:
365     grub2_pass: "{{  host_os.grub2_password | default('Empty')  }}"
366
367 - name: protect grub with root password
368   when: grub2_pass is defined and grub2_pass != 'Empty'
369   blockinfile:
370     dest: /etc/grub.d/40_custom
371     state: present
372     insertafter: 'EOF'
373     content: |
374       # define superusers
375       set superusers="root"
376       #define users
377       password_pbkdf2 root "{{ grub2_pass }}"
378
379 - name: check whether grub-efi exists
380   stat:
381     path: /boot/efi/EFI/centos/grub.cfg
382   register: grub_efi_file_stat
383
384 - name: generate grub config
385   when: grub2_pass is defined and grub2_pass != 'Empty'
386   command: /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
387
388 - name: generate grub-efi config
389   command: /usr/sbin/grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
390   when:
391     - grub2_pass is defined and grub2_pass != 'Empty'
392     - grub_efi_file_stat.stat.exists == true
393
394 #
395 #Setting the noexec option to the /dev/shm mount dir
396 #
397
398 - name: get back device associated to mountpoint
399   shell: mount | grep ' /dev/shm ' |cut -d ' ' -f 1
400   register: device_name
401   check_mode: no
402
403 - name: get back device previous mount option
404   shell: mount | grep ' /dev/shm ' | sed -re 's:.*\((.*)\):\1:'
405   register: device_cur_mountoption
406   check_mode: no
407
408 - name: get back device fstype
409   shell: mount | grep ' /dev/shm ' | cut -d ' ' -f 5
410   register: device_fstype
411   check_mode: no
412
413 - name: Ensure permission noexec are set on /dev/shm
414   mount:
415     path: "/dev/shm"
416     src: "{{device_name.stdout}}"
417     opts: "{{device_cur_mountoption.stdout}},noexec"
418     state: "mounted"
419     fstype: "{{device_fstype.stdout}}"
420
421 #
422 # Disable NFS service
423 #
424
425 - name: disable NFS related services
426   service:
427     name: "{{ item }}"
428     enabled: no
429     state: stopped
430   ignore_errors: yes
431   with_items:
432     - nfslock
433     - rpcgssd
434     - rpcidmapd
435     - nfs-idmap
436     - nfs-server
437     - nfs
438
439 - name: remove nfs-utils package
440   yum:
441     name: nfs-utils
442     state: absent
443
444 #
445 # Setting file permissions
446 #
447
448 #- name: "Remove the other user write permission from the system directorys"
449 #  command: find / -xdev \( -perm -0002 -a ! -perm -1000 \) -type d -exec chmod o-w {} \;
450 #
451 #- name: "Remove the other user write permission from the system files"
452 #  command: find / -xdev -perm -0002 -type f -exec chmod o-w {} \;
453 #
454 #- name: "Modified the unauthorized SUID/SGID system executables"
455 #  command: sudo chmod -s $(sudo find / -xdev \( -perm -4000 -o -perm -2000 \) -type f | grep -v sudo)