Major Hayden dccce1d5cc
Handle RHEL 7 STIG renumbering
This patch gets the docs adjusted to work with the new RHEL 7 STIG
version 1 release. The new STIG release has changed all of the
numbering, but it maintains a link to (most) of the old STIG IDs in
the XML.

Closes-bug: 1676865
Change-Id: I65023fe63163c9804a3aec9dcdbf23c69bedb604
2017-04-04 07:22:12 -05:00

464 lines
12 KiB
YAML

---
# Copyright 2016, Rackspace US, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Get a list of users on the system to use throughout the auth tasks
action: get_users
register: user_list
check_mode: no
tags:
- always
- name: Check if /etc/security/pwquality.conf exists
stat:
path: /etc/security/pwquality.conf
check_mode: no
register: pwquality_config_check
tags:
- always
- name: Set password quality requirements
blockinfile:
dest: /etc/security/pwquality.conf
backup: yes
insertbefore: EOF
marker: "# {mark} Added by openstack-ansible-security role"
state: present
block: "{{ lookup('template', 'pwquality.conf.j2') }}"
when:
- pwquality_config_check.stat.exists
tags:
- auth
- medium
- V-71903
- V-71905
- V-71907
- V-71909
- V-71911
- V-71913
- V-71915
- V-71917
- V-71935
- name: Use pwquality when passwords are changed or created
lineinfile:
dest: /etc/pam.d/passwd
line: "password required pam_pwquality.so retry=3"
state: present
when:
- security_enable_pwquality_password_set | bool
tags:
- auth
- medium
- V-73159
- name: Check for SHA512 password storage in PAM
command: "grep pam_unix.so {{ pam_password_file }}"
register: password_sha512_check
changed_when: False
check_mode: no
tags:
- always
- name: V-71919 - The PAM system service must be configured to store only encrypted representations of passwords.
debug:
msg: >
PAM is not using SHA512 for password storage. This is a security issue.
when:
- password_sha512_check is defined
- "'sha512' not in password_sha512_check.stdout"
tags:
- auth
- medium
- V-71919
- name: Configure shadow-utils configuration
lineinfile:
dest: /etc/login.defs
regexp: "^{{ item.parameter }}"
line: "{{ item.parameter }} {{ item.value }}"
state: present
when:
- item.value != ''
- item.ansible_os_family == 'all' or item.ansible_os_family == ansible_os_family
with_items: "{{ shadow_utils_rhel7 }}"
tags:
- auth
- medium
- V-71921
- V-71925
- V-71929
- V-71951
- V-71995
- V-72013
# NOTE(mhayden): pam_faildelay expects the `delay` parameter to be in
# microseconds.
- name: Set pam_faildelay configuration on Ubuntu
lineinfile:
dest: /etc/pam.d/login
regexp: '^(auth[\s]+optional[\s]+pam_faildelay.so).*$'
line: '\1 delay={{ security_shadow_utils_fail_delay * 10**6 }}'
state: present
backrefs: yes
when:
- security_shadow_utils_fail_delay is defined
- ansible_os_family | lower == 'debian'
tags:
- auth
- medium
- V-71951
- name: V-71923 - User and group account administration utilities must be configured to store only encrypted representations of passwords.
ini_file:
dest: /etc/libuser.conf
section: defaults
option: crypt_style
value: sha512
backup: yes
when:
- security_libuser_crypt_style_sha512 | bool
- ansible_os_family | lower == 'redhat'
tags:
- auth
- medium
- V-71923
- name: Get all user accounts with a password lifetime limit under 24 hours
shell: "awk -F: '$4 < 1 {print $1}' /etc/shadow"
check_mode: no
changed_when: False
register: password_lifetime_check
tags:
- auth
- medium
- V-71927
- skip_ansible_lint
- name: V-71927 - Passwords must be restricted to a 24 hours/1 day minimum lifetime.
debug:
msg: |
Accounts were found with a minimum password lifetime limit under 24 hours:
{{ password_lifetime_check.stdout_lines | join(', ') }}
when:
- password_lifetime_check.stdout_lines is defined
tags:
- auth
- medium
- V-71927
- name: V-71933 - Passwords must be prohibited from reuse for a minimum of five generations.
lineinfile:
dest: "{{ pam_password_file }}"
regexp: '^(password\s+[a-z0-9\=\[\] ]+\s+pam_unix\.so.+?)\s+(?:remember=\d+)?$'
line: '\1 remember={{ security_password_remember_password }}'
backrefs: yes
state: present
when:
- security_password_remember_password is defined
tags:
- auth
- medium
- V-71933
- name: V-71931 - Existing passwords must be restricted to a 60-day maximum lifetime.
debug:
msg: |
The following user accounts have an existing password with a lifetime of
greater than 60 days:
{%- for user in user_list.users %}
{% if user['shadow']['max_days'] > 60 %}
{{ user['name'] }} has an expiration of {{ user['shadow']['max_days'] }} days
{% endif %}
{% endfor %}
tags:
- auth
- medium
- V-71931
- name: V-71937 - The system must not have accounts configured with blank or null passwords
lineinfile:
dest: "{{ pam_auth_file }}"
state: present
regexp: "^(.*)nullok_secure(.*)$"
line: '\1\2'
backup: yes
backrefs: yes
when:
- ansible_os_family == 'Debian'
- security_disallow_blank_password_login | bool
tags:
- auth
- high
- V-71937
- name: V-71937 - The system must not have accounts configured with blank or null passwords
lineinfile:
dest: "{{ pam_auth_file }}"
state: present
regexp: "^({{ item }}.*sufficient.*)nullok(.*)$"
line: '\1\2'
backup: yes
backrefs: yes
with_items:
- auth
- password
when:
- ansible_os_family == 'RedHat'
- security_disallow_blank_password_login | bool
tags:
- auth
- high
- V-71937
- name: V-71941 - The operating system must disable account identifiers if the password expires.
lineinfile:
dest: /etc/default/useradd
regexp: '^[#\s]*INACTIVE'
line: 'INACTIVE=0'
when:
- security_disable_account_if_password_expires | bool
tags:
- auth
- medium
- V-71941
- name: V-71945 - If three unsuccessful logon attempts within 15 minutes occur the associated account must be locked.
blockinfile:
dest: pam_password_file
state: present
marker: "# {mark} MANAGED BY OPENSTACK-ANSIBLE-SECURITY"
insertbefore: EOF
block: "{{ lookup('template', 'pam_faillock.j2') }}"
when:
- ansible_os_family | lower == 'redhat'
- security_pam_faillock_enable | bool
tags:
- auth
- medium
- V-71943
- V-71945
- name: Check for 'nopasswd' in sudoers files
shell: grep -ir nopasswd /etc/sudoers /etc/sudoers.d/ || echo 'not found'
register: sudoers_nopasswd_check
changed_when: False
tags:
- auth
- medium
- V-71947
- name: V-71947 - Users must provide a password for privilege escalation.
debug:
msg: >
The 'NOPASSWD' directive was found in the sudoers configuration files.
Remove the directive to ensure that all users must provide a password to
run commands as the root user.
when:
- not sudoers_nopasswd_check | skipped
- sudoers_nopasswd_check.stdout != 'not found'
tags:
- auth
- medium
- V-71947
- skip_ansible_lint
- name: Check for '!authenticate' in sudoers files
shell: grep -ir '\!authenticate' /etc/sudoers /etc/sudoers.d/ || echo 'not found'
register: sudoers_authenticate_check
changed_when: False
tags:
- auth
- medium
- V-71949
- name: V-71949 - Users must re-authenticate for privilege escalation.
debug:
msg: >
The '!authenticate' directive was found in the sudoers configuration
files. Remove the directive to ensure that all users must provide a
password to run commands as the root user each time they use sudo.
when:
- not sudoers_authenticate_check | skipped
- sudoers_authenticate_check.stdout != 'not found'
tags:
- auth
- medium
- V-71949
- skip_ansible_lint
- name: Check if sssd.conf exists
stat:
path: /etc/sssd/sssd.conf
register: sssd_conf_check
check_mode: no
tags:
- always
- name: Set a GRUB 2 password for single-user/maintenance modes
lineinfile:
dest: "{{ grub_defaults_file }}"
regexp: '^(#)?GRUB_PASSWORD'
line: 'GRUB_PASSWORD="{{ security_grub_password_hash }}"'
state: present
when:
- security_require_grub_authentication | bool
notify:
- update grub config
tags:
- auth
- high
- V-71961
- V-71963
- name: Get all accounts with UID 0
shell: "awk -F: '$3 == 0 {print $1}' /etc/passwd"
changed_when: False
check_mode: no
register: root_user_check
tags:
- auth
- high
- V-72005
- skip_ansible_lint
- name: Check for groups in /etc/passwd that are not in /etc/group
debug:
msg: >
The following users have GIDs in /etc/passwd that do not exist in /etc/group:
{{ user_list.users | selectattr('group', 'equalto', False) | map(attribute='name') | join(', ') }}
when:
- user_list is defined
- user_list.users | selectattr('group', 'equalto', False) | list | length > 0
tags:
- auth
- low
- V-72003
- name: V-72005 - The root account must be the only account having unrestricted access to the system
fail:
msg: |
Only the 'root' user should have UID 0. Other users were found:
{{ root_user_check.stdout_lines | join(', ') }}"
when:
- root_user_check.stdout != 'root'
tags:
- auth
- high
- V-72005
- name: V-72011 - All local interactive users must have a home directory assigned in the /etc/passwd file.
debug:
msg: |
The following users do not have a home directory assigned:
{{ user_list.users | selectattr('dir', 'equalto', '') | map(attribute='name') | join(', ') }}
when:
- user_list is defined
- user_list.users | selectattr('dir', 'equalto', '') | map(attribute='name') | list | length > 0
tags:
- auth
- medium
- V-72011
- name: Check each user to see if its home directory exists on the filesystem
stat:
path: "{{ item['dir'] }}"
when:
- item['dir'] != ''
with_items: "{{ user_list.users }}"
register: home_directory_checks
tags:
- auth
- medium
- V-72015
- name: V-72015 - All local interactive user home directories defined in the /etc/passwd file must exist.
debug:
msg: |
These users have a home directory assigned, but the directory does not exist:
{% for check in home_directory_checks.results %}
{% if not check.stat.exists %}
{{ check.item.name }} ({{ check.item.dir }} does not exist)
{% endif %}
{% endfor %}
when:
- home_directory_checks.results | selectattr('stat.exists', 'sameas', false) | list | length > 0
tags:
- auth
- medium
- V-72015
- name: V-72217 - The operating system must limit the number of concurrent sessions to 10 for all accounts and/or account types.
blockinfile:
dest: /etc/security/limits.d/openstack-ansible-security-maxlogins.conf
create: yes
block: |
# Deployed by the openstack-ansible-security role
# V-72217 - Limit concurrent sessions for all accounts/types
* hard maxlogins {{ security_rhel7_concurrent_session_limit }}
when:
- security_rhel7_concurrent_session_limit is defined
tags:
- auth
- low
- V-72217
- name: Check for pam_lastlog in PAM configuration
command: "grep pam_lastlog {{ pam_postlogin_file }}"
register: pam_lastlog_check
changed_when: False
failed_when: False
check_mode: no
tags:
- always
- name: V-72275 - Display date/time of last logon after logon
debug:
msg: >
The 'pam_lastlog' directive is missing in {{ pam_postlogin_file }}.
This is required by V-72275.
when:
- pam_lastlog_check.rc != 0
tags:
- low
- auth
- V-72275
- name: Check for .shosts or shosts.equiv files
find:
paths: /
recurse: yes
hidden: yes
patterns: '.shosts,shosts.equiv'
register: shosts_find
when:
- security_rhel7_remove_shosts_files | bool
tags:
- always
- name: Remove .shosts or shosts.equiv files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{ shosts_find.files }}"
when:
- security_rhel7_remove_shosts_files | bool
- shosts_find is defined
- shosts_find.files is defined
tags:
- high
- auth
- V-72277
- V-72279