## 1. Project Overview & Quickstart (dev-sec/ansible-collection-hardening)

## File: README.md

# Ansible Collection - devsec.hardening

[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/os_hardening.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/os_hardening_vm.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening_vm.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening_custom_tests.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/nginx_hardening.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/mysql_hardening.yml)

## Description

This collection provides battle tested hardening for:

- Linux operating systems:
  - CentOS Stream 9
  - AlmaLinux 8/9/10
  - Rocky Linux 8/9/10
  - Debian 11/12/13
  - Ubuntu 22.04/24.04/26.04
  - Amazon Linux (some roles supported)
  - Arch Linux (some roles supported)
  - Fedora 42/43/44 (some roles supported)
  - Suse Tumbleweed (some roles supported)
- MySQL
  - MariaDB >= 5.5.65, >= 10.1.45, >= 10.3.17
  - MySQL >= 5.7.31, >= 8.0.3
- Nginx 1.0.16 or later
- OpenSSH 5.3 and later

The hardening is intended to be compliant with the Inspec DevSec Baselines:

- <https://github.com/dev-sec/linux-baseline>
- <https://github.com/dev-sec/mysql-baseline>
- <https://github.com/dev-sec/nginx-baseline>
- <https://github.com/dev-sec/ssh-baseline>

## Looking for the old roles?

The roles are now part of the hardening-collection.
We have kept the old releases of the `os-hardening` role in this repository, so you can find the them by exploring older tags.
The last release of the standalone role was [6.2.0](https://github.com/dev-sec/ansible-collection-hardening/tree/6.2.0).

The other roles are in separate archives repositories:

- [apache_hardening](https://github.com/dev-sec/ansible-apache-hardening)
- [mysql_hardening](https://github.com/dev-sec/ansible-mysql-hardening)
- [nginx_hardening](https://github.com/dev-sec/ansible-nginx-hardening)
- [ssh_hardening](https://github.com/dev-sec/ansible-ssh-hardening)
- [windows_hardening](https://github.com/dev-sec/ansible-windows-hardening)

## Minimum required Ansible-version

- Ansible >= 2.16

## Included content

- [os_hardening](roles/os_hardening/)
- [mysql_hardening](roles/mysql_hardening/)
- [nginx_hardening](roles/nginx_hardening/)
- [ssh_hardening](roles/ssh_hardening/)

In progress, not working:

- [apache_hardening](roles/apache_hardening/)
- [windows_hardening](roles/windows_hardening/)

## Installation

Install the collection via ansible-galaxy:

`ansible-galaxy collection install devsec.hardening`

## Using this collection

Please refer to the examples in the readmes of the role.

See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.

## Contributing to this collection

See the [contributor guideline](CONTRIBUTING.md).

## Release notes

See the [changelog](https://github.com/dev-sec/ansible-os-hardening/tree/master/CHANGELOG.md).

## Roadmap

Todos:

- Work on [apache_hardening](roles/apache_hardening/) and [windows_hardening](roles/windows_hardening/)
- Add support for more operating systems

## More information

General information:

- [Ansible Collection overview](https://github.com/ansible-collections/overview)
- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html)
- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html)
- [Ansible Collections Checklist](https://github.com/ansible-collections/overview/blob/master/collection_requirements.rst)
- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
- [The Bullhorn (the Ansible Contributor newsletter)](https://us19.campaign-archive.com/home/?u=56d874e027110e35dea0e03c1&id=d6635f5420)
- [Changes impacting Contributors](https://github.com/ansible-collections/overview/issues/45)

## Licensing

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.

---

## File: roles/ssh_hardening/README.md

# dev-sec.ssh_hardening

[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening_vm.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/ssh_hardening_custom_tests.yml)

## Description

This role provides secure ssh-client and ssh-server configurations. It is intended to be compliant with the [DevSec SSH Baseline](https://github.com/dev-sec/ssh-baseline).

Warning: This role disables root-login on the target server! Please make sure you have another user with su or sudo permissions that can login into the server.

## Configuring settings not listed in role-variables

If you want to configure ssh options that are not listed above, you can use `ssh_custom_options` (for `/etc/ssh/ssh_config`) or `sshd_custom_options` (for `/etc/ssh/sshd_config`) to set them. These options will be set on the **beginning** of the file so you can override options further down in the file.

Example playbook:

```yml
- hosts: localhost
  roles:
    - devsec.hardening.ssh_hardening
  vars:
    ssh_custom_options:
      - "Include /etc/ssh/ssh_config.d/*"
    sshd_custom_options:
      - "AcceptEnv LANG"
```

## After using the role Ansibles template/copy/file module does not work anymore

If you use this role to disable SFTP (`sftp_enabled: false`) you will get errors. Ansible uses by default SFTP to transfer files to the remote hosts. You have to set `scp_if_ssh = True` in your ansible.cfg. This way Ansible uses SCP to copy files. If your control node uses OpenSSH version 9.0 or above, you also need to set `scp_extra_args = "-O"`, since starting with that version the `scp` utility also defaults to using SFTP.

## Changing the default port and idempotency

This role uses the default port 22 or the port configured in the inventory to connect to the server. If the default `ssh` port is changed via `ssh_server_ports`, once the ssh server is restarted, it will still try to connect using the previous port. In order to run this role again on the same server the inventory will have to be updated to use the new ssh port.

If idempotency is important, please consider using role [`ssh-hardening-fallback`](https://github.com/nununo/ansible-ssh-hardening-fallback), which is a wrapper around this role that falls back to port 22 if the configured port is unreachable.

## Disabling systemd-socket activation on Debian and Ubuntu systems

Since Debian 12 and Ubuntu 22.04 the ssh-daemon is not running by default anymore but is instead activated via systemd.
We revert this change to its traditional behaviour.
For more information, see [this issue](https://github.com/dev-sec/ansible-collection-hardening/issues/763).



## Supported Operating Systems
- EL
  - 8, 9, 10
- Ubuntu
  - jammy, noble, resolute
- Debian
  - trixie, bookworm, bullseye
- Alpine
- Amazon
- Fedora
- ArchLinux
- SmartOS
- FreeBSD
  - 14.0
- OpenBSD
  - 7.0

## Role Variables

- `network_ipv6_enable`
  - Default: `True`
  - Description: `false` if IPv6 is not needed. `ssh_listen_to` must also be set to listen to IPv6 addresses (for example `[::]`).
  - Type: bool
  - Required: no
- `sftp_chroot`
  - Default: `True`
  - Description: Set to `false` to disable chroot for sftp.
  - Type: bool
  - Required: no
- `sftp_chroot_dir`
  - Default: `/home/%u`
  - Description: change default stp chroot location
  - Type: str
  - Required: no
- `sftp_enabled`
  - Default: `True`
  - Description: Set to `false` to disable sftp configuration.
  - Type: bool
  - Required: no
- `sftp_umask`
  - Default: `0027`
  - Description: Specifies the umask for sftp.
  - Type: str
  - Required: no
- `ssh_allow_agent_forwarding`
  - Default: `False`
  - Description: Set to `false` to disable Agent Forwarding. Set to `true` to allow Agent Forwarding.
  - Type: bool
  - Required: no
- `ssh_allow_groups`
  - Default: ``
  - Description: if specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns.
  - Type: str
  - Required: no
- `ssh_allow_tcp_forwarding`
  - Default: `no`
  - Description: Set to `'no'` or `false` to disable TCP Forwarding. Set to `'yes'` or`True` to allow TCP Forwarding. If you are using OpenSSH >= 6.2 version, you can specify `'yes'`, `'no'`, `'all'`, `'local'`or`'remote'`.
  - Type: str
  - Required: no
- `ssh_allow_users`
  - Default: ``
  - Description: if specified, login is allowed only for user names that match one of the patterns.
  - Type: str
  - Required: no
- `ssh_authorized_keys_file`
  - Default: ``
  - Description: change default file that contains the public keys that can be used for user authentication
  - Type: str
  - Required: no
- `ssh_authorized_principals`
  - Default: `[]`
  - Description: list of hashes containing file paths and authorized principals, see `default_cstom.yml` for all options. Only used if `ssh_authorized_principals_file` is set
  - Type: list of ''
  - Required: no
- `ssh_authorized_principals_file`
  - Default: ``
  - Description: specifies the file containing principals that are allowed. Only used if `ssh_trusted_user_ca_keys_file` is set.
  - Type: str
  - Required: no
- `ssh_banner`
  - Default: `False`
  - Description: Set to `true` to print a banner on login.
  - Type: bool
  - Required: no
- `ssh_banner_path`
  - Default: `/etc/sshd/banner.txt`
  - Description: path to the SSH banner file.
  - Type: str
  - Required: no
- `ssh_challengeresponseauthentication`
  - Default: `False`
  - Description: Specifies whether challenge-response authentication is allowed (e.g. via PAM).
  - Type: bool
  - Required: no
- `ssh_ciphers`
  - Default: ``
  - Description: Change this list to overwrite ciphers. Defaults found in `defaults/main.yml`
  - Type: list of ''
  - Required: no
- `ssh_client_alive_count`
  - Default: `3`
  - Description: Defines the number of acceptable unanswered client alive messages before disconnecting clients.
  - Type: int
  - Required: no
- `ssh_client_alive_interval`
  - Default: `300`
  - Description: specifies an interval for sending keepalive messages.
  - Type: int
  - Required: no
- `ssh_client_compression`
  - Default: `False`
  - Description: Specifies whether the client requests compression.
  - Type: bool
  - Required: no
- `ssh_client_config_file`
  - Default: `/etc/ssh/ssh_config`
  - Description: path of the ssh client configuration file, e.g. `/etc/ssh/ssh_config.d/custom.conf`.
  - Type: str
  - Required: no
- `ssh_client_hardening`
  - Default: `True`
  - Description: Set to `false` to stop harden the client.
  - Type: bool
  - Required: no
- `ssh_client_host_key_algorithms`
  - Default: `[]`
  - Description: Specifies the host key algorithms that the client wants to use in order of preference. If empty the default list will be used. Otherwise overrides the setting with specified list of algorithms. Check `man ssh_config`, `ssh -Q HostKeyAlgorithms` or other sources for supported algorithms - make sure you check the correct version!
  - Type: list of ''
  - Required: no
- `ssh_client_password_login`
  - Default: `False`
  - Description: Set to `true` to allow password-based authentication with the ssh client.
  - Type: bool
  - Required: no
- `ssh_client_port`
  - Default: `22`
  - Description: Specifies the port number to connect on the remote host.
  - Type: str
  - Required: no
- `ssh_client_roaming`
  - Default: `False`
  - Description: enable experimental client roaming.
  - Type: bool
  - Required: no
- `ssh_compression`
  - Default: `False`
  - Description: Specifies whether server-side compression is enabled after the user has authenticated successfully.
  - Type: bool
  - Required: no
- `ssh_custom_options`
  - Default: `[]`
  - Description: Custom lines for SSH client configuration.
  - Type: list of ''
  - Required: no
- `ssh_custom_selinux_dir`
  - Default: `/etc/selinux/local-policies`
  - Description: directory where to store the ssh_password policy
  - Type: str
  - Required: no
- `ssh_deny_groups`
  - Default: ``
  - Description: if specified, login is disallowed for users whose primary group or supplementary group list matches one of the patterns.
  - Type: str
  - Required: no
- `ssh_deny_users`
  - Default: ``
  - Description: if specified, login is disallowed for user names that match one of the patterns.
  - Type: str
  - Required: no
- `ssh_forward_agent`
  - Default: `no`
  - Description: Enables the ssh forward agent for the Cli if set to 'yes'
  - Type: str
  - Required: no
- `ssh_gateway_ports`
  - Default: `False`
  - Description: Set to `false` to disable binding forwarded ports to non-loopback addresses. Set to `true` to force binding on wildcard address. Set to `clientspecified` to allow the client to specify which address to bind to.
  - Type: raw
  - Required: no
- `ssh_gssapi_delegation`
  - Default: `False`
  - Description: Set to `true` to enable GSSAPI credential forwarding.
  - Type: bool
  - Required: no
- `ssh_gssapi_support`
  - Default: `False`
  - Description: Set to `true` to enable GSSAPI authentication (both client and server).
  - Type: bool
  - Required: no
- `ssh_hardening_enabled`
  - Default: `True`
  - Description: Whether to run the hardening
  - Type: bool
  - Required: no
- `ssh_host_certificates`
  - Default: `[]`
  - Description: Host certificates to look for when starting sshd
  - Type: list of ''
  - Required: no
- `ssh_host_key_algorithms`
  - Default: `[]`
  - Description: Host key algorithms that the server offers. If empty the default list will be used. Otherwise overrides the setting with specified list of algorithms. Check `man sshd_config`, `ssh -Q HostKeyAlgorithms` or other sources for supported algorithms - make sure you check the correct version
  - Type: list of ''
  - Required: no
- `ssh_host_key_files`
  - Default: ``
  - Description: Host keys for sshd. If empty ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key'] will be used, as far as supported by the installed sshd version.
  - Type: list of ''
  - Required: no
- `ssh_host_rsa_key_size`
  - Default: `4096`
  - Description: Specifies the number of bits in the private host RSA key to create.
  - Type: int
  - Required: no
- `ssh_kerberos_support`
  - Default: `True`
  - Description: Set to `true` if SSH has Kerberos support.
  - Type: bool
  - Required: no
- `ssh_kex`
  - Default: ``
  - Description: Change this list to overwrite kexs. Defaults found in `defaults/main.yml`
  - Type: list of ''
  - Required: no
- `ssh_listen_to`
  - Default: `['0.0.0.0']`
  - Description: one or more ip addresses, to which ssh-server should listen to. Default is all IPv4 addresses, but should be configured to specific addresses for security reasons
  - Type: list of ''
  - Required: no
- `ssh_login_grace_time`
  - Default: `30s`
  - Description: specifies the time allowed for successful authentication to the SSH server.
  - Type: str
  - Required: no
- `ssh_macs`
  - Default: ``
  - Description: Change this list to overwrite macs. Defaults found in `defaults/main.yml`
  - Type: list of ''
  - Required: no
- `ssh_max_auth_retries`
  - Default: `2`
  - Description: Specifies the maximum number of authentication attempts permitted per connection.
  - Type: int
  - Required: no
- `ssh_max_sessions`
  - Default: `10`
  - Description: Specifies the maximum number of open sessions permitted from a given connection.
  - Type: int
  - Required: no
- `ssh_max_startups`
  - Default: `10:30:60`
  - Description: Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon.
  - Type: str
  - Required: no
- `ssh_pam_support`
  - Default: `True`
  - Description: Set to `true` if SSH has PAM support.
  - Type: bool
  - Required: no
- `ssh_permit_root_login`
  - Default: `no`
  - Description: Disable root-login. Set to `'without-password'` or `'yes'` to enable root-login - The quotes are required!
  - Type: str
  - Required: no
- `ssh_permit_tunnel`
  - Default: `no`
  - Description: Specifies whether tun(4) device forwarding is allowed. The argument must be "yes", point-to-point (layer 3), ethernet (layer 2), or "no". Specifying yes permits both point-to-point and ethernet. - The quotes are required!
  - Type: str
  - Required: no
  - Choices:
    - no
    - yes
    - point-to-point
    - ethernet
- `ssh_print_debian_banner`
  - Default: `False`
  - Description: Set to `true` to print debian specific banner.
  - Type: bool
  - Required: no
- `ssh_print_last_log`
  - Default: `False`
  - Description: Set to `false` to disable display of last login information.
  - Type: bool
  - Required: no
- `ssh_print_motd`
  - Default: `False`
  - Description: Set to `false` to disable printing of the MOTD.
  - Type: bool
  - Required: no
- `ssh_print_pam_motd`
  - Default: `False`
  - Description: Set to `false` to disable printing of the MOTD via pam (Debian and Ubuntu).
  - Type: bool
  - Required: no
- `ssh_ps59`
  - Default: `sandbox`
  - Description: Specifies whether sshd separates privileges by creating an unprivileged child process to deal with incoming network traffic.
  - Type: str
  - Required: no
- `ssh_remote_hosts`
  - Default: `[]`
  - Description: one or more hosts and their custom options for the ssh-client. Default is empty. See examples in `defaults/main.yml`
  - Type: list of ''
  - Required: no
- `ssh_server_accept_env_vars`
  - Default: ``
  - Description: Specifies what environment variables sent by the client will be copied into the session's environment, multiple environment variables may be separated by whitespace.
  - Type: str
  - Required: no
- `ssh_server_config_file`
  - Default: `/etc/ssh/sshd_config`
  - Description: path of the ssh server configuration file, e.g. `/etc/ssh/sshd_config.d/custom.conf`.
  - Type: str
  - Required: no
- `ssh_server_enabled`
  - Default: `True`
  - Description: Set to `false` to disable the opensshd server.
  - Type: bool
  - Required: no
- `ssh_server_hardening`
  - Default: `True`
  - Description: Set to `false` to stop harden the server.
  - Type: bool
  - Required: no
- `ssh_server_match_address`
  - Default: ``
  - Description: Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file.
  - Type: str
  - Required: no
- `ssh_server_match_group`
  - Default: ``
  - Description: Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file.
  - Type: str
  - Required: no
- `ssh_server_match_local_port`
  - Default: ``
  - Description: Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file.
  - Type: str
  - Required: no
- `ssh_server_match_user`
  - Default: ``
  - Description: Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file.
  - Type: str
  - Required: no
- `ssh_server_password_login`
  - Default: `False`
  - Description: Set to `true` to allow password-based authentication to the ssh server. You probably also need to change `sshd_authenticationmethods` to include `password` if you set `ssh_server_password_login`: `true`.
  - Type: bool
  - Required: no
- `ssh_server_permit_environment_vars`
  - Default: `no`
  - Description: `yes` to specify that ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd. With openssh version 7.8 it is possible to specify a whitelist of environment variable names in addition to global 'yes' or 'no' settings.
  - Type: str
  - Required: no
- `ssh_server_ports`
  - Default: `['22']`
  - Description: ports on which ssh-server should listen.
  - Type: list of ''
  - Required: no
- `ssh_server_revoked_keys`
  - Default: `[]`
  - Description: a list of revoked public keys that the ssh server will always reject, useful to revoke known weak or compromised keys.
  - Type: list of ''
  - Required: no
- `ssh_server_service_enabled`
  - Default: `True`
  - Description: Set to `false` to disable starting sshd at boot.
  - Type: bool
  - Required: no
- `ssh_trusted_user_ca_keys`
  - Default: `[]`
  - Description: set the trusted certificate authorities public keys used to sign user certificates. Only used if `ssh_trusted_user_ca_keys_file` is set.
  - Type: list of ''
  - Required: no
- `ssh_trusted_user_ca_keys_file`
  - Default: ``
  - Description: specifies the file containing trusted certificate authorities public keys used to sign user certificates.
  - Type: str
  - Required: no
- `ssh_use_dns`
  - Default: `False`
  - Description: Specifies whether sshd should look up the remote host name, and to check that the resolved host name for the remote IP address maps back to the very same IP address.
  - Type: bool
  - Required: no
- `ssh_use_pam`
  - Default: `True`
  - Description: Set to `false` to disable pam authentication.
  - Type: bool
  - Required: no
- `ssh_x11_forwarding`
  - Default: `False`
  - Description: Set to `false` to disable X11 Forwarding. Set to `true` to allow X11 Forwarding.
  - Type: bool
  - Required: no
- `sshd_authenticationmethods`
  - Default: `publickey`
  - Description: Specifies the authentication methods that must be successfully completed for a user to be granted access. Make sure to set all required variables for your selected authentication method. Defaults found in `defaults/main.yml`
  - Type: str
  - Required: no
- `sshd_custom_options`
  - Default: `[]`
  - Description: Custom lines for SSH daemon configuration.
  - Type: list of ''
  - Required: no
- `sshd_log_level`
  - Default: `VERBOSE`
  - Description: the verbosity level that is used when logging messages from sshd.
  - Type: str
  - Required: no
- `sshd_moduli_file`
  - Default: `/etc/ssh/moduli`
  - Description: path to the SSH moduli file.
  - Type: str
  - Required: no
- `sshd_moduli_minimum`
  - Default: `2048`
  - Description: remove Diffie-Hellman parameters smaller than the defined size to mitigate logjam.
  - Type: int
  - Required: no
- `sshd_strict_modes`
  - Default: `True`
  - Description: Check file modes and ownership of the user's files and home directory before accepting login.
  - Type: bool
  - Required: no
- `sshd_syslog_facility`
  - Default: `AUTH`
  - Description: The facility code that is used when logging messages from sshd.
  - Type: str
  - Required: no

## Dependencies

None.

## Example Playbook

```
- hosts: all
  become: true
  roles:
    - name: devsec.hardening.ssh_hardening
```

---

## File: roles/os_hardening/README.md

# devsec.os_hardening

[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/os_hardening.yml)
[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/os_hardening_vm.yml)

## Description

This role provides numerous security-related configurations, providing all-round base protection. It is intended to be compliant with the [DevSec Linux Baseline](https://github.com/dev-sec/linux-baseline).

It configures:

- Removes unused yum repositories and enables GPG key-checking
- Removes packages with known issues
- Configures pam for strong password checks
- Installs and configures auditd
- Disables core dumps via soft limits
- sets a restrictive umask
- Configures execute permissions of files in system paths
- Hardens access to shadow and passwd files
- Disables unused filesystems
- Disables rhosts
- Configures secure ttys
- Configures kernel parameters via sysctl
- Enables selinux on EL-based systems
- Removes SUIDs and GUIDs
- Configures login and passwords of system accounts

It will not:

- Update system packages
- Install security patches

We remove the following packages:

- xinetd ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.1)
- inetd ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.1)
- tftp-server ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.5)
- ypserv ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.4)
- telnet-server ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.2)
- rsh-server ([NSA](https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm), Chapter 3.2.3)
- prelink ([open-scap](https://static.open-scap.org/ssg-guides/ssg-sl7-guide-ospp-rhel7-server.html#xccdf_org.ssgproject.content_rule_disable_prelink))

We disable the following filesystems, because they're most likely not used:

- "cramfs"
- "freevxfs"
- "jffs2"
- "hfs"
- "hfsplus"
- "squashfs"
- "udf"
- "vfat" # only if uefi is not in use

To prevent some of the filesystems from being disabled, add them to the `os_filesystem_whitelist` variable.

## Known Limitations

### Docker support

If you're using Docker / Kubernetes+Docker you'll need to override the ipv4 ip forward sysctl setting.

```yaml
- hosts: localhost
  roles:
    - devsec.hardening.os_hardening
  vars:
    sysctl_overwrite:
      # Enable IPv4 traffic forwarding.
      net.ipv4.ip_forward: 1
```

### hidepid on RHEL/CentOS 7

When having `polkit-0.112-18.el7` (and later) installed and `/proc` mounted with `hidepid=2`, every time someone uses `systemctl` the following error is displayed, but systemctl runs successfully.

```
Error registering authentication agent: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: Cannot determine user of subject (polkit-error-quark, 0)
```

We decided to set `hidepid=0` to remove the error message, if you want to use the other proposed workaround, you have to setup the user yourself and set our option to `hidepid_option: 2` via Ansible vars.

For further details see [RedHat: "GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: Cannot determine user of subject" seen when executing systemctl command](https://access.redhat.com/solutions/5005111) or [#364: hidepid=2 gives error when running systemctl on EL7](https://github.com/dev-sec/ansible-collection-hardening/issues/364)

### sysctl - vm.mmap_rnd_bits

We are setting this sysctl to a default of `32`, some systems only support smaller values and this will generate an error. Unfortunately we cannot determine the correct applicable maximum. If you encounter this error you have to override this sysctl in your playbook.

```yaml
- hosts: localhost
  roles:
    - devsec.hardening.os_hardening
  vars:
    sysctl_overwrite:
      vm.mmap_rnd_bits: 16
```

### password expiry and SSH key based logins

With default PAM configuration setting a password expiry for users will also block SSH key logins after the password has expired.
We have added a flag for PAM to ignore the expiry if SSH keys or other login mechanisms are used.
If you choose to use your own PAM configuration please adjust it accordingly to contain `no_pass_expiry` in the `account` stage for the `pam_unix.so` module.

A valid example would look like this:

```text
account     required      pam_unix.so no_pass_expiry
```

## Testing with inspec

If you're using inspec to test your machines after applying this role, please make sure to add the connecting user to the `os_ignore_users`-variable.
Otherwise inspec will fail. For more information, see [issue #124](https://github.com/dev-sec/ansible-os-hardening/issues/124).

We know that this is the case on Raspberry Pi.

## Changing sysctl variables

If you want to override sysctl-variables, you can use the `sysctl_overwrite` variable (in older versions you had to override the whole `sysctl_dict`).
So for example if you want to change the IPv4 traffic forwarding variable to `1`, do it like this:

```yaml
- hosts: localhost
  roles:
    - devsec.hardening.os_hardening
  vars:
    sysctl_overwrite:
      # Enable IPv4 traffic forwarding.
      net.ipv4.ip_forward: 1
```

Alternatively you can change Ansible's [hash-behaviour](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-hash-behaviour) to `merge`, then you only have to overwrite the single hash you need to. But please be aware that changing the hash-behaviour changes it for all your playbooks and is not recommended by Ansible.

## Improving Kernel Audit logging

By default, any process that starts before the `auditd` daemon will have an AUID of `4294967295`. To improve this and provide more accurate logging, it's recommended to add the kernel boot parameter `audit=1` to you configuration. Without doing this, you will find that your `auditd` logs fail to properly audit all processes.

For more information, please see this [upstream documentation](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html) and your system's boot loader documentation for how to configure additional kernel parameters.

## PAM configuration

We use specific PAM configuration for every linux distribution. This is a very diverse area, since every vendor seems to push their own system for managing PAM. We used following guides and sources for our configuration.

- on Debian/Ubuntu we use [pam-config-framework](https://wiki.ubuntu.com/PAMConfigFrameworkSpec)
- RHEL8 and compatible use information from [authselect](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel), but our setup disables the configuration from authselect
- RHEL 6/7 and compatible use [authconfig](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/authconfig-install), but our setup disables the configuration from authconfig
- for RHEL 6/7 we also use information from [Desktop Security](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-hardening_your_system_with_tools_and_services#sec-Desktop_Security)

## Acknowledgements

This role is mostly based on guides by:

- [Arch Linux wiki, Sysctl hardening](https://wiki.archlinux.org/index.php/Sysctl)
- [NSA: Guide to the Secure Configuration of Red Hat Enterprise Linux 5](http://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf)
- [Ubuntu Security/Features](https://wiki.ubuntu.com/Security/Features)
- [Deutsche Telekom, Group IT Security, Security Requirements (German)](https://www.telekom.com/psa)



## Supported Operating Systems
- EL
  - 8, 9, 10
- Ubuntu
  - jammy, noble, resolute
- Debian
  - trixie, bookworm, bullseye
- Amazon
- Fedora
- ArchLinux
- SmartOS
- opensuse

## Role Variables

- `os_apt_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring apt.
  - Type: bool
  - Required: no
- `os_auditd_action_mail_acct`
  - Default: `root`
  - Description: If `space_left_action` or `admin_space_left_action` are set to `email`, uses the address or alias to send the email using `/usr/lib/sendmail`. of events created on one system but reported/analyzed on another system.
  - Type: str
  - Required: no
- `os_auditd_admin_space_left`
  - Default: `50`
  - Description: This is a numeric value in megabytes that tells the audit daemon when to perform a configurable action because the system is running low on disk space.
  - Type: int
  - Required: no
- `os_auditd_admin_space_left_action`
  - Default: `SUSPEND`
  - Description: This parameter tells the system what action to take when the system has detected that it is low on disk space. Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt.
  - Type: str
  - Required: no
- `os_auditd_disk_error_action`
  - Default: `SUSPEND`
  - Description: This parameter tells the system what action to take whenever there is an error detected when writing audit events to disk or rotating logs. Valid values are ignore, syslog, exec, suspend, single, and halt.
  - Type: str
  - Required: no
- `os_auditd_disk_full_action`
  - Default: `SUSPEND`
  - Description: This parameter tells the system what action to take when the system has detected that the partition to which log files are written has become full. Valid values are ignore, syslog, rotate, exec, suspend, single, and halt.
  - Type: str
  - Required: no
- `os_auditd_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring auditd.
  - Type: bool
  - Required: no
- `os_auditd_flush`
  - Default: `INCREMENTAL`
  - Description: Valid values are none, incremental, incremental_async, data, and sync.
  - Type: str
  - Required: no
- `os_auditd_log_format`
  - Default: `RAW`
  - Description: Describes how the information should be stored on disk. There are 2 options - raw and enriched.
  - Type: str
  - Required: no
- `os_auditd_log_group`
  - Default: `root`
  - Description: specifies the group that is applied to the log file's permissions. The group name can be either numeric or spelled out.
  - Type: str
  - Required: no
- `os_auditd_max_log_file`
  - Default: `6`
  - Description: This keyword specifies the maximum file size in megabytes. When this limit is reached, it will trigger a configurable action. The value given must be numeric.
  - Type: int
  - Required: no
- `os_auditd_max_log_file_action`
  - Default: `keep_logs`
  - Description: Defines the behaviour of auditd when its log file is filled up. Possible other values are described in the auditd.conf man page. The most common alternative to the default may be `rotate`.
  - Type: str
  - Required: no
- `os_auditd_name_format`
  - Default: `NONE`
  - Description: This keyword specifies how computer node names are inserted into the audit event stream.
  - Type: str
  - Required: no
  - Choices:
    - NONE
    - hostname
    - fqd
    - numeric
- `os_auditd_num_logs`
  - Default: `5`
  - Description: This keyword specifies the number of log files to keep if `rotate` is given as the max_log_file_action. The value given must be numeric.
  - Type: int
  - Required: no
- `os_auditd_space_left`
  - Default: `75`
  - Description: If the free space in the filesystem containing log_file drops below this value, the audit daemon takes the action specified by space_left_action.
  - Type: int
  - Required: no
- `os_auditd_space_left_action`
  - Default: `SYSLOG`
  - Description: This parameter tells the system what action to take when the system has detected that it is starting to get low on disk space. Valid values are ignore, syslog, rotate, email, exec, suspend, single, and halt.
  - Type: str
  - Required: no
- `os_auth_allow_homeless`
  - Default: `False`
  - Description: true if to allow users without home to login.
  - Type: bool
  - Required: no
- `os_auth_gid_max`
  - Default: `60000`
  - Description: maximum number for automatic gid selection in groupadd.
  - Type: int
  - Required: no
- `os_auth_gid_min`
  - Default: `1000`
  - Description: minimum number for automatic gid selection in groupadd.
  - Type: int
  - Required: no
- `os_auth_lockout_time`
  - Default: `600`
  - Description: time in seconds that needs to pass, if the account was locked due to too many failed authentication attempts.
  - Type: int
  - Required: no
- `os_auth_pam_oddjob_mkhomedir`
  - Default: `False`
  - Description: Enables automatic homedir e.g. in FreeIPA environments
  - Type: bool
  - Required: no
- `os_auth_pam_passwdqc_enable`
  - Default: `True`
  - Description: true if you want to use strong password checking in PAM using passwdqc.
  - Type: bool
  - Required: no
- `os_auth_pam_passwdqc_options`
  - Default: `min=disabled,disabled,16,12,8`
  - Description: set to any option line (as a string) that you want to pass to passwdqc.
  - Type: str
  - Required: no
- `os_auth_pam_pwquality_options`
  - Default: `try_first_pass retry=3 authtok_type=`
  - Description: Options to pass to the PAM module pwquality
  - Type: str
  - Required: no
- `os_auth_pw_max_age`
  - Default: `60`
  - Description: maximum password age (set to `99999` to effectively disable it).
  - Type: int
  - Required: no
- `os_auth_pw_min_age`
  - Default: `7`
  - Description: minimum password age (before allowing any other password change).
  - Type: int
  - Required: no
- `os_auth_pw_remember`
  - Default: `5`
  - Description: how many used passwords are record.
  - Type: int
  - Required: no
- `os_auth_pw_warn_age`
  - Default: `7`
  - Description: number of days of warning before password expires.
  - Type: int
  - Required: no
- `os_auth_retries`
  - Default: `5`
  - Description: the maximum number of authentication attempts, before the account is locked for some time.
  - Type: int
  - Required: no
- `os_auth_root_ttys`
  - Default: `['console', 'tty1', 'tty2', 'tty3', 'tty4', 'tty5', 'tty6']`
  - Description: A list of TTYs, from which root can log in, see `man securetty` for reference
  - Type: list of ''
  - Required: no
- `os_auth_sub_gid_count`
  - Default: `65536`
  - Description: If /etc/subuid exists, the commands useradd and newusers (unless the user already have subordinate group IDs) allocate SUB_GID_COUNT unused group IDs from the range SUB_GID_MIN to SUB_GID_MAX for each new user. See also `os_auth_sub_gid_min` and `os_auth_sub_gid_max`.
  - Type: int
  - Required: no
- `os_auth_sub_gid_max`
  - Default: `600100000`
  - Description: maximum number for automatic subordinate gid selection in useradd and newusers.
  - Type: int
  - Required: no
- `os_auth_sub_gid_min`
  - Default: `100000`
  - Description: minimum number for automatic subordinate gid selection in useradd and newusers.
  - Type: int
  - Required: no
- `os_auth_sub_uid_count`
  - Default: `65536`
  - Description: If /etc/subuid exists, the commands useradd and newusers (unless the user already have subordinate user IDs) allocate SUB_UID_COUNT unused user IDs from the range SUB_UID_MIN to SUB_UID_MAX for each new user. See also `os_auth_sub_uid_min` and `os_auth_sub_uid_max`.
  - Type: int
  - Required: no
- `os_auth_sub_uid_max`
  - Default: `600100000`
  - Description: maximum number for automatic subordinate uid selection in useradd and newusers.
  - Type: int
  - Required: no
- `os_auth_sub_uid_min`
  - Default: `100000`
  - Description: minimum number for automatic subordinate uid selection in useradd and newusers.
  - Type: int
  - Required: no
- `os_auth_timeout`
  - Default: `60`
  - Description: authentication timeout in seconds, so login will exit if this time passes.
  - Type: int
  - Required: no
- `os_auth_uid_max`
  - Default: `60000`
  - Description: maximum number for automatic uid selection in useradd.
  - Type: int
  - Required: no
- `os_auth_uid_min`
  - Default: `1000`
  - Description: minimum number for automatic uid selection in useradd.
  - Type: int
  - Required: no
- `os_chfn_restrict`
  - Default: `''`
  - Description: Indicate which fields are changeable by chfn.
  - Type: str
  - Required: no
- `os_chmod_home_folders`
  - Default: `True`
  - Description: Set to `false` to disable "chmod 700" of home folders for regular users
  - Type: bool
  - Required: no
- `os_chmod_rootuser_home_folder`
  - Default: `True`
  - Description: Set to `false` to disable "chmod 700" of root's home folder
  - Type: bool
  - Required: no
- `os_cron_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring cron.
  - Type: bool
  - Required: no
- `os_ctrlaltdel_disabled`
  - Default: `False`
  - Description: Set to true to disable ctrl-alt-delete key combination.
  - Type: bool
  - Required: no
- `os_env_extra_user_paths`
  - Default: `[]`
  - Description: Specify additional paths that should be checked for binaries where access will be minimized
  - Type: list of ''
  - Required: no
- `os_env_user_paths`
  - Default: `['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin']`
  - Description: Specify paths that should be checked for binaries where access will be minimized
  - Type: list of ''
  - Required: no
- `os_filesystem_whitelist`
  - Default: `[]`
  - Description: A list of filesystems that should not be disabled
  - Type: list of ''
  - Required: no
- `os_hardening_enabled`
  - Default: `True`
  - Description: Whether to run the hardening
  - Type: bool
  - Required: no
- `os_ignore_home_folder_users`
  - Default: `[]`
  - Description: Specify user accounts, whose home folders shouldn't be chmodded to 700 when "os_chmod_home_folders" is enabled.
  - Type: list of ''
  - Required: no
- `os_ignore_users`
  - Default: `['vagrant', 'kitchen']`
  - Description: Specify system accounts whose login should not be disabled and password not changed
  - Type: list of ''
  - Required: no
- `os_limits_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring limits.
  - Type: bool
  - Required: no
- `os_login_defs_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring login_defs for newly created users.
  - Type: bool
  - Required: no
- `os_minimize_access_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring minimize_access.
  - Type: bool
  - Required: no
- `os_mnt_boot_dir_mode`
  - Default: `0700`
  - Description: Set default perimissions for /boot
  - Type: str
  - Required: no
- `os_mnt_boot_dump`
  - Default: `ext3 + ext4 = 1 / other = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_boot_enabled`
  - Default: `False`
  - Description: Set to true to configure /boot mountpoint
  - Type: bool
  - Required: no
- `os_mnt_boot_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /boot. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_boot_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /boot
  - Type: str
  - Required: no
- `os_mnt_boot_passno`
  - Default: `ext3 + ext4 = 2 / other = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_boot_src`
  - Default: `''`
  - Description: Set mount source for /boot
  - Type: str
  - Required: no
- `os_mnt_dev_dir_mode`
  - Default: `0755`
  - Description: Set default perimissions for /dev
  - Type: str
  - Required: no
- `os_mnt_dev_dump`
  - Default: `0`
  - Description: Configure dump for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_dev_enabled`
  - Default: `True`
  - Description: Set to false to ignore /dev mountpoint
  - Type: bool
  - Required: no
- `os_mnt_dev_filesystem`
  - Default: `devtmpfs`
  - Description: Configure file system for fstab entry /dev
  - Type: str
  - Required: no
- `os_mnt_dev_options`
  - Default: `rw,nosuid,noexec`
  - Description: Configure mount options for /dev
  - Type: str
  - Required: no
- `os_mnt_dev_passno`
  - Default: `0`
  - Description: Configure passno for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_dev_shm_dir_mode`
  - Default: `1777`
  - Description: Set default perimissions for /dev/shm
  - Type: str
  - Required: no
- `os_mnt_dev_shm_dump`
  - Default: `0`
  - Description: Configure dump for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_dev_shm_enabled`
  - Default: `True`
  - Description: Set to false to ignore /dev/shm mountpoint
  - Type: bool
  - Required: no
- `os_mnt_dev_shm_filesystem`
  - Default: `tmpfs`
  - Description: Configure file system for fstab entry /dev/shm
  - Type: str
  - Required: no
- `os_mnt_dev_shm_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /dev/shm
  - Type: str
  - Required: no
- `os_mnt_dev_shm_passno`
  - Default: `0`
  - Description: Configure passno for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_dev_shm_src`
  - Default: `tmpfs`
  - Description: Set mount source for /dev/shm
  - Type: str
  - Required: no
- `os_mnt_dev_src`
  - Default: `devtmpfs`
  - Description: Set mount source for /dev
  - Type: str
  - Required: no
- `os_mnt_home_dir_mode`
  - Default: `0755`
  - Description: Set default perimissions for /home
  - Type: str
  - Required: no
- `os_mnt_home_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_home_enabled`
  - Default: `False`
  - Description: Set to true to configure /home mountpoint
  - Type: bool
  - Required: no
- `os_mnt_home_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /home. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_home_options`
  - Default: `rw,nosuid,nodev`
  - Description: Configure mount options for /home
  - Type: str
  - Required: no
- `os_mnt_home_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_home_src`
  - Default: `''`
  - Description: Set mount source for /home. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_mnt_run_dir_mode`
  - Default: `0755`
  - Description: Set default perimissions for /run
  - Type: str
  - Required: no
- `os_mnt_run_dump`
  - Default: `0`
  - Description: Configure dump for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_run_enabled`
  - Default: `True`
  - Description: Set to false to ignore /run mountpoint
  - Type: bool
  - Required: no
- `os_mnt_run_filesystem`
  - Default: `tmpfs`
  - Description: Configure file system for fstab entry /run
  - Type: str
  - Required: no
- `os_mnt_run_options`
  - Default: `rw,nosuid,nodev`
  - Description: Configure mount options for /run
  - Type: str
  - Required: no
- `os_mnt_run_passno`
  - Default: `0`
  - Description: Configure passno for fstab entry /var/tmp.
  - Type: str
  - Required: no
- `os_mnt_run_src`
  - Default: `tmpfs`
  - Description: Set mount source for /run
  - Type: str
  - Required: no
- `os_mnt_tmp_dir_mode`
  - Default: `1777`
  - Description: Set default perimissions for /tmp
  - Type: str
  - Required: no
- `os_mnt_tmp_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_tmp_enabled`
  - Default: `False`
  - Description: Set to true to configure /tmp mountpoint
  - Type: bool
  - Required: no
- `os_mnt_tmp_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /tmp. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_tmp_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /tmp
  - Type: str
  - Required: no
- `os_mnt_tmp_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_tmp_src`
  - Default: `''`
  - Description: Set mount source for /tmp. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_mnt_var_dir_mode`
  - Default: `0755`
  - Description: Set default perimissions for /var
  - Type: str
  - Required: no
- `os_mnt_var_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_enabled`
  - Default: `False`
  - Description: Set to true to configure /var mountpoint
  - Type: bool
  - Required: no
- `os_mnt_var_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /var. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_dir_mode`
  - Default: `0640`
  - Description: Set default perimissions for /var/log/audit
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_enabled`
  - Default: `False`
  - Description: Set to true to configure /var/log/audit mountpoint
  - Type: bool
  - Required: no
- `os_mnt_var_log_audit_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /var/log/audit. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /var/log/audit
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_log_audit_src`
  - Default: `''`
  - Description: Set mount source for /var/log/audit. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_mnt_var_log_dir_mode`
  - Default: `0755`
  - Description: Set default perimissions for /var/log
  - Type: str
  - Required: no
- `os_mnt_var_log_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_log_enabled`
  - Default: `False`
  - Description: Set to true to configure /var/log mountpoint
  - Type: bool
  - Required: no
- `os_mnt_var_log_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /var/log. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_var_log_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /var/log
  - Type: str
  - Required: no
- `os_mnt_var_log_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_log_src`
  - Default: `''`
  - Description: Set mount source for /var/log. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_mnt_var_options`
  - Default: `rw,nosuid,nodev`
  - Description: Configure mount options for /var
  - Type: str
  - Required: no
- `os_mnt_var_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_src`
  - Default: `''`
  - Description: Set mount source for /var. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_mnt_var_tmp_dir_mode`
  - Default: `1777`
  - Description: Set default perimissions for /var/tmp
  - Type: str
  - Required: no
- `os_mnt_var_tmp_dump`
  - Default: `ext3/4 = 1, others = 0`
  - Description: Configure dump for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_tmp_enabled`
  - Default: `False`
  - Description: Set to true to configure /var/tmp mountpoint
  - Type: bool
  - Required: no
- `os_mnt_var_tmp_filesystem`
  - Default: `''`
  - Description: Configure file system for fstab entry /var/tmp. If empty, the current file system type will be used.
  - Type: str
  - Required: no
- `os_mnt_var_tmp_options`
  - Default: `rw,nosuid,nodev,noexec`
  - Description: Configure mount options for /var/tmp
  - Type: str
  - Required: no
- `os_mnt_var_tmp_passno`
  - Default: `ext3/4 = 2, others = 0`
  - Description: Configure passno for fstab entry /var/tmp. If empty, the default depends on fstype.
  - Type: str
  - Required: no
- `os_mnt_var_tmp_src`
  - Default: `''`
  - Description: Set mount source for /var/tmp. If empty, the current file system source device will be used.
  - Type: str
  - Required: no
- `os_modprobe_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring modprobe.
  - Type: bool
  - Required: no
- `os_netrc_enabled`
  - Default: `True`
  - Description: Configure filesystem for existence of .netrc file in homedir
  - Type: bool
  - Required: no
- `os_netrc_whitelist_user`
  - Default: `[]`
  - Description: Add list of user to allow creation of .netrc in users homedir
  - Type: list of ''
  - Required: no
- `os_pam_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring pam.
  - Type: bool
  - Required: no
- `os_profile_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring profile.
  - Type: bool
  - Required: no
- `os_remove_additional_root_users`
  - Default: `False`
  - Description: When enabled and there are multiple users with UID=0, only "root" will be kept. Others will be deleted.
  - Type: bool
  - Required: no
- `os_rhosts_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring rhosts.
  - Type: bool
  - Required: no
- `os_rootuser_pw_ageing`
  - Default: `False`
  - Description: Set to true to enforce password age settings for root user(s)
  - Type: bool
  - Required: no
- `os_securetty_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring securetty.
  - Type: bool
  - Required: no
- `os_security_auto_logout`
  - Default: `0`
  - Description: Set timeout in seconds for logout users automatically after time. Setting this to `0` disables the timeout.
  - Type: int
  - Required: no
- `os_security_init_prompt`
  - Default: `True`
  - Description: The PROMPT option provides console users the ability to interactively boot the system and select which services to start on boot.
  - Type: bool
  - Required: no
- `os_security_init_single`
  - Default: `False`
  - Description: Single-user mode is intended as a system recovery method, providing a single user root access to the system by providing a boot option at startup. By default, no authentication is performed if single-user mode is selected. To require entry of the root password even if the system is started in single-user mode, set this to false
  - Type: bool
  - Required: no
- `os_security_kernel_enable_core_dump`
  - Default: `False`
  - Description: kernel is crashing or otherwise misbehaving and a kernel core dump is created.
  - Type: bool
  - Required: no
- `os_security_packages_clean`
  - Default: `True`
  - Description: removes packages with known issues. See section packages.
  - Type: bool
  - Required: no
- `os_security_packages_list`
  - Default: `['xinetd', 'inetd', 'ypserv', 'telnet-server', 'rsh-server', 'prelink']`
  - Description: List of deprecated or insecure packages to remove
  - Type: list of ''
  - Required: no
- `os_security_suid_sgid_blacklist`
  - Default: `[]`
  - Description: a list of paths which should have their SUID/SGID bits removed.
  - Type: list of ''
  - Required: no
- `os_security_suid_sgid_enforce`
  - Default: `True`
  - Description: true if you want to reduce SUID/SGID bits. There is already a list of items which are searched for configured, but you can also add your own.
  - Type: bool
  - Required: no
- `os_security_suid_sgid_remove_from_unknown`
  - Default: `False`
  - Description: true if you want to remove SUID/SGID bits from any file, that is not explicitly configured in a `blacklist`. This will make every Ansible-run search through the mounted filesystems looking for SUID/SGID bits that are not configured in the default and user blacklist. If it finds an SUID/SGID bit, it will be removed, unless this file is in your `whitelist`.
  - Type: bool
  - Required: no
- `os_security_suid_sgid_whitelist`
  - Default: `[]`
  - Description: a list of paths which should not have their SUID/SGID bits altered.
  - Type: list of ''
  - Required: no
- `os_security_users_allow`
  - Default: `[]`
  - Description: list of things, that a user is allowed to do. May contain `change_user`.
  - Type: list of ''
  - Required: no
- `os_selinux_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring selinux.
  - Type: bool
  - Required: no
- `os_selinux_policy`
  - Default: `targeted`
  - Description: Set the SELinux polixy.
  - Type: str
  - Required: no
- `os_selinux_state`
  - Default: `enforcing`
  - Description: Set the SELinux state, can be either disabled, permissive, or enforcing.
  - Type: str
  - Required: no
- `os_sha_crypt_max_rounds`
  - Default: `640000`
  - Description: Define the number of maximum SHA rounds. With a lot of rounds brute forcing the password is more difficult. But note also that it more CPU resources will be needed to authenticate users. The values must be inside the 1000-999999999 range.
  - Type: int
  - Required: no
- `os_sha_crypt_min_rounds`
  - Default: `640000`
  - Description: Define the number of minimum SHA rounds. With a lot of rounds brute forcing the password is more difficult. But note also that it more CPU resources will be needed to authenticate users. The values must be inside the 1000-999999999 range.
  - Type: int
  - Required: no
- `os_sysctl_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring sysctl.
  - Type: bool
  - Required: no
- `os_unused_filesystems`
  - Default: `['cramfs', 'freevxfs', 'jffs2', 'hfs', 'hfsplus', 'squashfs', 'udf', 'vfat', 'dccp', 'rds', 'sctp', 'tipc']`
  - Description: Disable this list of unused filesystems
  - Type: list of ''
  - Required: no
- `os_user_accounts_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring user_accounts.
  - Type: bool
  - Required: no
- `os_user_pw_ageing`
  - Default: `True`
  - Description: Set to false to disable password age enforcement on existing users
  - Type: bool
  - Required: no
- `os_users_without_password_ageing`
  - Default: `[]`
  - Description: List of users, where password ageing should not be enforced even if "os_user_pw_ageing" is enabled
  - Type: list of ''
  - Required: no
- `os_yum_enabled`
  - Default: `True`
  - Description: Set to false to disable installing and configuring yum.
  - Type: bool
  - Required: no
- `os_yum_repo_file_whitelist`
  - Default: `[]`
  - Description: List of yum repository files under /etc/yum.repos.d/ which should not be altered.
  - Type: list of ''
  - Required: no
- `proc_mnt_options`
  - Default: `rw,nosuid,nodev,noexec,relatime`
  - Description: Mount proc with hardenized options. Note that the hidepid option is set separately in vars/.
  - Type: str
  - Required: no
- `sysctl_config`
  - Default: `{"fs.protected_hardlinks": 1, "fs.protected_symlinks": 1, "fs.protected_fifos": 1, "fs.protected_regular": 2, "fs.suid_dumpable": 0, "kernel.core_uses_pid": 1, "kernel.kptr_restrict": 2, "kernel.kexec_load_disabled": 1, "kernel.sysrq": 0, "kernel.randomize_va_space": 2, "kernel.yama.ptrace_scope": 2, "net.ipv4.ip_forward": 0, "net.ipv6.conf.all.forwarding": 0, "net.ipv4.conf.all.rp_filter": 1, "net.ipv4.conf.default.rp_filter": 1, "net.ipv4.icmp_echo_ignore_broadcasts": 1, "net.ipv4.icmp_ignore_bogus_error_responses": 1, "net.ipv4.icmp_ratelimit": 100, "net.ipv4.icmp_ratemask": 88089, "net.ipv4.tcp_timestamps": 0, "net.ipv4.conf.all.arp_ignore": 1, "net.ipv4.conf.all.arp_announce": 2, "net.ipv4.tcp_rfc1337": 1, "net.ipv4.tcp_syncookies": 1, "net.ipv4.conf.all.shared_media": 1, "net.ipv4.conf.default.shared_media": 1, "net.ipv4.conf.all.accept_source_route": 0, "net.ipv4.conf.default.accept_source_route": 0, "net.ipv6.conf.all.accept_source_route": 0, "net.ipv6.conf.default.accept_source_route": 0, "net.ipv4.conf.all.send_redirects": 0, "net.ipv4.conf.default.send_redirects": 0, "net.ipv4.conf.all.log_martians": 1, "net.ipv4.conf.default.log_martians": 1, "net.ipv4.conf.default.accept_redirects": 0, "net.ipv4.conf.all.accept_redirects": 0, "net.ipv4.conf.all.secure_redirects": 0, "net.ipv4.conf.default.secure_redirects": 0, "net.ipv6.conf.default.accept_redirects": 0, "net.ipv6.conf.all.accept_redirects": 0, "net.ipv6.conf.all.accept_ra": 0, "net.ipv6.conf.default.accept_ra": 0, "net.ipv6.conf.default.router_solicitations": 0, "net.ipv6.conf.all.router_solicitations": 0, "net.ipv6.conf.default.accept_ra_rtr_pref": 0, "net.ipv6.conf.default.accept_ra_pinfo": 0, "net.ipv6.conf.default.accept_ra_defrtr": 0, "net.ipv6.conf.default.autoconf": 0, "net.ipv6.conf.all.autoconf": 0, "net.ipv6.conf.default.dad_transmits": 0, "net.ipv6.conf.default.max_addresses": 1, "vm.mmap_min_addr": 65536, "vm.mmap_rnd_bits": 32, "vm.mmap_rnd_compat_bits": 16}`
  - Description: various sysctl-settings
  - Type: dict
  - Required: no
- `sysctl_overwrite`
  - Default: `"{}"`
  - Description: To overwrite options in the `sysctl_config`-dict, overwrite them here.
  - Type: dict
  - Required: no
- `ufw_default_application_policy`
  - Default: `SKIP`
  - Description: The default application policy is skip, which means that the update --add-new command will do nothing
  - Type: str
  - Required: no
- `ufw_default_forward_policy`
  - Default: `DROP`
  - Description: set default forward policy of ufw to `DROP`.
  - Type: str
  - Required: no
- `ufw_default_input_policy`
  - Default: `DROP`
  - Description: set default input policy of ufw to `DROP`.
  - Type: str
  - Required: no
- `ufw_default_output_policy`
  - Default: `ACCEPT`
  - Description: set default output policy of ufw to `ACCEPT`.
  - Type: str
  - Required: no
- `ufw_enable_ipv6`
  - Default: `True`
  - Description: Set to `true` to apply rules to support IPv6 (no means only IPv6 on loopback accepted).
  - Type: bool
  - Required: no
- `ufw_ipt_modules`
  - Default: `nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns`
  - Description: Define which netfilter modules to load
  - Type: str
  - Required: no
- `ufw_ipt_sysctl`
  - Default: `''`
  - Description: by default it disables IPT_SYSCTL in /etc/default/ufw. If you want to overwrite /etc/sysctl.conf values using ufw - set it to your sysctl dictionary, for example `/etc/ufw/sysctl.conf`.
  - Type: str
  - Required: no
- `ufw_manage_builtins`
  - Default: `no`
  - Description: If this variable is set to 'yes', on stop and reload the built-in chains are flushed. If it is set to 'no', on stop and reload the ufw secondary chains are removed and the ufw primary chains are flushed
  - Type: str
  - Required: no
- `ufw_manage_defaults`
  - Default: `True`
  - Description: true means apply all settings with `ufw_` prefix.
  - Type: bool
  - Required: no

## Dependencies

None.

## Example Playbook

```
- hosts: all
  become: true
  roles:
    - name: devsec.hardening.os_hardening
```

---

## File: roles/nginx_hardening/README.md

# devsec.nginx_hardening

[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/nginx_hardening.yml)

## Description

This role provides secure nginx configuration. It is intended to be compliant with the [DevSec Nginx Baseline](https://github.com/dev-sec/nginx-baseline).

It works with the following nginx-roles, including, but not limited to:

- [nginxinc.nginx](https://galaxy.ansible.com/ui/standalone/roles/nginxinc/nginx/)
- [geerlinggux.nginx](https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/nginx/)
- [jdauphant.nginx](https://galaxy.ansible.com/ui/standalone/roles/jdauphant/nginx/)

**NOTE: This role does not work with nginx 1.0.15 or older! Please use the latest version from the official nginx repositories!**



## Supported Operating Systems
- EL
  - 8, 9, 10
- Ubuntu
  - jammy, noble, resolute
- Debian
  - trixie, bookworm, bullseye
- Amazon

## Role Variables

- `nginx_add_header`
  - Default: `['X-Frame-Options SAMEORIGIN', 'X-Content-Type-Options nosniff', 'X-XSS-Protection "1; mode=block"', 'Content-Security-Policy \\"script-src \'self\'; object-src \'self\'\\"']`
  - Description: Adds the specified field to a response header provided that the response code equals 200, 201, 204, 206, 301, 302, 303, 304, or 307. See [nginx_add_header](http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header)
  - Type: list of ''
  - Required: no
- `nginx_client_body_buffer_size`
  - Default: `1k`
  - Description: Sets buffer size for reading client request body. In case the request body is larger than the buffer, the whole body or only its part is written to a temporary file. See [nginx_client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size)
  - Type: str
  - Required: no
- `nginx_client_body_timeout`
  - Default: `10`
  - Description: Defines a timeout for reading client request body. See [nginx_client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout)
  - Type: int
  - Required: no
- `nginx_client_header_buffer_size`
  - Default: `1k`
  - Description: Sets buffer size for reading client request header. For most requests, a buffer of 1K bytes is enough. See [nginx_client_header_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client
  - Type: str
  - Required: no
- `nginx_client_header_timeout`
  - Default: `10`
  - Description: Defines a timeout for reading client request header. See [nginx_client_header_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout)
  - Type: int
  - Required: no
- `nginx_client_max_body_size`
  - Default: `1k`
  - Description: Sets the maximum allowed size of the client request body, specified in the "Content-Length" request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. See [nginx_client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size)
  - Type: str
  - Required: no
- `nginx_configuration_dir`
  - Default: `/etc/nginx`
  - Description: The main location for all nginx configuration files
  - Type: str
  - Required: no
- `nginx_configuration_hardening_dir`
  - Default: `/etc/nginx`
  - Description: The location for the nginx hardening configuration file (Could be different e.g. when used in jails)
  - Type: str
  - Required: no
- `nginx_dh_size`
  - Default: `2048`
  - Description: Specifies the length of DH parameters for EDH ciphers. See [nginx_dh_size](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam)
  - Type: int
  - Required: no
- `nginx_keepalive_timeout`
  - Default: `5 5`
  - Description: The first parameter sets a timeout during which a keep-alive client connection will stay open on the server side. The zero value disables keep-alive client connections. The optional second parameter sets a value in the "Keep-Alive timeout=time" response header field. See [nginx_keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout)
  - Type: str
  - Required: no
- `nginx_large_client_header_buffers`
  - Default: `2 1k`
  - Description: Sets the maximum number and size of buffers used for reading large client request header. See [nginx_large_client_header_buffers](http://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)
  - Type: str
  - Required: no
- `nginx_limit_conn`
  - Default: `default 5`
  - Description: Sets the shared memory zone and the maximum allowed number of connections for a given key value. See [nginx_limit_conn](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn)
  - Type: str
  - Required: no
- `nginx_limit_conn_zone`
  - Default: `$binary_remote_addr zone=default:10m`
  - Description: Sets parameters for a shared memory zone that will keep states for various keys. See [nginx_limit_conn_zone](http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone)
  - Type: str
  - Required: no
- `nginx_owner_group`
  - Default: `root`
  - Description: The owner group of the nginx configuration files
  - Type: str
  - Required: no
- `nginx_owner_user`
  - Default: `root`
  - Description: The owner user of the nginx configuration files
  - Type: str
  - Required: no
- `nginx_remove_default_site`
  - Default: `True`
  - Description: Disables the default site. Set to false to enable the default site in nginx.
  - Type: bool
  - Required: no
- `nginx_send_timeout`
  - Default: `10`
  - Description: Sets a timeout for transmitting a response to the client. See [nginx_send_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout)
  - Type: int
  - Required: no
- `nginx_server_tokens`
  - Default: `off`
  - Description: Disables emitting nginx version in error messages and in the "Server" response header field. Set to on to enable the nginx version in error messages and "Server" response header. See [nginx_server_tokens](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens)
  - Type: str
  - Required: no
- `nginx_ssl_ciphers`
  - Default: `ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256`
  - Description: Specifies the TLS ciphers which should be used. See [nginx_ssl_ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers)
  - Type: str
  - Required: no
- `nginx_ssl_prefer_server_ciphers`
  - Default: `on`
  - Description: Specifies that server ciphers should be preferred over client ciphers when using the TLS protocols. Set to false to disable it. See [nginx_ssl_prefer_server_ciphers](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers)
  - Type: str
  - Required: no
- `nginx_ssl_protocols`
  - Default: `TLSv1.2`
  - Description: Specifies the SSL protocol which should be used. See [nginx_ssl_protocols](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols)
  - Type: str
  - Required: no

## Dependencies

None.

## Example Playbook

```
- hosts: all
  become: true
  roles:
    - name: devsec.hardening.nginx_hardening
```

---

## File: roles/mysql_hardening/README.md

# devsec.mysql_hardening

[](https://github.com/dev-sec/ansible-collection-hardening/actions/workflows/mysql_hardening.yml)

## Description

This role provides security configurations for MySQL and its derivates. It is intended to set up production-ready MySQL instances that are configured with minimal surface for attackers. Furthermore it is intended to be compliant with the [DevSec MySQL Baseline](https://github.com/dev-sec/mysql-baseline).

It configures:

- Permissions for the various configuration files and folders
- Removes anonymous users, users without a password or authentication_string and test databases
- various hardening options inside MySQL

Changes of options `log_error` or `datadir` in `mysql_hardening_options` will not be checked for correct permissions. Please change/set `log_error` or `datadir` with the installation role of MySQL before running this role, or you can run this role twice.

Further information is available at [Deutsche Telekom (German)](http://www.telekom.com/static/-/155996/7/technische-sicherheitsanforderungen-si) and [Symantec](http://www.symantec.com/connect/articles/securing-mysql-step-step)

## Requirements

- An existing installation of MySQL or MariaDB.
- python-jmespath on the ansible host



## Supported Operating Systems
- EL
  - 8, 9, 10
- Ubuntu
  - jammy, noble
- Debian
  - trixie, bookworm, bullseye
- Amazon
- opensuse

## Role Variables

- `mysql_daemon_enabled`
  - Default: `True`
  - Description: Whether to enable the MySQL-service so it starts on boot
  - Type: bool
  - Required: no
- `mysql_hardening_chroot`
  - Default: ``
  - Description: [chroot](http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_chroot)
  - Type: str
  - Required: no
- `mysql_hardening_chroot.automatic-sp-privileges`
  - Default: `0`
  - Description: [automatic_sp_privileges](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_automatic_sp_privileges)
  - Type: int
  - Required: no
- `mysql_hardening_enabled`
  - Default: `True`
  - Description: Whether to run the hardening
  - Type: bool
  - Required: no
- `mysql_hardening_options.allow-suspicious-udfs`
  - Default: `0`
  - Description: [allow-suspicious-udfs](https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_allow-suspicious-udfs)
  - Type: int
  - Required: no
- `mysql_hardening_options.local-infile`
  - Default: `0`
  - Description: [local-infile](http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_local_infile)
  - Type: int
  - Required: no
- `mysql_hardening_options.safe-user-create`
  - Default: `1`
  - Description: [safe-user-create](http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_safe-user-create)
  - Type: int
  - Required: no
- `mysql_hardening_options.secure-auth`
  - Default: `1`
  - Description: [secure-auth](http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_secure-auth)
  - Type: int
  - Required: no
- `mysql_hardening_options.secure-file-priv`
  - Default: `/tmp`
  - Description: [secure-file-priv](https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_secure-file-priv)
  - Type: str
  - Required: no
- `mysql_hardening_options.skip-symbolic-links`
  - Default: `1`
  - Description: [skip-symbolic-links](http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_symbolic-links)
  - Type: int
  - Required: no
- `mysql_hardening_restart_mysql`
  - Default: `True`
  - Description: Restart mysql after running this role
  - Type: bool
  - Required: no
- `mysql_hardening_skip_grant_tables:`
  - Default: `False`
  - Description: [skip-grant-tables](https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_skip-grant-tables)
  - Type: bool
  - Required: no
- `mysql_hardening_skip_show_database`
  - Default: `1`
  - Description: [skip-show-database](http://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_skip-show-database)
  - Type: int
  - Required: no
- `mysql_remove_anonymous_users`
  - Default: `True`
  - Description: Set to `false` to keep users without authentication
  - Type: bool
  - Required: no
- `mysql_remove_remote_root`
  - Default: `True`
  - Description: If `true`, root can only connect from localhost. Set to `false` to not remove remote root users.
  - Type: bool
  - Required: no
- `mysql_remove_test_database`
  - Default: `True`
  - Description: Set to `false` to keep the test database
  - Type: bool
  - Required: no
- `mysql_root_password`
  - Default: `-----====>SetR00tPa$$wordH3r3!!!<====-----`
  - Description: The default password. Please change or overwrite it
  - Type: str
  - Required: no
- `mysql_user_home`
  - Default: `{{ ansible_env.HOME }}`
  - Description: The path where the `.my.cnf` will be stored
  - Type: str
  - Required: no

## Dependencies

None.

## Example Playbook

```
- hosts: all
  become: true
  roles:
    - name: devsec.hardening.mysql_hardening
```

## 2. Official Technical Reference & Guides (dev-sec/docs)

## File: README.md

# Hardening Framework Documentation

We use [MkDocs](http://www.mkdocs.org/) to document all hardening projects

## Build

    # build the site
    mkdocs build
    # update master branch
    ghp-import -b gh-pages -p site

## Author

* Author:: Christoph Hartmann <chris@lollyrock.com>
* Author:: Hardening Framework Team
* Author:: Deutsche Telekom AG

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.

---

## File: docs/coding/contributing.md

# Contributing

The general steps are:

- Create a ticket in Github Issues.
- Fork the repository on GitHub.
- Clone the repository on your local system.
- Create a branch and make your changes.
- Push the branch, create a pull request and [reference the issue in your pull request](https://github.com/blog/1506-closing-issues-via-pull-requests).

Read on for detailed steps

## License

This project is Apache 2 licensed. Every contribution must be under the Apache 2 License too. For new files we have added a section with [License Headers](/docs/license-headers).

### Sign your work

In addition to the license we only accept contributions signed as your work. The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch. The rules are pretty simple: if you can certify the below (from [developercertificate.org](developercertificate.org)):

```
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
```

then you just add a line to every git commit message:

    HardeningFramework-DCO-1.1-Signed-off-by: Joe Smith <joe.smith@email.com> (github: github_handle)

using your real name (sorry, no pseudonyms or anonymous contributions.)

One way to automate this, is customise your get ``commit.template`` by adding
a ``prepare-commit-msg`` hook to your hardening project checkout:

```
curl -o .git/hooks/prepare-commit-msg https://raw.githubusercontent.com/hardening-io/docs/master/docs/contrib/prepare-commit-msg.hook && chmod +x .git/hooks/prepare-commit-msg
```
* Note: the above script expects to find your GitHub user name in ``git config --get github.user``, set it with `git config --global github.user `


## Contributing to the Hardening Framework Projects

Below, replace "REPO" with the project that should be changed. Replace "USER" with your GitHub username.

0. Create a issue for the bug, feature or improvement you are contributing.

See [Mastering Issues](https://guides.github.com/features/issues/) for details

1. Fork the repository on GitHub.

    HardeningFramework/REPO -> USER/REPO

    You can replace REPO in your fork with a name for the repository
    that makes it unique, if required.

2. Clone the repository locally

    ```
    git clone git@github.com:USER/REPO.git
    ```

3. Ensure the origin is your repository.

    ```
    git config remote.origin.url git@github.com:USER/REPO.git
    ```

4. Add Hardening Framework REPOs as a remote named `upstream` and track it
instead of your origin.

    ```
    git remote add upstream git://github.com/hardening-io/REPO.git
    git config branch.master.remote upstream
    ```

5. Make sure your master branch is updated.

    ```
    git checkout master
    git pull --rebase
    ```

6. Create a new branch for the ticket.

    ```
    git checkout -b ISSUE-####
    ```

7. Make your changes and push the branch to your origin.

    ```
    git push origin ISSUE-####
    ```

8. [Reference the ISSUE](https://github.com/blog/1506-closing-issues-via-pull-requests) in your [Github Pull Request](https://help.github.com/articles/using-pull-requests). We will review the issue and contribution as soon as possible.

### Some Tips

In order to have your contribution accepted as quickly as possible, we have some requests for you. These make it easier to merge contributions without merge conflicts, and keep the scope on topic for a specific issue.

- Please do not update the version in the metadata.rb (chef) or Modulefile/metadata.json (Puppet) files. We handle that as part of the release process.
- Please do not update the CHANGELOG.md. We handle that as part of the release process.
- Please do not mix style changes that are not related to the specific ticket. Create a new, separate ticket for style updates. For example, if a REPO has  Foodcritic findings, create a separate ticket to handle those. See the section on linting.
- Follow the current style of the code where appropriate.
- Run the provided lint, spec and integration tests

---

## File: docs/coding/headers.md

# File headers

## Ruby
```ruby
# encoding: utf-8
#
# Copyright 2015, Hardening Framework Team
#
# 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.
#
```

## JavaScript
```javascript
/* Copyright 2014 Hardening Framework Team
 *
 * 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.
 */
```

## Python

```python
# Copyright 2014 Hardening Framework Team
#
# 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.
```

## HTML

```html

```

---

## File: docs/chef.md

# Chef overview

The following modules are part of the hardening framework:

Base Operating System

* [chef-os-hardening](https://github.com/hardening-io/chef-os-hardening)
* [chef-ssh-hardening](https://github.com/hardening-io/chef-ssh-hardening)

Database

* [chef-mysql-hardening](https://github.com/hardening-io/chef-mysql-hardening)
* [chef-postgres-hardening](https://github.com/hardening-io/chef-postgres-hardening)

Web Server

* [chef-nginx-hardening](https://github.com/hardening-io/chef-nginx-hardening)
* [chef-apache-hardening](https://github.com/hardening-io/chef-apache-hardening)

Example

* [example-chef-hardening](https://github.com/hardening-io/example-chef-hardening)


## Publishing Cookbooks

### Stove-route

The easy way:

        gem install stove
        stove login --username YOURNAME --key ~/.chef/YOURKEY.pem
        cd chef-os-hardening
        stove

In case of errors: Use the method below to ensure that your `metadata.rb` is configure correctly. If you cannot generate a `metadata.json`, fix this error first.

### Chef-route

We will use `chef-ssh-hardening` as an example project.

1. Install chef
        
        gem install chef

2. Since development happens locally, define your ssh key in your chef config

        ~/.chef/knife.rb
        
        client_key "#{ENV['HOME']}/.ssh/id_rsa"
        cookbook_license "apachev2"
        cookbook_copyright "<YOURNAME>"
        cookbook_email ""

3. Copy to temporary cookbooks location

        mkdir /tmp/cookbooks
        cp -r . /tmp/cookbooks/ssh-hardening

4. Generate `metadata.json`

        knife cookbook metadata ssh-hardening -o /tmp/cookbooks

5. Generate tarball

        knife cookbook site share ssh-hardening "ssh-hardening" -o /tmp/cookbooks

---

## File: docs/faq.md

# Frequently asked questions

### Is it possible to use the toolkit without internet connection

Yes, it is possible to use the hardening scripts on computers without internet connection. You need to ensure two specific things:

 * Configured package repository access (eg. RedHat Satellite)
 * Manual installation of chef or puppet

To run the scripts via chef without internet and chef server, do the following.

1. Download the chef package for your operating system.

```bash
wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/13.04/x86_64/chef_11.12.8-2_amd64.deb
```

Transfer the the package and the cookbooks on your servers and start the run:

```bash
echo "---> Install Chef"
dpkg -i chef_11.12.8-2_amd64.deb

echo "---> Start chef run in local mode"
# runs chef client in local mode
chef-client -z -o yourcookbook
```

More information about about chef in local mode is available at [getchef.com](http://www.getchef.com/blog/2013/10/31/chef-client-z-from-zero-to-chef-in-8-5-seconds/)

### How do I configure LDAP authentication with ssh-hardening

Configure the `ssh-cookbook` with `use-pam: true`. This enables the PAM authentication via ssh. In addition you need to configure [PAM properly to work with LDAP](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Directory_Servers.html#s2-ldap-pam). The configuration of PAM for LDAP is not covered by `os-hardening` or `ssh-hardening`.

---

## File: docs/index.md

# Automatic server hardening

Server hardening is a well-known topic with many guides out in the wild. Why this project?

At Deutsche Telekom we need to manage thousands of servers for customers and ourselves. All servers need to be configured properly and maintained, which is difficult and time-consuming to get right.

To answer these needs for security, compliance, and maintainability, we decided to launch this project as a common ground for requirements and their fulfillment.

## Vision / Goal

Our goal is simple: Create a common layer for hardening operating systems and services easily and without interference. Even if you aren't knee-deep in configuration manuals for services or the latest security recommendations, you will be able to implement and use this framework with ease.

## Scope

Since we use Chef and Puppet to automate our deployments, we decided to put them to work for system hardening. The hardening project is currently limited to Chef and Puppet, though extensions to other automation frameworks are welcome!

**What is part of hardening?**

* **Attack surface reduction**: Use service configurations to remove all those components, that are often activated for legacy compatibility or simplified setups. Some default configurations these days already cover good security practices. We take a step further and make sure to deactivate all application modules, which aren't usually required. This baseline changes over time. We keep track of these developments and integrate them with this project.

* **Secure configuration**: It's easy enough to find a guide in a 2 minute search which will tell you to "Set this to 0 and everything will work". Without investigation, it's difficult to know what implications a few configuration lines may carry. Moreover, even a simple starting configuration can quickly make it into a production setup. To avoid these easy mistakes, we make the configuration explicit and default to a secure baseline. Many settings aren't changeable and some will yield errors and warnings with this framework.

* **Core components**: Anything from the basic operating system to well known databases and web servers is part of this project. We want these common building blocks to be at their optimal configuration and avoid repeated mistakes.

**What is NOT part of hardening?**

* **Patch management**: We track changes and will update every piece of this project to work with current and older supported versions of operating systems and applications. However, we cannot safely automate all aspects of patch management. Nevertheless, you can easily integrate hardening into your patch management lifecycle.

* **Minor components**: It's easy to set up a configuration for a service at some point of time and make it secure. It's much more difficult to maintain it over time and support it. We will focus on wide-spread services and components and support them with your and our feedback.

* **Complex configurations**: This includes: Firewall configurations, web-application firewalls, AppArmor profiles or SELinux configurations, amongst others. These are incredibly important to have in your environment, however, their configuration is too dependent on specific setups to abstracted properly. We decided to focus on those components, that are able to take a generalized into their configuration. For everything else, feel free to get in touch with us.

## Lifecycle

Let's take a quick look at the full lifecycle for servers and services and see where hardening fits in.

### Installation of OS

We recommend to install operating systems from trusted sources. This could be an operating system vendor or a trusted third party. In virtualized environments like OpenStack, the secure generation of base images is part of our daily activity. We have automated the building of RedHat, CentOS and Oracle Linux based instances.

* [packer-rhel](https://github.com/TelekomLabs/packer-rhel)

### Hardening

We provide multiple cookbooks for chef and modules for puppet to cover this area. We use best-known guides like [Deutsche Telekom (German)](http://www.telekom.com/static/-/155996/7/technische-sicherheitsanforderungen-si), [BetterCrypto](https://bettercrypto.org/) and the [NSA hardening guide](http://www.nsa.gov/ia/_files/os/redhat/NSA_RHEL_5_GUIDE_v4.2.pdf). For more details look into the respective `test-` repository. Checks are implemented following these guides.


### Continuous management

This area includes tasks like patch management, attack monitoring, and fixing known vulnerabilities. None of these areas are covered in this hardening project.

#### Patch management

It is the heart of keeping your systems secure once everything is in place. So why not patch automatically on every run? We have considered this option for our hardening components but ultimately decided against it: Patches generally aren't a trivial thing to do. Even if you reduce it to security updates only, there may still be regressions which have to be weighted against benefits. Set up a patch management system of your choice.

#### Attack monitoring

Hardening includes a small section of compliance monitoring. Every time an attacker changes a core system configuration, you can gain insights into this through hardening. Since all of our components are tested independently, you can potentially use these tests to validate the compliance of your configuration. However, we recommend against putting too much weight on the results you get. The tests created here are written to verify hardening instructions. Attackers may still find ways to modify files in a way that gets around these checks (example: if we check `main.cfg` only, but attacker writes to `main.cfg.d/my.cfg`). Use HIDS, auditing, and monitoring systems to manage these risks.

#### Vulnerability fixes

A remainder of vulnerabilities may still remain after successful patch management. There are vulnerabilities that need mitigation before proper vendor fixes are released. We won't cover such vulnerabilities in this project. Many settings, however, are meant to reduce the attack surface and thus directly contribute to reducing the risks from unpatched vulnerabilities.

---

## File: docs/principles.md

# Principles

This section records decisions for all defaults and options we set.