move to collections

This commit is contained in:
Sebastian Gumprich 2020-11-07 21:19:43 +01:00
parent eb777fbe2f
commit ac3c12d264
96 changed files with 1456 additions and 2392 deletions

20
.github/labeler.yml vendored Normal file
View file

@ -0,0 +1,20 @@
---
mysql_hardening:
- 'roles/mysql_hardening/**'
- 'molecule/mysql_hardening/**'
- '.github/workflows/mysql_hardening.yml'
os_hardening:
- 'roles/os_hardening/**'
- 'molecule/os_hardening/**'
- '.github/workflows/os_hardening.yml'
ssh_hardening:
- 'roles/ssh_hardening/**'
- 'molecule/ssh_hardening/**'
- '.github/workflows/ssh_hardening.yml'
nginx_hardening:
- 'roles/nginx_hardening/**'
- 'molecule/nginx_hardening/**'
- '.github/workflows/nginx_hardening.yml'

12
.github/workflows/enforce-labels.yml vendored Normal file
View file

@ -0,0 +1,12 @@
name: "Enforce PR labels"
on:
pull_request:
types: [labeled, unlabeled, opened, edited, synchronize]
jobs:
enforce-label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@main
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

39
.github/workflows/galaxy.yml vendored Normal file
View file

@ -0,0 +1,39 @@
---
name: Publish collection to Ansible Galaxy
on:
release:
types:
- published
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# deploy the collection first, because if it fails, we don't want
# to update the galaxy.yml
- name: Deploy the collection
uses: artis3n/ansible_galaxy_collection@v2
with:
api_key: ${{ secrets.GALAXY_API_KEY }}
galaxy_version: ${{ github.event.release.tag_name }}
- name: update galaxy.yml with new version
uses: microsoft/variable-substitution@v1
with:
files: 'galaxy.yml'
env:
version: "${{ github.event.release.tag_name }}"
- name: push galaxy.yml
uses: github-actions-x/commit@v2.7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
push-branch: 'master'
commit-message: 'update galaxy.yml with new version'
force-add: 'true'
files: galaxy.yml
name: dev-sec CI
email: hello@dev-sec.io

76
.github/workflows/mysql_hardening.yml vendored Normal file
View file

@ -0,0 +1,76 @@
---
name: "devsec.mysql_hardening"
on: # yamllint disable-line rule:truthy
workflow_dispatch:
push:
paths:
- 'roles/mysql_hardening/**'
- 'molecule/mysql_hardening/**'
- '.github/workflows/mysql_hardening.yml'
pull_request:
paths:
- 'roles/mysql_hardening/**'
- 'molecule/mysql_hardening/**'
- '.github/workflows/mysql_hardening.yml'
jobs:
build:
runs-on: ubuntu-18.04
env:
PY_COLORS: 1
ANSIBLE_FORCE_COLOR: 1
strategy:
fail-fast: false
matrix:
molecule_distro:
- centos7
- centos8
- ubuntu1604
- ubuntu1804
- ubuntu2004
- debian9
- debian10
# - amazon # geerlingguy.mysql does not support fedora
# - arch # needs to be fixed
# - opensuse_tumbleweed # needs to be fixed
# - fedora # geerlingguy.mysql does not support fedora
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
path: ansible_collections/devsec/hardening
submodules: true
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
sudo apt install git
python -m pip install --no-cache-dir --upgrade pip
pip install -r requirements.txt
working-directory: ansible_collections/devsec/hardening
- name: Create default collection path symlink
run: |
mkdir -p /home/runner/.ansible
ln -s /home/runner/work/ansible-os-hardening/ansible-os-hardening /home/runner/.ansible/collections
# that was a hard one to fix. robert did it thankfully
# https://github.com/robertdebock/ansible-role-mysql/commit/7562e99099b06282391ab7ed102b393a0406d212
- name: disable apparmor on debian systems
run: |
set -x
sudo apt-get install apparmor-profiles
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
if: ${{ startsWith(matrix.molecule_distro, 'Debian') }}
- name: Test with molecule
run: |
molecule --version
molecule test -s mysql_hardening
env:
MOLECULE_DISTRO: ${{ matrix.molecule_distro }}
working-directory: ansible_collections/devsec/hardening

66
.github/workflows/nginx_hardening.yml vendored Normal file
View file

@ -0,0 +1,66 @@
---
name: "devsec.nginx_hardening"
on: # yamllint disable-line rule:truthy
workflow_dispatch:
push:
paths:
- 'roles/nginx_hardening/**'
- 'molecule/nginx_hardening/**'
- '.github/workflows/nginx_hardening.yml'
pull_request:
paths:
- 'roles/nginx_hardening/**'
- 'molecule/nginx_hardening/**'
- '.github/workflows/nginx_hardening.yml'
jobs:
build:
runs-on: ubuntu-18.04
env:
PY_COLORS: 1
ANSIBLE_FORCE_COLOR: 1
strategy:
fail-fast: false
matrix:
molecule_distro:
- centos7
- centos8
- ubuntu1604
- ubuntu1804
- ubuntu2004
- debian9
- debian10
- amazon
# - arch # needs to be fixed
# - opensuse_tumbleweed # needs to be fixed
# - fedora # no support from geerlingguy role
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
path: ansible_collections/devsec/hardening
submodules: true
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
sudo apt install git
python -m pip install --no-cache-dir --upgrade pip
pip install -r requirements.txt
working-directory: ansible_collections/devsec/hardening
- name: Create default collection path symlink
run: |
mkdir -p /home/runner/.ansible
ln -s /home/runner/work/ansible-os-hardening/ansible-os-hardening /home/runner/.ansible/collections
- name: Test with molecule
run: |
molecule --version
molecule test -s nginx_hardening
env:
MOLECULE_DISTRO: ${{ matrix.molecule_distro }}
working-directory: ansible_collections/devsec/hardening

68
.github/workflows/os_hardening.yml vendored Normal file
View file

@ -0,0 +1,68 @@
---
name: "devsec.os_hardening"
on: # yamllint disable-line rule:truthy
workflow_dispatch:
push:
paths:
- 'roles/os_hardening/**'
- 'molecule/os_hardening/**'
- '.github/workflows/os_hardening.yml'
pull_request:
paths:
- 'roles/os_hardening/**'
- 'molecule/os_hardening/**'
- '.github/workflows/os_hardening.yml'
jobs:
build:
runs-on: ubuntu-18.04
env:
PY_COLORS: 1
ANSIBLE_FORCE_COLOR: 1
strategy:
fail-fast: false
matrix:
molecule_distro:
- centos7
- centos8
- ubuntu1604
- ubuntu1804
- ubuntu2004
- debian9
- debian10
- amazon
- opensuse_tumbleweed
# - arch # needs to be fixed
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
path: ansible_collections/devsec/hardening
submodules: true
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
sudo apt install git
python -m pip install --no-cache-dir --upgrade pip
pip install -r requirements.txt
working-directory: ansible_collections/devsec/hardening
- name: Create default collection path symlink
run: |
mkdir -p /home/runner/.ansible
ln -s /home/runner/work/ansible-os-hardening/ansible-os-hardening /home/runner/.ansible/collections
- name: Test with molecule
run: |
if [ "$MOLECULE_DISTRO" = "opensuse_tumbleweed" ]; then
export MOLECULE_DOCKER_COMMAND="/usr/lib/systemd/systemd"
fi
molecule --version
molecule test -s os_hardening
env:
MOLECULE_DISTRO: ${{ matrix.molecule_distro }}
working-directory: ansible_collections/devsec/hardening

24
.github/workflows/prettier-md.yml vendored Normal file
View file

@ -0,0 +1,24 @@
---
# https://github.com/creyD/prettier_action
name: Prettier markdown files
on:
push:
paths:
- '**.md'
jobs:
prettier-md:
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- name: Git checkout
uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: Prettify code
uses: creyD/prettier_action@v3.1
with:
prettier_options: --write {**/*,*}.md

View file

@ -1,3 +1,4 @@
---
name: New release
on:
@ -59,7 +60,7 @@ jobs:
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
release_name: ${{ steps.version.outputs.next-version }}
tag_name: ${{ steps.version.outputs.next-version }}

70
.github/workflows/ssh_hardening.yml vendored Normal file
View file

@ -0,0 +1,70 @@
---
name: "devsec.ssh_hardening"
on: # yamllint disable-line rule:truthy
workflow_dispatch:
push:
paths:
- 'roles/ssh_hardening/**'
- 'molecule/ssh_hardening/**'
- '.github/workflows/ssh_hardening.yml'
pull_request:
paths:
- 'roles/ssh_hardening/**'
- 'molecule/ssh_hardening/**'
- '.github/workflows/ssh_hardening.yml'
jobs:
build:
runs-on: ubuntu-18.04
env:
PY_COLORS: 1
ANSIBLE_FORCE_COLOR: 1
strategy:
fail-fast: false
matrix:
molecule_distro:
- centos7
- centos8
- fedora
- ubuntu1604
- ubuntu1804
- ubuntu2004
- debian9
- debian10
- amazon
# - arch # needs to be fixed
# - opensuse_tumbleweed # baseline is not compatible with suse
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
path: ansible_collections/devsec/hardening
submodules: true
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
sudo apt install git
python -m pip install --no-cache-dir --upgrade pip
pip install -r requirements.txt
working-directory: ansible_collections/devsec/hardening
- name: Create default collection path symlink
run: |
mkdir -p /home/runner/.ansible
ln -s /home/runner/work/ansible-os-hardening/ansible-os-hardening /home/runner/.ansible/collections
- name: Test with molecule
run: |
if [ "$MOLECULE_DISTRO" = "opensuse_tumbleweed" ]; then
export MOLECULE_DOCKER_COMMAND="/usr/lib/systemd/systemd"
fi
molecule --version
molecule test -s ssh_hardening
env:
MOLECULE_DISTRO: ${{ matrix.molecule_distro }}
working-directory: ansible_collections/devsec/hardening

18
.gitmodules vendored Normal file
View file

@ -0,0 +1,18 @@
[submodule "roles/windows_hardening"]
path = roles/windows_hardening
url = https://github.com/dev-sec/ansible-windows-hardening/
[submodule "roles/apache_hardening"]
path = roles/apache_hardening
url = https://github.com/dev-sec/ansible-apache-hardening/
[submodule "roles/nginx_hardening"]
path = roles/nginx_hardening
url = https://github.com/dev-sec/ansible-nginx-hardening/
[submodule "roles/mysql_hardening"]
path = roles/mysql_hardening
url = https://github.com/dev-sec/ansible-mysql-hardening/
[submodule "roles/ssh_hardening"]
path = roles/ssh_hardening
url = https://github.com/dev-sec/ansible-ssh-hardening/
[submodule "roles/os_hardening"]
path = roles/os_hardening
url = https://github.com/dev-sec/ansible-os-hardening/

View file

@ -1,79 +0,0 @@
---
driver:
name: vagrant
driver_config:
http_proxy: <%= ENV['http_proxy'] || nil %>
https_proxy: <%= ENV['https_proxy'] || nil %>
vagrantfiles:
- kitchen_vagrant_block.rb
provisioner:
name: ansible_playbook
hosts: all
require_ansible_repo: false
require_ansible_omnibus: true
require_chef_for_busser: false
require_ruby_for_busser: false
ansible_verbose: true
roles_path: ../ansible-os-hardening/
playbook: tests/test.yml
http_proxy: <%= ENV['http_proxy'] || nil %>
https_proxy: <%= ENV['https_proxy'] || nil %>
transport:
max_ssh_sessions: 1
platforms:
- name: ubuntu-16.04
driver_config:
box: bento/ubuntu-16.04
- name: ubuntu-18.04
driver_config:
box: bento/ubuntu-18.04
- name: centos-6
driver_config:
box: bento/centos-6.7
provision: true
vagrantfiles:
- rhel6_provision.rb
- name: centos-7
driver_config:
box: bento/centos-7
- name: centos-8
driver_config:
box: bento/centos-8
- name: oracle-6
driver_config:
box: bento/oracle-6
provision: true
vagrantfiles:
- rhel6_provision.rb
- name: oracle-7
driver_config:
box: bento/oracle-7
- name: debian-9
driver_config:
box: bento/debian-9
- name: debian-10
driver_config:
box: bento/debian-10
- name: amazon
driver_config:
box: bento/amazonlinux-2
- name: opensuse_tumbleweed
driver_config:
box: opensuse/Tumbleweed.x86_64
provision: true
vagrantfiles:
- suse_provision.rb
provisioner:
ansible_binary_path: "/usr/local/bin"
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/linux-baseline/
suites:
- name: os

View file

@ -1,144 +0,0 @@
---
driver:
name: docker
use_sudo: false
cap_add:
- SYS_ADMIN
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
run_options:
tmpfs:
- /tmp
- /run
- /run/lock
run_command: /sbin/init
http_proxy: <%= ENV['http_proxy'] || nil %>
https_proxy: <%= ENV['https_proxy'] || nil %>
transport:
max_ssh_sessions: 1
provisioner:
name: ansible_playbook
hosts: all
require_ansible_repo: false
require_chef_for_busser: false
require_ruby_for_busser: false
ansible_verbose: true
ansible_diff: true
roles_path: ../ansible-os-hardening/
http_proxy: <%= ENV['http_proxy'] || nil %>
https_proxy: <%= ENV['https_proxy'] || nil %>
playbook: tests/test.yml
platforms:
- name: centos6-ansible-latest
driver:
image: rndmh3ro/docker-centos6-ansible:latest
platform: centos
provision_command:
- sed -i '/loginuid/d' /etc/pam.d/sshd
- name: centos7-ansible-latest
driver:
image: rndmh3ro/docker-centos7-ansible:latest
platform: centos
provision_command:
- sed -i '/nologin/d' /etc/pam.d/sshd
- systemctl enable sshd.service
- name: centos8-ansible-latest
driver:
image: rndmh3ro/docker-centos8-ansible:latest
platform: centos
provision_command:
- sed -i '/nologin/d' /etc/pam.d/sshd
- systemctl enable sshd.service
provisioner:
ansible_binary_path: "/usr/local/bin"
- name: oracle6-ansible-latest
driver:
image: rndmh3ro/docker-oracle6-ansible:latest
platform: centos
provision_command:
- sed -i '/loginuid/d' /etc/pam.d/sshd
- name: oracle7-ansible-latest
driver:
image: rndmh3ro/docker-oracle7-ansible:latest
platform: centos
provision_command:
- yum -y install initscripts
- sed -i '/nologin/d' /etc/pam.d/sshd
- systemctl enable sshd.service
- name: ubuntu1604-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1604-ansible:latest
platform: ubuntu
provision_command:
- systemctl enable ssh.service
- name: ubuntu1804-ansible-latest
driver:
image: rndmh3ro/docker-ubuntu1804-ansible:latest
platform: ubuntu
provision_command:
- systemctl enable ssh.service
- name: debian9-ansible-latest
driver:
image: rndmh3ro/docker-debian9-ansible:latest
platform: debian
provision_command:
- apt install -y systemd-sysv
- systemctl enable ssh.service
- name: debian10-ansible-latest
driver:
image: rndmh3ro/docker-debian10-ansible:latest
platform: debian
provision_command:
- apt install -y systemd-sysv
- systemctl enable ssh.service
- name: amazon-ansible-latest
driver:
image: rndmh3ro/docker-amazon-ansible:latest
platform: centos
provision_command:
- sed -i '/nologin/d' /etc/pam.d/sshd
- systemctl enable sshd.service
- name: fedora-ansible-latest
driver:
image: rndmh3ro/docker-fedora-ansible:latest
platform: centos
provision_command:
- dnf install -y python
- sed -i '/nologin/d' /etc/pam.d/sshd
- systemctl enable sshd.service
- name: opensuse_tumbleweed-ansible-latest
driver:
image: rndmh3ro/docker-opensuse_tumbleweed-ansible
platform: opensuse
provision_command:
- zypper -n install python-xml
- sed -i '/nologin/d' /etc/pam.d/sshd
- sed -i '/systemd/d' /etc/pam.d/common-session
- systemctl enable sshd.service
verifier:
name: inspec
sudo: true
inspec_tests:
- https://github.com/dev-sec/linux-baseline
controls:
# skip sysctl checks, since they make no sense in docker
- /^(?!sysctl-|package-07).+/
suites:
- name: os

View file

@ -1,52 +0,0 @@
---
services: docker
env:
global:
- version=latest
- init=/sbin/init
- run_opts="--cap-add SYS_ADMIN"
- volume="/sys/fs/cgroup:/sys/fs/cgroup:ro"
jobs:
- distro=centos6
volume=":"
run_opts=""
- distro=centos7
- distro=centos8
- distro=oracle6
volume=":"
run_opts=""
# - distro=oracle7
- distro=ubuntu1604
- distro=ubuntu1804
- distro=debian9
init=/lib/systemd/systemd
- distro=debian10
- distro=amazon
- distro=fedora
- distro=opensuse_tumbleweed
run_opts="--privileged"
before_install:
# Pull container
- 'docker pull rndmh3ro/docker-${distro}-ansible:${version}'
script:
- pip install --user ansible-lint
- ansible-lint ./
- container_id=$(mktemp)
# Run container in detached state.
- 'docker run --detach --volume="${volume}" --volume="${PWD}":/etc/ansible/roles/ansible-os-hardening:ro ${run_opts} rndmh3ro/docker-${distro}-ansible:${version} "${init}" > "${container_id}"'
# Output Ansible version from docker image
- 'docker exec "$(cat ${container_id})" ansible-playbook --version'
# Test role.
- 'docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/ansible-os-hardening/tests/test.yml --diff'
# Verify role
- 'inspec exec https://github.com/dev-sec/linux-baseline/ -t docker://$(cat ${container_id}) --no-distinct-exit'
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

33
.yamllint Normal file
View file

@ -0,0 +1,33 @@
---
# Based on ansible-lint config
extends: default
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
# comments: disable
# comments-indentation: disable
# document-start: disable
empty-lines:
max: 3
level: error
hyphens:
level: error
# indentation: disable
key-duplicates: enable
line-length: disable
# new-line-at-end-of-file: disable
new-lines:
type: unix
# trailing-spaces: disable
# truthy: disable

19
Gemfile
View file

@ -1,19 +0,0 @@
# encoding: utf-8
source 'https://rubygems.org'
group :integration do
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-ansible'
gem 'kitchen-vagrant'
gem 'kitchen-inspec'
gem 'kitchen-sharedtests', '~> 0.2.0'
gem 'kitchen-sync'
gem 'kitchen-transport-rsync'
gem 'kitchen-docker'
gem 'inspec', '~> 3'
end
group :tools do
gem 'github_changelog_generator', '~> 1'
end

257
README.md
View file

@ -1,228 +1,87 @@
# os-hardening (Ansible Role)
# Ansible Collection - devsec.hardening
[![Build Status](http://img.shields.io/travis/dev-sec/ansible-os-hardening.svg)][1]
[![Ansible Galaxy](https://img.shields.io/badge/galaxy-os--hardening-660198.svg)][3]
![devsec.os_hardening](https://github.com/dev-sec/ansible-os-hardening/workflows/devsec.os_hardening/badge.svg)
![devsec.ssh_hardening](https://github.com/dev-sec/ansible-os-hardening/workflows/devsec.ssh_hardening/badge.svg)
![devsec.nginx_hardening](https://github.com/dev-sec/ansible-os-hardening/workflows/devsec.nginx_hardening/badge.svg)
![devsec.mysql_hardening](https://github.com/dev-sec/ansible-os-hardening/workflows/devsec.mysql_hardening/badge.svg)
## 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).
This collections provides battle tested hardening for:
It configures:
* Linux operating systems:
* CentOS 7/8
* Ubuntu 16.04/18.04/20.04
* Debian 9/10
* Arch Linux (some roles supported)
* Suse Tumbleweed (some roles supported)
* Fedora (some roles supported)
* Amazon Linux (some roles supported)
* OpenSSH 5.3 and later
* Nginx 1.0.16 or later
* MySQL
* MySQL >= 5.7.31, >= 8.0.3
* MariaDB >= 5.5.65, >= 10.1.45, >= 10.3.17
* Configures package management e.g. allows only signed packages
* Remove packages with known issues
* Configures `pam` and `pam_limits` module
* Shadow password suite configuration
* Configures system path permissions
* Disable core dumps via soft limits
* Restrict root Logins to System Console
* Set SUIDs
* Configures kernel parameters via sysctl
* Install and configure auditd
The hardening is intended to be compliant with the Inspec DevSec Baselines:
It will not:
* https://github.com/dev-sec/linux-baseline
* https://github.com/dev-sec/ssh-baseline
* https://github.com/dev-sec/nginx-baseline
* https://github.com/dev-sec/mysql-baseline
* Update system packages
* Install security patches
## Tested with Ansible
## Requirements
2.10
* Ansible 2.5.0
## Included content
## Warning
* [os_hardening](roles/os_hardening/)
* [ssh_hardening](roles/ssh_hardening/)
* [mysql_hardening](roles/mysql_hardening/)
* [nginx_hardening](roles/nginx_hardening/)
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).
If you're using Docker / Kubernetes+Docker you'll need to override the ipv4 ip forward sysctl setting.
```yaml
- hosts: localhost
roles:
- dev-sec.os-hardening
vars:
sysctl_overwrite:
# Enable IPv4 traffic forwarding.
net.ipv4.ip_forward: 1
```
In progress, not working:
* [apache_hardening](roles/apache_hardening/)
* [windows_hardening](roles/windows_hardening/)
## Using this collection
## Variables
Please refer to the examples in the readmes of the role.
| Name | Default Value | Description |
| -------------- | ------------- | -----------------------------------|
| `os_desktop_enable`| false | true if this is a desktop system, ie Xorg, KDE/GNOME/Unity/etc|
| `os_env_extra_user_paths`| [] | add additional paths to the user's `PATH` variable (default is empty).|
| `os_env_umask`| 027| set default permissions for new files to `750` |
| `os_auth_pw_max_age`| 60 | maximum password age (set to `99999` to effectively disable it) |
| `os_auth_pw_min_age`| 7 | minimum password age (before allowing any other password change)|
| `os_auth_retries`| 5 | the maximum number of authentication attempts, before the account is locked for some time|
| `os_auth_lockout_time`| 600 | time in seconds that needs to pass, if the account was locked due to too many failed authentication attempts|
| `os_auth_timeout`| 60 | authentication timeout in seconds, so login will exit if this time passes|
| `os_auth_allow_homeless`| false | true if to allow users without home to login|
| `os_auth_pam_passwdqc_enable`| true | true if you want to use strong password checking in PAM using passwdqc|
| `os_auth_pam_passwdqc_options`| "min=disabled,disabled,16,12,8" | set to any option line (as a string) that you want to pass to passwdqc|
| `os_security_users_allow`| [] | list of things, that a user is allowed to do. May contain `change_user`.
| `os_security_kernel_enable_module_loading`| true | true if you want to allowed to change kernel modules once the system is running (eg `modprobe`, `rmmod`)|
| `os_security_kernel_enable_core_dump`| false | kernel is crashing or otherwise misbehaving and a kernel core dump is created |
| `os_security_suid_sgid_enforce`| true | 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|
| `os_security_suid_sgid_blacklist`| [] | a list of paths which should have their SUID/SGID bits removed|
| `os_security_suid_sgid_whitelist`| [] | a list of paths which should not have their SUID/SGID bits altered|
| `os_security_suid_sgid_remove_from_unknown`| false | 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`.|
| `os_security_packages_clean`| true | removes packages with known issues. See section packages.|
| `os_selinux_state` | enforcing | Set the SELinux state, can be either disabled, permissive, or enforcing. |
| `os_selinux_policy` | targeted | Set the SELinux polixy. |
| `ufw_manage_defaults` | true | true means apply all settings with `ufw_` prefix|
| `ufw_ipt_sysctl` | '' | 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`
| `ufw_default_input_policy` | DROP | set default input policy of ufw to `DROP` |
| `ufw_default_output_policy` | ACCEPT | set default output policy of ufw to `ACCEPT` |
| `ufw_default_forward_policy` | DROP | set default forward policy of ufw to `DROP` |
| `os_auditd_enabled` | true | Set to false to disable installing and configuring auditd. |
| `os_auditd_max_log_file_action` | `keep_logs` | 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`. |
| `hidepid_option` | `2` | `0`: This is the default setting and gives you the default behaviour. `1`: With this option an normal user would not see other processes but their own about ps, top etc, but he is still able to see process IDs in /proc. `2`: Users are only able too see their own processes (like with hidepid=1), but also the other process IDs are hidden for them in /proc. |
| `proc_mnt_options` | `rw,nosuid,nodev,noexec,relatime,hidepid={{ hidepid_option }}` | Mount proc with hardenized options, including `hidepid` with variable value. |
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
## Packages
## Contributing to this collection
We remove the following packages:
See the [contributor guideline](CONTRIBUTING.md).
* 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))
## Release notes
## Disabled filesystems
See the [changelog](https://github.com/dev-sec/ansible-os-hardening/tree/master/CHANGELOG.md).
We disable the following filesystems, because they're most likely not used:
## Roadmap
* "cramfs"
* "freevxfs"
* "jffs2"
* "hfs"
* "hfsplus"
* "squashfs"
* "udf"
* "vfat" # only if uefi is not in use
Todos:
* Work on [apache_hardening](roles/apache_hardening/) and [windows_hardening](roles/windows_hardening/).
* Add support for more operating systems,
To prevent some of the filesystems from being disabled, add them to the `os_filesystem_whitelist` variable.
## More information
## Installation
General information:
Install the role with ansible-galaxy:
- [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)
```
ansible-galaxy install dev-sec.os-hardening
```
## Licensing
## Example Playbook
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
```yaml
- hosts: localhost
roles:
- dev-sec.os-hardening
```
http://www.apache.org/licenses/LICENSE-2.0
## 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:
- dev-sec.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.
## Local Testing
The preferred way of locally testing the role is to use Docker. You will have to install Docker on your system. See [Get started](https://docs.docker.com/) for a Docker package suitable to for your system.
You can also use vagrant and Virtualbox or VMWare to run tests locally. You will have to install Virtualbox and Vagrant on your system. See [Vagrant Downloads](http://downloads.vagrantup.com/) for a vagrant package suitable for your system. For all our tests we use `test-kitchen`. If you are not familiar with `test-kitchen` please have a look at [their guide](http://kitchen.ci/docs/getting-started).
Next install test-kitchen:
```bash
# Install dependencies
gem install bundler
bundle install
```
### Testing with Docker
```
# fast test on one machine
bundle exec kitchen test default-ubuntu-1404
# test on all machines
bundle exec kitchen test
# for development
bundle exec kitchen create default-ubuntu-1404
bundle exec kitchen converge default-ubuntu-1404
```
### Testing with Virtualbox
```
# fast test on one machine
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test default-ubuntu-1404
# test on all machines
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen test
# for development
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen create default-ubuntu-1404
KITCHEN_YAML=".kitchen.vagrant.yml" bundle exec kitchen converge default-ubuntu-1404
```
For more information see [test-kitchen](http://kitchen.ci/docs/getting-started)
## Contributors + Kudos
...
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)
Thanks to all of you!
## Contributing
See [contributor guideline](CONTRIBUTING.md).
## License and Author
* Author:: Sebastian Gumprich
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.
[1]: http://travis-ci.org/dev-sec/ansible-os-hardening
[2]: https://gitter.im/dev-sec/general
[3]: https://galaxy.ansible.com/dev-sec/os-hardening
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.

View file

@ -1,11 +0,0 @@
#!/usr/bin/env rake
# encoding: utf-8
# Automatically generate a changelog for this project. Only loaded if
# the necessary gem is installed.
begin
require 'github_changelog_generator/task'
GitHubChangelogGenerator::RakeTask.new :changelog
rescue LoadError
puts '>>>>> GitHub Changelog Generator not loaded, omitting tasks'
end

View file

@ -1,4 +0,0 @@
# TODO
* [Adduser consistency](https://github.com/hardening-io/chef-os-hardening/pull/73)
* [add support for limiting password re-use](https://github.com/hardening-io/puppet-os-hardening/pull/61)

View file

@ -1,16 +0,0 @@
# config file for ansible -- http://ansible.com/
# ==============================================
# nearly all parameters can be overridden in ansible-playbook
# or with command line flags. ansible will read ANSIBLE_CONFIG,
# ansible.cfg in the current working directory, .ansible.cfg in
# the home directory or /etc/ansible/ansible.cfg, whichever it
# finds first
[defaults]
ansible_managed = Ansible managed: {file} modified by {uid} on {host}
# additional paths to search for roles in, colon separated
roles_path = ../
[ssh_connection]
scp_if_ssh = True

View file

@ -1,283 +0,0 @@
os_desktop_enable: false
os_env_extra_user_paths: []
os_auth_pw_max_age: 60
os_auth_pw_min_age: 7 # discourage password cycling
os_auth_retries: 5
os_auth_lockout_time: 600 # 10min
os_auth_timeout: 60
os_auth_allow_homeless: false
os_auth_pam_passwdqc_enable: true
os_auth_pam_passwdqc_options: 'min=disabled,disabled,16,12,8' # used in RHEL6
os_auth_pam_pwquality_options: 'try_first_pass retry=3 type=' # used in RHEL7
os_auth_root_ttys: [console, tty1, tty2, tty3, tty4, tty5, tty6]
os_chfn_restrict: ''
# may contain: change_user
os_security_users_allow: []
# specify system accounts those login should not be disabled and password not changed
os_ignore_users: ['vagrant', 'kitchen']
os_security_kernel_enable_module_loading: true
os_security_kernel_enable_core_dump: false
os_security_suid_sgid_enforce: true
# user-defined blacklist and whitelist
os_security_suid_sgid_blacklist: []
os_security_suid_sgid_whitelist: []
# if this is true, remove any suid/sgid bits from files that were not in the whitelist
os_security_suid_sgid_remove_from_unknown: false
# remove packages with known issues
os_security_packages_clean: true
os_security_packages_list: ['xinetd', 'inetd', 'ypserv', 'telnet-server', 'rsh-server', 'prelink']
# Allow interactive startup (rhel, centos)
os_security_init_prompt: true
# Require root password for single user mode. (rhel, centos)
os_security_init_single: false
# Apply ufw defaults
ufw_manage_defaults: true
# Empty variable disables IPT_SYSCTL in /etc/default/ufw
# by default in Ubuntu it set to: /etc/ufw/sysctl.conf
# CAUTION
# if you enable it - it'll overwrite /etc/sysctl.conf file, managed by hardening framework
ufw_ipt_sysctl: ''
# Default ufw variables
ufw_default_input_policy: 'DROP'
ufw_default_output_policy: 'ACCEPT'
ufw_default_forward_policy: 'DROP'
ufw_default_application_policy: 'SKIP'
ufw_manage_builtins: 'no'
ufw_ipt_modules: 'nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns'
sysctl_config:
# Disable IPv4 traffic forwarding. | sysctl-01
net.ipv4.ip_forward: 0
# Disable IPv6 traffic forwarding. | sysctl-19
net.ipv6.conf.all.forwarding: 0
# ignore RAs on Ipv6. | sysctl-25
net.ipv6.conf.all.accept_ra: 0
net.ipv6.conf.default.accept_ra: 0
# Enable RFC-recommended source validation feature. | sysctl-02
net.ipv4.conf.all.rp_filter: 1
net.ipv4.conf.default.rp_filter: 1
# Reduce the surface on SMURF attacks. | sysctl-04
# Make sure to ignore ECHO broadcasts, which are only required in broad network analysis.
net.ipv4.icmp_echo_ignore_broadcasts: 1
# There is no reason to accept bogus error responses from ICMP, so ignore them instead. | sysctl-03
net.ipv4.icmp_ignore_bogus_error_responses: 1
# Limit the amount of traffic the system uses for ICMP. | sysctl-05
net.ipv4.icmp_ratelimit: 100
# Adjust the ICMP ratelimit to include ping, dst unreachable,
# source quench, ime exceed, param problem, timestamp reply, information reply | sysctl-06
net.ipv4.icmp_ratemask: 88089
# Disable IPv6 | sysctl-18
net.ipv6.conf.all.disable_ipv6: 1
# Protect against wrapping sequence numbers at gigabit speeds | sysctl-07
net.ipv4.tcp_timestamps: 0
# Define restriction level for announcing the local source IP | sysctl-08
net.ipv4.conf.all.arp_ignore: 1
# Define mode for sending replies in response to
# received ARP requests that resolve local target IP addresses | sysctl-09
net.ipv4.conf.all.arp_announce: 2
# RFC 1337 fix F1 | sysctl-10
net.ipv4.tcp_rfc1337: 1
# Send(router) or accept(host) RFC1620 shared media redirects | sysctl-12
net.ipv4.conf.all.shared_media: 1
net.ipv4.conf.default.shared_media: 1
# Accepting source route can lead to malicious networking behavior,
# so disable it if not needed. | sysctl-13
net.ipv4.conf.all.accept_source_route: 0
net.ipv4.conf.default.accept_source_route: 0
# Accepting redirects can lead to malicious networking behavior, so disable
# it if not needed. | sysctl-13 | sysctl-14 | sysctl-15 | sysctl-20
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
# For non-routers: don't send redirects, these settings are 0 | sysctl-16
net.ipv4.conf.all.send_redirects: 0
net.ipv4.conf.default.send_redirects: 0
# log martian packets | sysctl-17
net.ipv4.conf.all.log_martians: 1
net.ipv4.conf.default.log_martians: 1
# ipv6 config
# Disable acceptance of IPv6 router solicitations messages | sysctl-21
net.ipv6.conf.default.router_solicitations: 0
# Disable Accept Router Preference from router advertisement | sysctl-22
net.ipv6.conf.default.accept_ra_rtr_pref: 0
# Disable learning Prefix Information from router advertisement | sysctl-23
net.ipv6.conf.default.accept_ra_pinfo: 0
# Disable learning Hop limit from router advertisement | sysctl-24
net.ipv6.conf.default.accept_ra_defrtr: 0
# Disable IPv6 autoconfiguration | sysctl-26
net.ipv6.conf.default.autoconf: 0
# Disable neighbor solicitations to send out per address | sysctl-27
net.ipv6.conf.default.dad_transmits: 0
# Assign one global unicast IPv6 addresses to each interface | sysctl-28
net.ipv6.conf.default.max_addresses: 1
# This settings controls how the kernel behaves towards module changes at
# runtime. Setting to 1 will disable module loading at runtime.
# Setting it to 0 is actually never supported. | sysctl-29
# kernel.modules_disabled: 1
# Magic Sysrq should be disabled, but can also be set to a safe value if so
# desired for physical machines. It can allow a safe reboot if the system hangs
# and is a 'cleaner' alternative to hitting the reset button. | sysctl-30
# The following values are permitted:
# * **0** - disable sysrq
# * **1** - enable sysrq completely
# * **>1** - bitmask of enabled sysrq functions:
# * **2** - control of console logging level
# * **4** - control of keyboard (SAK, unraw)
# * **8** - debugging dumps of processes etc.
# * **16** - sync command
# * **32** - remount read-only
# * **64** - signalling of processes (term, kill, oom-kill)
# * **128** - reboot/poweroff
# * **256** - nicing of all RT tasks
kernel.sysrq: 0
# Prevent core dumps with SUID. These are usually only
# needed by developers and may contain sensitive information. | sysctl-31
fs.suid_dumpable: 0
# Virtual memory regions protection | sysctl-32
kernel.randomize_va_space: 2
kernel.core_uses_pid: 1
# The PTRACE system is used for debugging. With it, a single user process
# can attach to any other dumpable process owned by the same user. In the
# case of malicious software, it is possible to use PTRACE to access
# credentials that exist in memory (re-using existing SSH connections,
# extracting GPG agent information, etc).
#
# A PTRACE scope of "0" is the more permissive mode. A scope of "1" limits
# PTRACE only to direct child processes (e.g. "gdb name-of-program" and
# "strace -f name-of-program" work, but gdb's "attach" and "strace -fp $PID"
# do not). The PTRACE scope is ignored when a user has CAP_SYS_PTRACE, so
# "sudo strace -fp $PID" will work as before. For more details see:
# https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace
#
# For applications launching crash handlers that need PTRACE, exceptions can
# be registered by the debugee by declaring in the segfault handler
# specifically which process will be using PTRACE on the debugee:
# prctl(PR_SET_PTRACER, debugger_pid, 0, 0, 0);
#
# In general, PTRACE is not needed for the average running Ubuntu system.
# To that end, the default is to set the PTRACE scope to "1". This value
# may not be appropriate for developers or servers with only admin accounts.
# kernel.yama.ptrace_scope = 1
kernel.yama.ptrace_scope: 1
# Protect the zero page of memory from userspace mmap to prevent kernel
# NULL-dereference attacks against potential future kernel security
# vulnerabilities. (Added in kernel 2.6.23.)
#
# While this default is built into the Ubuntu kernel, there is no way to
# restore the kernel default if the value is changed during runtime; for
# example via package removal (e.g. wine, dosemu). Therefore, this value
# is reset to the secure default each time the sysctl values are loaded.
vm.mmap_min_addr: 65536
# These settings eliminate an entire class of security vulnerability:
# time-of-check-time-of-use cross-privilege attacks using guessable
# filenames (generally seen as "/tmp file race" vulnerabilities).
fs.protected_hardlinks: 1
fs.protected_symlinks: 1
# These settings are set to the maximum supported value in order to
# improve ASLR effectiveness for mmap, at the cost of increased
# address-space fragmentation. | Tail-1
vm.mmap_rnd_bits: 32
vm.mmap_rnd_compat_bits: 16
# When an attacker is trying to exploit the local kernel, it is often
# helpful to be able to examine where in memory the kernel, modules,
# and data structures live. As such, kernel addresses should be treated
# as sensitive information.
#
# Many files and interfaces contain these addresses (e.g. /proc/kallsyms,
# /proc/modules, etc), and this setting can censor the addresses. A value
# of "0" allows all users to see the kernel addresses. A value of "1"
# limits visibility to the root user, and "2" blocks even the root user.
#
# Some off-the-shelf malware exploit kernel addresses exposed
# via /proc/kallsyms so by not making these addresses easily available
# we increase the cost of such attack some what; now such malware has
# to check which kernel Tails is running and then fetch the corresponding
# kernel address map from some external source. This is not hard,
# but certainly not all malware has such functionality. | Tails-2
kernel.kptr_restrict: 2
# kexec is dangerous: it enables replacement of the running kernel. | Tails-3
kernel.kexec_load_disabled: 1
# Do not delete the following line or otherwise the playbook will fail
# at task 'create a combined sysctl-dict if overwrites are defined'
sysctl_overwrite:
# disable unused filesystems
os_unused_filesystems:
- "cramfs"
- "freevxfs"
- "jffs2"
- "hfs"
- "hfsplus"
- "squashfs"
- "udf"
- "vfat"
# Obsolete network protocols that should be disabled
# per CIS Oracle Linux 6 Benchmark (2016)
- "tipc" # CIS 3.5.4
- "sctp" # CIS 3.5.2
- "dccp" # CIS 3.5.1
- "rds" # CIS 3.5.3
# whitelist for used filesystems
os_filesystem_whitelist: []
# Set to false to turn the role into a no-op. Useful when using
# the Ansible role dependency mechanism.
os_hardening_enabled: true
# Set to false to disable installing and configuring auditd.
os_auditd_enabled: true
os_auditd_max_log_file_action: keep_logs
# Set the SELinux state, can be either disabled, permissive, or enforcing.
os_selinux_state: enforcing
# Set the SELinux polixy.
os_selinux_policy: targeted
hidepid_option: '2' # allowed values: 0, 1, 2
proc_mnt_options: 'rw,nosuid,nodev,noexec,relatime,hidepid={{ hidepid_option }}'

85
galaxy.yml Normal file
View file

@ -0,0 +1,85 @@
# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with
# underscores or numbers and cannot contain consecutive underscores
namespace: devsec
# The name of the collection. Has the same character restrictions as 'namespace'
name: hardening
# The version of the collection. Must be compatible with semantic versioning
version: 1.0.0
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
# A list of the collection's content authors. Can be just the name or in the format 'Full Name <email> (url)
# @nicks:irc/im.site#channel'
authors:
- dev-sec <hello@dev-sec.io>
# A short summary description of the collection
description: >-
This collections provides battle tested hardening for:
* Linux operating systems:
* CentOS 7/8
* Ubuntu 16.04/18.04/20.04
* Debian 9/10
* Arch Linux (some roles supported)
* Suse Tumbleweed (some roles supported)
* Fedora (some roles supported)
* Amazon Linux (some roles supported)
* OpenSSH 5.3 and later
* Nginx 1.0.16 or later
* MySQL
* MySQL >= 5.7.31, >= 8.0.3
* MariaDB >= 5.5.65, >= 10.1.45, >= 10.3.17
# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only
# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file'
license:
- GPL-2.0-or-later
# The path to the license file for the collection. This path is relative to the root of the collection. This key is
# mutually exclusive with 'license'
license_file: ''
# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character
# requirements as 'namespace' and 'name'
tags:
- dev-sec
- hardening
- centos
- ubuntu
- debian
- nginx
- mysql
- openssh
# Collections that this collection requires to be installed for it to be usable. The key of the dict is the
# collection label 'namespace.name'. The value is a version range
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
# range specifiers can be set and are separated by ','
dependencies: {}
# The URL of the originating SCM repository
repository: https://github.com/dev-sec/ansible-os-hardening
# The URL to the homepage of the collection/project
homepage: https://dev-sec.io/
# The URL to the collection issue tracker
issues: https://github.com/dev-sec/ansible-os-hardening/issues
# ignore files not needed for release
build_ignore:
- codecov.yml
- .github
- .gitattributes
- .gitignore
- hacking
- requirements.txt
- test-requirements.txt
- tests
- .tox
- tox.ini
- .yamllint

View file

@ -1,3 +0,0 @@
---
- name: update-initramfs
command: 'update-initramfs -u'

View file

@ -1,5 +0,0 @@
# This is a Vagrant block to allow proxy settings to be carried into Kitchen
# You need this for all of yum/apt etc. to work!
Vagrant.configure(2) do |config|
end

View file

@ -1,29 +0,0 @@
---
galaxy_info:
author: "Sebastian Gumprich"
description: 'This role provides numerous security-related configurations, providing all-round base protection.'
company: Hardening Framework Team
license: Apache License 2.0
min_ansible_version: '2.5'
platforms:
- name: EL
versions:
- 6
- 7
- 8
- name: Ubuntu
versions:
- xenial
- bionic
- name: Debian
versions:
- stretch
- buster
- name: Amazon
- name: Fedora
- name: openSUSE
galaxy_tags:
- system
- security
- hardening
dependencies: []

View file

@ -0,0 +1,22 @@
******
Docker driver installation guide
******
Requirements
============
* Docker Engine
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ python3 -m pip install 'molecule[docker]'

View file

@ -0,0 +1,31 @@
---
- name: wrapper playbook for kitchen testing "ansible-mysql-hardening"
hosts: all
become: true
tasks:
- name: Determine required MySQL Python libraries (Ubuntu Focal Fossa ++)
set_fact:
mysql_python_package_debian: "python3-pymysql"
when:
- mysql_python_package_debian is not defined
- ansible_distribution == "Ubuntu"
- ansible_distribution_major_version|int > 19
- name: Determine required MySQL Python libraries.
set_fact:
mysql_python_package_debian: "{% if 'python3' in ansible_python_interpreter|default('') %}python3-mysqldb{% else %}python-mysqldb{% endif %}"
when:
- mysql_python_package_debian is not defined
- ansible_distribution != "Ubuntu"
- ansible_distribution_major_version|int < 20
- include_role:
name: dev-sec.mysql
- include_role:
name: mysql_hardening
vars:
overwrite_global_mycnf: false
mysql_root_password: iloverandompasswordsbutthiswilldo
mysql_user_password: iloverandompasswordsbutthiswilldo
mysql_config_file: /etc/mysql/mariadb.cnf
mysql_root_password_update: true

View file

@ -0,0 +1,63 @@
---
dependency:
name: galaxy
options:
role-file: molecule/mysql_hardening/requirements.yml
driver:
name: docker
lint: |
yamllint roles/mysql_hardening/ molecule/mysql_hardening/ .github/workflows/mysql_hardening.yml
ansible-lint roles/mysql_hardening/
platforms:
- name: instance
image: "rndmh3ro/docker-${MOLECULE_DISTRO}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
pre_build_image: true
environment:
container: docker
security_opts:
- apparmor=unconfined
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
callback_whitelist: profile_tasks, timer, yaml
verifier:
name: ansible
scenario:
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- destroy
test_sequence:
- dependency
- lint
- destroy
- syntax
- create
- prepare
- converge
# - idempotence # not idempotent
- verify
- destroy

View file

@ -0,0 +1,23 @@
---
- name: wrapper playbook for kitchen testing "ansible-mysql-hardening"
hosts: all
become: true
tasks:
- name: Run the equivalent of "apt-get update && apt-get upgrade"
apt:
name: "*"
state: latest
update_cache: true
when: ansible_os_family == 'Debian'
- name: install required tools on SuSE
zypper:
name: "python-xml"
state: present
when: ansible_facts.os_family == 'Suse'
- name: create missing directory
file:
path: "/etc/mysql/conf.d"
state: directory

View file

@ -0,0 +1,11 @@
---
roles:
- name: geerlingguy.git
version: 3.0.0
- name: dev-sec.mysql
version: master
collections:
- name: https://github.com/ansible-collections/community.mysql.git
type: git
version: main

View file

@ -0,0 +1,55 @@
---
- name: Verify
hosts: all
become: true
roles:
- geerlingguy.git
tasks:
- name: install fake SuSE-release for cinc compatibility
copy:
content: |
openSUSE Faked Enterprise 2020 (x86_64)
VERSION = 2020
CODENAME = Faked Feature
dest: /etc/SuSE-release
owner: root
group: root
mode: '0444'
when: ansible_facts.os_family == 'Suse'
- name: install git for SuSE since geerlinguy.git does not support it
zypper:
name: git
state: present
when: ansible_facts.os_family == 'Suse'
- name: install procps for debian systems
apt:
name: procps
state: present
update_cache: true
when: ansible_distribution == 'Debian'
- name: download cinc-auditor
get_url:
url: https://omnitruck.cinc.sh/install.sh
dest: /tmp/install.sh
mode: '0775'
- name: install cinc-auditor
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
- name: Execute cinc-auditor tests
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/mysql-baseline.git"
register: test_results
changed_when: false
ignore_errors: true
- name: Display details about the cinc-auditor results
debug:
msg: "{{ test_results.stdout_lines }}"
- name: Fail when tests fail
fail:
msg: "Inspec failed to validate"
when: test_results.rc != 0

View file

@ -0,0 +1,22 @@
*******
Docker driver installation guide
*******
Requirements
============
* Docker Engine
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ python3 -m pip install 'molecule[docker]'

View file

@ -0,0 +1,10 @@
---
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
become: true
hosts: all
vars:
- nginx_ppa_use: true
- nginx_ppa_version: stable
tasks:
- include_role:
name: nginx_hardening

View file

@ -0,0 +1,66 @@
---
dependency:
name: galaxy
options:
role-file: molecule/nginx_hardening/requirements.yml
driver:
name: docker
lint: |
yamllint roles/nginx_hardening/ molecule/nginx_hardening/ .github/workflows/nginx_hardening.yml
ansible-lint roles/nginx_hardening/
platforms:
- name: instance
image: "rndmh3ro/docker-${MOLECULE_DISTRO}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
tmpfs:
- /tmp
- /run
capabilities:
- SYS_ADMIN
tty: true
environment:
container: docker
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
callback_whitelist: profile_tasks, timer, yaml
verifier:
name: ansible
scenario:
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- destroy
test_sequence:
- dependency
- lint
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy

View file

@ -0,0 +1,24 @@
---
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
hosts: localhost
vars:
- nginx_main_template_enable: true
- nginx_main_template:
template_file: nginx.conf.j2
conf_file_name: nginx.conf
conf_file_location: /etc/nginx/
user: www-data
worker_processes: auto
error_level: warn
worker_connections: 1024
http_enable: true
http_settings:
keepalive_timeout: 65
cache: false
rate_limit: false
keyval: false
stream_enable: false
http_global_autoindex: false
roles:
- nginxinc.nginx
- nginx_hardening

View file

@ -0,0 +1,6 @@
---
- name: wrapper playbook for kitchen testing "ansible-nginx-hardening" with custom settings
hosts: localhost
roles:
- nginxinc.nginx
- nginx_hardening

View file

@ -0,0 +1,24 @@
---
- name: prepare playbook for kitchen testing "ansible-nginx-hardening" with custom settings
become: true
hosts: all
tasks:
- name: install required tools on SuSE
zypper:
name: "python-xml"
state: present
when: ansible_facts.os_family == 'Suse'
- name: install required packages
package:
name: "python3-apt"
update_cache: true
ignore_errors: true
- name: Set correct distribution Version for Amazon Linux
set_fact:
ansible_distribution_major_version: 7
when: ansible_distribution == 'Amazon'
- include_role:
name: geerlingguy.nginx

View file

@ -0,0 +1,4 @@
---
roles:
- geerlingguy.git
- geerlingguy.nginx

View file

@ -0,0 +1,58 @@
---
- name: Verify
hosts: all
become: true
roles:
- geerlingguy.git
tasks:
- name: install fake SuSE-release for cinc compatibility
copy:
content: |
openSUSE Faked Enterprise 2020 (x86_64)
VERSION = 2020
CODENAME = Faked Feature
dest: /etc/SuSE-release
owner: root
group: root
mode: '0444'
when: ansible_facts.os_family == 'Suse'
- name: install git for SuSE since geerlinguy.git does not support it
zypper:
name: git
state: present
when: ansible_facts.os_family == 'Suse'
- name: Run the equivalent of "apt-get update" as a separate step
apt:
update_cache: true
when: ansible_facts.os_family == 'Debian'
- name: install required tools on debian
apt:
name: procps
when: ansible_facts.os_family == 'Debian'
- name: download cinc-auditor
get_url:
url: https://omnitruck.cinc.sh/install.sh
dest: /tmp/install.sh
mode: '0775'
- name: install cinc-auditor
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
- name: Execute cinc-auditor tests
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/nginx-baseline.git"
register: test_results
changed_when: false
ignore_errors: true
- name: Display details about the cinc-auditor results
debug:
msg: "{{ test_results.stdout_lines }}"
- name: Fail when tests fail
fail:
msg: "Inspec failed to validate"
when: test_results.rc != 0

View file

@ -0,0 +1,22 @@
*******
Docker driver installation guide
*******
Requirements
============
* Docker Engine
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ python3 -m pip install 'molecule[docker]'

View file

@ -1,34 +1,15 @@
---
- name: wrapper playbook for kitchen testing "ansible-os-hardening" with custom vars for testing
hosts: localhost
roles:
- ansible-os-hardening
pre_tasks:
- name: set ansible_python_interpreter to "/usr/bin/python3" on fedora
hosts: all
become: true
collections:
- devsec.hardening
tasks:
- name: workaround for https://github.com/ansible/ansible/issues/66304
set_fact:
ansible_python_interpreter: "/usr/bin/python3"
when: ansible_facts.distribution == 'Fedora'
- name: Run the equivalent of "apt-get update" as a separate step
apt:
update_cache: yes
when: ansible_facts.os_family == 'Debian'
- name: install required tools on debian
apt:
name: procps
when: ansible_facts.os_family == 'Debian'
- name: install required tools on fedora
dnf:
name:
- python
- findutils
- procps-ng
when: ansible_facts.distribution == 'Fedora'
- name: install required tools on SuSE
shell: "zypper -n install python-xml"
when: ansible_facts.os_family == 'Suse'
- name: create recursing symlink to test minimize access
shell: "rm -f /usr/bin/zzz && ln -s /usr/bin /usr/bin/zzz"
ansible_virtualization_type: "docker"
- include_role:
name: os_hardening
vars:
os_security_users_allow: change_user
os_security_kernel_enable_core_dump: true
@ -78,19 +59,23 @@
fs.suid_dumpable: 0
kernel.randomize_va_space: 2
- name: wrapper playbook for kitchen testing "ansible-os-hardening"
hosts: localhost
vars:
os_auditd_enabled: false
pre_tasks:
- name: set ansible_python_interpreter to "/usr/bin/python3" on fedora
set_fact:
ansible_python_interpreter: "/usr/bin/python3"
when: ansible_facts.distribution == 'Fedora'
- name: Run the equivalent of "apt-get update" as a separate step
apt:
update_cache: yes
when: ansible_facts.os_family == 'Debian'
roles:
- ansible-os-hardening
# - name: wrapper playbook for kitchen testing "ansible-os-hardening"
# hosts: all
# become: true
# collections:
# - devsec.hardening
# vars:
# os_auditd_enabled: false
# tasks:
# - name: set ansible_python_interpreter to "/usr/bin/python3" on fedora
# set_fact:
# ansible_python_interpreter: "/usr/bin/python3"
# when: ansible_facts.distribution == 'Fedora'
#
# - name: Run the equivalent of "apt-get update" as a separate step
# apt:
# update_cache: yes
# when: ansible_facts.os_family == 'Debian'
#
# - include_role:
# name: os_hardening

View file

@ -0,0 +1,66 @@
---
dependency:
name: galaxy
options:
role-file: molecule/os_hardening/requirements.yml
driver:
name: docker
lint: |
yamllint roles/os_hardening/ molecule/os_hardening/ .github/workflows/os_hardening.yml
ansible-lint roles/os_hardening/
platforms:
- name: instance
image: "rndmh3ro/docker-${MOLECULE_DISTRO}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
tmpfs:
- /tmp
- /run
capabilities:
- SYS_ADMIN
tty: true
environment:
container: docker
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
callback_whitelist: profile_tasks, timer, yaml
verifier:
name: ansible
scenario:
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- destroy
test_sequence:
- dependency
- lint
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy

View file

@ -0,0 +1,52 @@
---
- name: wrapper playbook for kitchen testing "ansible-os-hardening" with custom vars for testing
hosts: all
become: true
collections:
- devsec.hardening
tasks:
- name: set ansible_python_interpreter to "/usr/bin/python3" on fedora
set_fact:
ansible_python_interpreter: "/usr/bin/python3"
when: ansible_facts.distribution == 'Fedora'
- name: Run the equivalent of "apt-get update && apt-get upgrade"
apt:
name: "*"
state: latest
update_cache: true
when: ansible_os_family == 'Debian'
- name: install required tools on SuSE
# cannot use zypper module, since it depends on python-xml
shell: "zypper -n install python-xml"
when: ansible_facts.os_family == 'Suse'
- name: install required tools on fedora
dnf:
name:
- python
- findutils
- procps-ng
when: ansible_facts.distribution == 'Fedora'
- name: install packages
pacman:
name:
- "awk"
state: present
update_cache: true
ignore_errors: true
- name: install required tools on RHEL
yum:
name:
- openssh-clients
- openssh
state: present
update_cache: true
ignore_errors: true
- name: create recursing symlink to test minimize access
shell: "rm -f /usr/bin/zzz && ln -s /usr/bin /usr/bin/zzz"
changed_when: false

View file

@ -0,0 +1,3 @@
---
roles:
- geerlingguy.git

View file

@ -0,0 +1,58 @@
---
- name: Verify
hosts: all
become: true
roles:
- geerlingguy.git
tasks:
- name: install fake SuSE-release for cinc compatibility
copy:
content: |
openSUSE Faked Enterprise 2020 (x86_64)
VERSION = 2020
CODENAME = Faked Feature
dest: /etc/SuSE-release
owner: root
group: root
mode: '0444'
when: ansible_facts.os_family == 'Suse'
- name: install git for SuSE since geerlinguy.git does not support it
zypper:
name: git
state: present
when: ansible_facts.os_family == 'Suse'
- name: Run the equivalent of "apt-get update" as a separate step
apt:
update_cache: true
when: ansible_facts.os_family == 'Debian'
- name: install required tools on debian
apt:
name: procps
when: ansible_facts.os_family == 'Debian'
- name: download cinc-auditor
get_url:
url: https://omnitruck.cinc.sh/install.sh
dest: /tmp/install.sh
mode: '0775'
- name: install cinc-auditor
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
- name: Execute cinc-auditor tests
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/linux-baseline.git"
register: test_results
changed_when: false
ignore_errors: true
- name: Display details about the cinc-auditor results
debug:
msg: "{{ test_results.stdout_lines }}"
- name: Fail when tests fail
fail:
msg: "Inspec failed to validate"
when: test_results.rc != 0

View file

@ -0,0 +1,22 @@
*******
Docker driver installation guide
*******
Requirements
============
* Docker Engine
Install
=======
Please refer to the `Virtual environment`_ documentation for installation best
practices. If not using a virtual environment, please consider passing the
widely recommended `'--user' flag`_ when invoking ``pip``.
.. _Virtual environment: https://virtualenv.pypa.io/en/latest/
.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
.. code-block:: bash
$ python3 -m pip install 'molecule[docker]'

View file

@ -0,0 +1,9 @@
---
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
hosts: all
become: true
collections:
- devsec.hardening
tasks:
- include_role:
name: ssh_hardening

View file

@ -0,0 +1,66 @@
---
dependency:
name: galaxy
options:
role-file: molecule/ssh_hardening/requirements.yml
driver:
name: docker
lint: |
yamllint roles/ssh_hardening/ molecule/ssh_hardening/ .github/workflows/ssh_hardening.yml
ansible-lint roles/ssh_hardening/
platforms:
- name: instance
image: "rndmh3ro/docker-${MOLECULE_DISTRO}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
tmpfs:
- /tmp
- /run
capabilities:
- SYS_ADMIN
tty: true
environment:
container: docker
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
callback_whitelist: profile_tasks, timer, yaml
verifier:
name: ansible
scenario:
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- destroy
test_sequence:
- dependency
- lint
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- destroy

View file

@ -0,0 +1,72 @@
---
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
hosts: all
become: true
tasks:
- name: use python3
set_fact:
ansible_python_interpreter: /usr/bin/python3
when: ansible_facts.distribution == 'Fedora'
- name: install packages
yum:
name:
- openssh-clients
- openssh-server
- libselinux-python
state: present
update_cache: true
ignore_errors: true
- name: install packages
dnf:
name:
- openssh-clients
- openssh-server
- procps-ng
state: present
update_cache: true
ignore_errors: true
- name: install packages
apt:
name:
- openssh-client
- openssh-server
state: present
update_cache: true
ignore_errors: true
- name: install required tools on SuSE
# cannot use zypper module, since it depends on python-xml
shell: "zypper -n install python-xml"
when: ansible_facts.os_family == 'Suse'
- name: install packages
zypper:
name:
- "openssh"
when: ansible_facts.os_family == 'Suse'
- name: install packages
pacman:
name:
- "openssh"
- "awk"
state: present
update_cache: true
ignore_errors: true
- name: created needed directory
file:
path: "/var/run/sshd"
state: directory
- name: create ssh host keys
command: "ssh-keygen -A"
when: not ((ansible_facts.os_family in ['Oracle Linux', 'RedHat']) and ansible_facts.distribution_major_version < '7') or
ansible_facts.distribution == "Fedora" or
ansible_facts.distribution == "Amazon" or
ansible_facts.os_family == "Suse"
changed_when: false
ignore_errors: true

View file

@ -0,0 +1,3 @@
---
roles:
- geerlingguy.git

View file

@ -0,0 +1,53 @@
---
- name: Verify
hosts: all
become: true
roles:
- geerlingguy.git
tasks:
- name: install fake SuSE-release for cinc compatibility
copy:
content: |
openSUSE Faked Enterprise 2020 (x86_64)
VERSION = 2020
CODENAME = Faked Feature
dest: /etc/SuSE-release
owner: root
group: root
mode: '0444'
when: ansible_facts.os_family == 'Suse'
- name: install git for SuSE since geerlinguy.git does not support it
zypper:
name: git
state: present
when: ansible_facts.os_family == 'Suse'
- name: install crypto compat modules on fedora
dnf:
name: libxcrypt-compat
when: ansible_facts.distribution == 'Fedora'
- name: download cinc-auditor
get_url:
url: https://omnitruck.cinc.sh/install.sh
dest: /tmp/install.sh
mode: '0775'
- name: install cinc-auditor
shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4"
- name: Execute cinc-auditor tests
command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/ssh-baseline.git"
register: test_results
changed_when: false
ignore_errors: true
- name: Display details about the cinc-auditor results
debug:
msg: "{{ test_results.stdout_lines }}"
- name: Fail when tests fail
fail:
msg: "Inspec failed to validate"
when: test_results.rc != 0

5
requirements.txt Normal file
View file

@ -0,0 +1,5 @@
molecule[docker]
yamllint
ansible-lint
docker
flake8

View file

@ -1,7 +0,0 @@
Vagrant.configure(2) do |config|
config.vm.provision "shell", inline: <<-SHELL
rpm -i http://mirror.de.leaseweb.net/epel/6/x86_64/epel-release-6-8.noarch.rpm
sed -i 's/\\(mirrorlist=http\\)s/\\1/' /etc/yum.repos.d/epel.repo
yum install -y ansible libselinux-python
SHELL
end

@ -0,0 +1 @@
Subproject commit 41bd7d7e9d169d01af9f28f11de62ae6acac38fe

1
roles/mysql_hardening Submodule

@ -0,0 +1 @@
Subproject commit 479f5c1e4a17a78361b4edae4a21b576fe8cd31d

1
roles/nginx_hardening Submodule

@ -0,0 +1 @@
Subproject commit 1e115d9eeb887a35fb1be124adbf0e1d4a6c7baf

1
roles/os_hardening Submodule

@ -0,0 +1 @@
Subproject commit 87e82cbc608a9adf5aceb145aaa9a59475b2d061

1
roles/ssh_hardening Submodule

@ -0,0 +1 @@
Subproject commit 9759c291db472331a65febd5a7089d67c7f22063

@ -0,0 +1 @@
Subproject commit 41e8a1893c7d01ab95527e37f8d527688c03953d

View file

@ -1,7 +0,0 @@
Vagrant.configure(2) do |config|
config.vm.provision "shell", inline: <<-SHELL
zypper -n install python2-setuptools
mkdir -p /usr/local/lib/python2.7/site-packages/
ln -s /usr/local/bin/pip /usr/bin/
SHELL
end

View file

@ -1,7 +0,0 @@
---
- name: remove deprecated or insecure packages | package-01 - package-09
apt:
name: '{{ os_security_packages_list }}'
state: 'absent'
purge: 'yes'
when: os_security_packages_clean | bool

View file

@ -1,14 +0,0 @@
---
- name: install auditd package | package-08
package:
name: '{{ auditd_package }}'
state: 'present'
- name: configure auditd | package-08
template:
src: 'etc/audit/auditd.conf.j2'
dest: '/etc/audit/auditd.conf'
owner: 'root'
group: 'root'
mode: '0640'

View file

@ -1,65 +0,0 @@
---
- name: Set OS family dependent variables
include_vars: '{{ ansible_facts.os_family }}.yml'
tags: always
- name: Set OS dependent variables
include_vars: '{{ item }}'
with_first_found:
- files:
- '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml'
- '{{ ansible_facts.distribution }}.yml'
- '{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml'
skip: true
tags: always
- import_tasks: auditd.yml
tags: auditd
when: os_auditd_enabled | bool
- import_tasks: limits.yml
tags: limits
- import_tasks: login_defs.yml
tags: login_defs
- import_tasks: minimize_access.yml
tags: minimize_access
- import_tasks: pam.yml
tags: pam
- import_tasks: modprobe.yml
tags: modprobe
- import_tasks: profile.yml
tags: profile
- import_tasks: securetty.yml
tags: securetty
- import_tasks: suid_sgid.yml
when: os_security_suid_sgid_enforce | bool
tags: suid_sgid
- import_tasks: sysctl.yml
tags: sysctl
- import_tasks: user_accounts.yml
tags: user_accounts
- import_tasks: rhosts.yml
tags: rhosts
- import_tasks: yum.yml
when: ansible_facts.os_family == 'RedHat'
tags: yum
- import_tasks: apt.yml
when: ansible_facts.distribution == 'Debian' or ansible_facts.distribution == 'Ubuntu'
tags: apt
- import_tasks: selinux.yml
tags: selinux
when:
- ansible_facts.selinux.status == 'enabled'

View file

@ -1,34 +0,0 @@
---
- block:
- name: create limits.d-directory if it does not exist | sysctl-31a, sysctl-31b
file:
path: '/etc/security/limits.d'
owner: 'root'
group: 'root'
mode: '0755'
state: 'directory'
- name: create additional limits config file -> 10.hardcore.conf | sysctl-31a, sysctl-31b
pam_limits:
dest: '/etc/security/limits.d/10.hardcore.conf'
domain: '*'
limit_type: hard
limit_item: core
value: '0'
comment: Prevent core dumps for all users. These are usually not needed and may contain sensitive information
- name: set 10.hardcore.conf perms to 0400 and root ownership
file:
path: /etc/security/limits.d/10.hardcore.conf
owner: 'root'
group: 'root'
mode: '0440'
when: not os_security_kernel_enable_core_dump | bool
- name: remove 10.hardcore.conf config file
file:
path: /etc/security/limits.d/10.hardcore.conf
state: absent
when: os_security_kernel_enable_core_dump | bool

View file

@ -1,8 +0,0 @@
---
- name: create login.defs | os-05, os-05b
template:
src: 'etc/login.defs.j2'
dest: '/etc/login.defs'
owner: 'root'
group: 'root'
mode: '0444'

View file

@ -1,4 +0,0 @@
---
- import_tasks: hardening.yml
when: os_hardening_enabled | bool

View file

@ -1,58 +0,0 @@
---
# If the find-task throws an error on /usr/bin/X11 like "File system loop detected"
# the other files inside /usr/bin (and all other directories) are
# still getting found and the permissions minimized in the next task.
# This is also the reason why there's ignore_errors: true on the task.
# also see: https://github.com/dev-sec/ansible-os-hardening/issues/219
- name: find files with write-permissions for group
shell: "find -L {{ item }} -perm /go+w -type f" # noqa 305
with_flattened:
- '/usr/local/sbin'
- '/usr/local/bin'
- '/usr/sbin'
- '/usr/bin'
- '/sbin'
- '/bin'
- "{{ os_env_extra_user_paths }}" # noqa 104
register: minimize_access_directories
ignore_errors: true
changed_when: false
- name: minimize access on found files
file:
path: '{{ item.1 }}'
mode: 'go-w'
state: file
with_subelements:
- "{{ minimize_access_directories.results }}"
- stdout_lines
- name: change shadow ownership to root and mode to 0600 | os-02
file:
dest: '/etc/shadow'
owner: '{{ os_shadow_perms.owner }}'
group: '{{ os_shadow_perms.group }}'
mode: '{{ os_shadow_perms.mode }}'
- name: change passwd ownership to root and mode to 0644 | os-03
file:
dest: '/etc/passwd'
owner: '{{ os_passwd_perms.owner }}'
group: '{{ os_passwd_perms.group }}'
mode: '{{ os_passwd_perms.mode }}'
- name: change su-binary to only be accessible to user and group root
file:
dest: '/bin/su'
owner: 'root'
group: 'root'
mode: '0750'
when: '"change_user" not in os_security_users_allow'
- name: set option hidepid for proc filesystem
mount:
path: /proc
src: proc
fstype: proc
opts: '{{ proc_mnt_options }}'
state: present

View file

@ -1,29 +0,0 @@
---
- name: install modprobe to disable filesystems | os-10
package:
name: '{{ modprobe_package }}'
state: 'present'
- name: check if efi is installed
stat:
path: "/sys/firmware/efi"
register: efi_installed
- name: remove vfat from fs-list if efi is used
set_fact:
os_unused_filesystems: "{{ os_unused_filesystems | difference('vfat') }}"
when: efi_installed.stat.isdir is defined and efi_installed.stat.isdir
- name: remove used filesystems from fs-list
set_fact:
os_unused_filesystems: "{{ os_unused_filesystems | difference(ansible_mounts | map(attribute='fstype') | list) }}"
# we cannot do this on el6 and below, because these systems don't support the map function
when: not ((ansible_facts.os_family in ['Oracle Linux', 'RedHat']) and ansible_facts.distribution_major_version < '7')
- name: disable unused filesystems | os-10
template:
src: 'etc/modprobe.d/modprobe.j2'
dest: '/etc/modprobe.d/dev-sec.conf'
owner: 'root'
group: 'root'
mode: '0644'

View file

@ -1,135 +0,0 @@
---
- name: update pam on Debian systems
command: 'pam-auth-update --package'
when: ansible_facts.distribution in ['Debian', 'Ubuntu']
changed_when: False
environment:
DEBIAN_FRONTEND: noninteractive
# the reason for this is so a user cannot connect to a server,
# that isn't connected to an LDAP server anymore.
# normally caching credentials shouldn't be necessary for most machines.
# removing it provides some more security while not removing usability.
- name: remove pam ccreds to disable password caching
package:
name: '{{ os_packages_pam_ccreds }}'
state: 'absent'
- name: remove pam_cracklib, because it does not play nice with passwdqc
apt:
name: '{{ os_packages_pam_cracklib }}'
state: 'absent'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- os_auth_pam_passwdqc_enable
- name: install the package for strong password checking
apt:
name: '{{ os_packages_pam_passwdqc }}'
state: 'present'
update_cache: 'yes'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- os_auth_pam_passwdqc_enable
- name: configure passwdqc
template:
src: 'usr/share/pam-configs/pam_passwdqd.j2'
dest: '{{ passwdqc_path }}'
mode: '0644'
owner: 'root'
group: 'root'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- os_auth_pam_passwdqc_enable
- name: remove passwdqc
apt:
name: '{{ os_packages_pam_passwdqc }}'
state: 'absent'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- not os_auth_pam_passwdqc_enable
- name: install tally2
apt:
name: 'libpam-modules'
state: 'present'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- not os_auth_pam_passwdqc_enable
- os_auth_retries > 0
- name: configure tally2
template:
src: 'usr/share/pam-configs/pam_tally2.j2'
dest: '{{ tally2_path }}'
mode: '0644'
owner: 'root'
group: 'root'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- not os_auth_pam_passwdqc_enable
- os_auth_retries > 0
- name: delete tally2 when retries is 0
file:
path: '{{ tally2_path }}'
state: 'absent'
when:
- ansible_facts.distribution in ['Debian', 'Ubuntu']
- not os_auth_pam_passwdqc_enable
- os_auth_retries == 0
- name: remove pam_cracklib, because it does not play nice with passwdqc
yum:
name: '{{ os_packages_pam_cracklib }}'
state: 'absent'
when:
- ansible_facts.os_family == 'RedHat'
- ansible_facts.distribution_major_version|int is version('7', '<')
- ansible_facts.distribution != 'Amazon'
- os_auth_pam_passwdqc_enable
- name: install the package for strong password checking
yum:
name: '{{ os_packages_pam_passwdqc }}'
state: 'present'
when:
- ansible_facts.os_family == 'RedHat'
- ansible_facts.distribution_major_version|int is version('7', '<')
- ansible_facts.distribution != 'Amazon'
- os_auth_pam_passwdqc_enable
- name: remove passwdqc
yum:
name: '{{ os_packages_pam_passwdqc }}'
state: 'absent'
when:
- ansible_facts.os_family == 'RedHat'
- not os_auth_pam_passwdqc_enable
- name: configure passwdqc and tally via central system-auth confic
template:
src: 'etc/pam.d/rhel_system_auth.j2'
dest: '/etc/pam.d/system-auth-ac'
mode: '0640'
owner: 'root'
group: 'root'
when: ansible_facts.os_family == 'RedHat'
- name: Gather package facts
package_facts:
manager: auto
when: ansible_facts.os_family != 'Suse'
- name: NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
template:
src: 'etc/libuser.conf.j2'
dest: '/etc/libuser.conf'
mode: '0640'
owner: 'root'
group: 'root'
when:
- ansible_facts.os_family != 'Suse'
- "'libuser' in ansible_facts.packages"

View file

@ -1,15 +0,0 @@
---
- name: add pinerolo_profile.sh to profile.d
template:
src: 'etc/profile.d/profile.conf.j2'
dest: '/etc/profile.d/pinerolo_profile.sh'
owner: 'root'
group: 'root'
mode: '0750'
when: not os_security_kernel_enable_core_dump | bool
- name: remove pinerolo_profile.sh from profile.d
file:
path: /etc/profile.d/pinerolo_profile.sh
state: absent
when: os_security_kernel_enable_core_dump | bool

View file

@ -1,23 +0,0 @@
---
- name: Get user accounts | os-09
command: "awk -F: '{print $1}' /etc/passwd"
changed_when: False
check_mode: False
register: users_accounts
- name: delete rhosts-files from system | os-09
file:
dest: '~{{ item }}/.rhosts'
state: 'absent'
with_flattened: '{{ users_accounts.stdout_lines | default([]) }}'
- name: delete hosts.equiv from system | os-01
file:
dest: '/etc/hosts.equiv'
state: 'absent'
- name: delete .netrc-files from system | os-09
file:
dest: '~{{ item }}/.netrc'
state: 'absent'
with_flattened: '{{ users_accounts.stdout_lines | default([]) }}'

View file

@ -1,8 +0,0 @@
---
- name: create securetty
template:
src: 'etc/securetty.j2'
dest: '/etc/securetty'
owner: 'root'
group: 'root'
mode: '0400'

View file

@ -1,5 +0,0 @@
---
- name: configure selinux | selinux-01
selinux:
policy: "{{ os_selinux_policy }}"
state: "{{ os_selinux_state }}"

View file

@ -1,32 +0,0 @@
---
- name: remove suid/sgid bit from binaries in blacklist | os-06
file:
path: '{{ item }}'
mode: 'a-s'
state: 'file'
follow: 'yes'
failed_when: false
with_flattened:
- '{{ os_security_suid_sgid_system_blacklist }}'
- '{{ os_security_suid_sgid_blacklist }}'
- name: find binaries with suid/sgid set | os-06
shell: find / -xdev \( -perm -4000 -o -perm -2000 \) -type f ! -path '/proc/*' -print 2>/dev/null
register: sbit_binaries
when: os_security_suid_sgid_remove_from_unknown | bool
changed_when: False
- name: gather files from which to remove suids/sgids and remove system white-listed files | os-06
set_fact:
suid: '{{ sbit_binaries.stdout_lines | difference(os_security_suid_sgid_system_whitelist) }}'
when: os_security_suid_sgid_remove_from_unknown | bool
- name: remove suid/sgid bit from all binaries except in system and user whitelist | os-06
file:
path: '{{ item }}'
mode: 'a-s'
state: 'file'
follow: 'yes'
with_flattened:
- '{{ suid | default([]) | difference(os_security_suid_sgid_whitelist) }}'
when: os_security_suid_sgid_remove_from_unknown | bool

View file

@ -1,73 +0,0 @@
---
- name: protect sysctl.conf
file:
path: '/etc/sysctl.conf'
owner: 'root'
group: 'root'
mode: '0440'
- name: set Daemon umask, do config for rhel-family | NSA 2.2.4.1
template:
src: 'etc/sysconfig/rhel_sysconfig_init.j2'
dest: '/etc/sysconfig/init'
owner: 'root'
group: 'root'
mode: '0544'
when: ansible_facts.distribution == 'RedHat' or ansible_facts.distribution == 'Fedora' or
ansible_facts.distribution == 'CentOS' or ansible_facts.distribution == 'Amazon'
- name: install initramfs-tools
apt:
name: 'initramfs-tools'
state: 'present'
update_cache: true
when: ansible_facts.os_family == 'Debian' and os_security_kernel_enable_module_loading
- name: rebuild initramfs with starting pack of modules, if module loading at runtime is disabled
template:
src: 'etc/initramfs-tools/modules.j2'
dest: '/etc/initramfs-tools/modules'
owner: 'root'
group: 'root'
mode: '0440'
notify:
- update-initramfs
when: ansible_facts.os_family == 'Debian' and os_security_kernel_enable_module_loading
register: initramfs
- name: change sysctls
block:
- name: create a combined sysctl-dict if overwrites are defined
set_fact:
sysctl_config: '{{ sysctl_config | combine(sysctl_overwrite) }}'
when: sysctl_overwrite | default()
- name: Change various sysctl-settings, look at the sysctl-vars file for documentation
sysctl:
name: '{{ item.key }}'
value: '{{ item.value }}'
sysctl_set: yes
state: present
reload: yes
ignoreerrors: yes
with_dict: '{{ sysctl_config }}'
- name: Change various sysctl-settings on rhel6-hosts or older, look at the sysctl-vars file for documentation
sysctl:
name: '{{ item.key }}'
value: '{{ item.value }}'
state: present
reload: yes
ignoreerrors: yes
with_dict: '{{ sysctl_rhel_config }}'
when: ((ansible_facts.distribution == 'RedHat' or ansible_facts.distribution == 'Fedora' or ansible_facts.distribution == 'CentOS') and
ansible_distribution_version|int is version('7', '<')) or ansible_facts.distribution == 'Amazon'
when: ansible_virtualization_type not in ['docker', 'openvz', 'lxc']
- name: Apply ufw defaults
template:
src: 'etc/default/ufw.j2'
dest: '/etc/default/ufw'
when: ufw_manage_defaults and (ansible_facts.distribution == 'Debian' or ansible_facts.distribution == 'Ubuntu')
tags: ufw

View file

@ -1,47 +0,0 @@
---
- name: get UID_MIN from login.defs
shell: awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs
args:
removes: /etc/login.defs
register: uid_min
check_mode: False
changed_when: False
- name: calculate UID_MAX from UID_MIN by substracting 1
set_fact:
uid_max: '{{ uid_min.stdout | int - 1 }}'
when: uid_min.stdout|int > 0
- name: set UID_MAX on Debian-systems if no login.defs exist
set_fact:
uid_max: '999'
when:
- ansible_facts.os_family == 'Debian'
- uid_max is not defined
- name: set UID_MAX on other systems if no login.defs exist
set_fact:
uid_max: '499'
when: uid_max is not defined
- name: get all system accounts
command: awk -F'':'' '{ if ( $3 <= {{ uid_max|quote }} ) print $1}' /etc/passwd
args:
removes: /etc/passwd
changed_when: False
check_mode: False
register: sys_accs
- name: remove always ignored system accounts from list
set_fact:
sys_accs_cond: '{{ sys_accs.stdout_lines | difference(os_always_ignore_users) }}'
check_mode: False
- name: change system accounts not on the user provided ignore-list
user:
name: '{{ item }}'
shell: '{{ os_nologin_shell_path }}'
password: '*'
createhome: False
with_flattened:
- '{{ sys_accs_cond | default([]) | difference(os_ignore_users) | list }}'

View file

@ -1,41 +0,0 @@
---
- name: remove unused repositories
file:
name: '/etc/yum.repos.d/{{ item }}.repo'
state: 'absent'
with_items:
- 'CentOS-Debuginfo'
- 'CentOS-Media'
- 'CentOS-Vault'
when: os_security_packages_clean | bool
- name: get yum-repository-files
shell: 'find /etc/yum.repos.d/ -type f -name *.repo'
changed_when: False
register: yum_repos
# for the 'default([])' see here:
# https://github.com/dev-sec/ansible-os-hardening/issues/99 and
# https://stackoverflow.com/questions/37067827/ansible-deprecation-warning-for-undefined-variable-despite-when-clause
#
# failed_when is needed because by default replace module will fail if the file doesn't exists.
# status.rc is only defined if an error accrued and only error code (rc) 257 will be ignored.
# All other errors will still be raised.
- name: activate gpg-check for config files
replace:
dest: '{{ item }}'
regexp: '^\s*gpgcheck: 0'
replace: 'gpgcheck: 1'
register: status
failed_when: status.rc is defined and status.rc != 257
with_flattened:
- '/etc/yum.conf'
- '/etc/dnf/dnf.conf'
- '{{ yum_repos.stdout_lines| default([]) }}' # noqa 104
- '/etc/yum/pluginconf.d/rhnplugin.conf'
- name: remove deprecated or insecure packages | package-01 - package-09
yum:
name: '{{ os_security_packages_list }}'
state: 'absent'
when: os_security_packages_clean | bool

View file

@ -1,30 +0,0 @@
{{ ansible_managed | comment }}
log_file = /var/log/audit/audit.log
log_format = RAW
log_group = root
priority_boost = 4
flush = INCREMENTAL
freq = 20
num_logs = 5
disp_qos = lossy
dispatcher = /sbin/audispd
name_format = NONE
##name = mydomain
max_log_file = 6
max_log_file_action = {{ os_auditd_max_log_file_action }}
space_left = 75
space_left_action = SYSLOG
action_mail_acct = root
admin_space_left = 50
admin_space_left_action = SUSPEND
disk_full_action = SUSPEND
disk_error_action = SUSPEND
##tcp_listen_port =
tcp_listen_queue = 5
tcp_max_per_addr = 1
##tcp_client_ports = 1024-65535
tcp_client_max_idle = 0
enable_krb5 = no
krb5_principal = auditd
##krb5_key_file = /etc/audit/audit.key

View file

@ -1,46 +0,0 @@
{{ ansible_managed | comment }}
# /etc/default/ufw
#
# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
IPV6={{ 'no' if sysctl_config['net.ipv6.conf.all.disable_ipv6'] is defined and sysctl_config['net.ipv6.conf.all.disable_ipv6'] == 1 else 'yes' }}
# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="{{ ufw_default_input_policy }}"
# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
# you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="{{ ufw_default_output_policy }}"
# Set the default forward policy to ACCEPT, DROP or REJECT. Please note that
# if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="{{ ufw_default_forward_policy }}"
# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please
# note that setting this to ACCEPT may be a security risk. See 'man ufw' for
# details
DEFAULT_APPLICATION_POLICY="{{ ufw_default_application_policy }}"
# By default, ufw only touches its own chains. Set this to 'yes' to have ufw
# manage the built-in chains too. Warning: setting this to 'yes' will break
# non-ufw managed firewall rules
MANAGE_BUILTINS="{{ ufw_manage_builtins }}"
#
# IPT backend
#
# only enable if using iptables backend and want to overwrite /etc/sysctl.conf
{% if ufw_ipt_sysctl == '' %}#{% endif %}IPT_SYSCTL={{ ufw_ipt_sysctl }}
# Extra connection tracking modules to load. Complete list can be found in
# net/netfilter/Kconfig of your kernel source. Some common modules:
# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support
# nf_conntrack_netbios_ns: NetBIOS (samba) client support
# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT
# nf_conntrack_ftp, nf_nat_ftp: active FTP support
# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side)
IPT_MODULES="{{ ufw_ipt_modules }}"

View file

@ -1,112 +0,0 @@
{{ ansible_managed | comment }}
# This file contains the names of kernel modules that should be loaded at boot time, one per line. Lines beginning with "#" are ignored.
#
# A list of all available kernel modules kann be found with `find /lib/modules/$(uname -r)/kernel/`
# We will sort by folder.
# Arch
# ----
#
# Modules for certains builds, contains support modules and some CPU-specific optimizations.
{% if ansible_facts.architecture == 'x86_64' %}
# Optimize for x86_64 cryptographic features
twofish-x86_64-3way
twofish-x86_64
aes-x86_64
salsa20-x86_64
blowfish-x86_64
{% endif %}
{% if 'amd' in ansible_facts.processor %}
# AMD-specific optimizations
kvm-amd
{% else %}
# Intel-specific optimizations
ghash-clmulni-intel
aesni-intel
kvm-intel
{% endif %}
kvm
# Crypto
# ------
# Some core modules which comprise strong cryptography.
blowfish_common
blowfish_generic
ctr
cts
lrw
lzo
rmd160
rmd256
rmd320
serpent
sha512_generic
twofish_common
twofish_generic
xts
zlib
# Drivers
# -------
# Basics
lp
rtc
loop
# Filesystems
ext2
btrfs
{% if os_desktop_enable %}
# Desktop
psmouse
snd
snd_ac97_codec
snd_intel8x0
snd_page_alloc
snd_pcm
snd_timer
soundcore
usbhid
{% endif %}
# Lib
# ---
xz
# Net
# ---
# All packets needed for netfilter rules (ie iptables, ebtables).
ip_tables
x_tables
iptable_filter
iptable_nat
# Targets
ipt_LOG
ipt_REJECT
# Modules
xt_connlimit
xt_tcpudp
xt_recent
xt_limit
xt_conntrack
nf_conntrack
nf_conntrack_ipv4
nf_defrag_ipv4
xt_state
nf_nat
# Addons
xt_pknock

View file

@ -1,90 +0,0 @@
{{ ansible_managed | comment }}
# See libuser.conf(5) for more information.
# Do not modify the default module list if you care about unattended calls
# to programs (i.e., scripts) working!
[import]
# Data from these files is used when libuser.conf does not define a value.
# The mapping is documented in the man page.
login_defs = /etc/login.defs
default_useradd = /etc/default/useradd
[defaults]
# The default (/usr/lib*/libuser) is usually correct
# moduledir = /your/custom/directory
# The following variables are usually imported:
# skeleton = /etc/skel
# mailspooldir = /var/mail
# NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
crypt_style = sha512
modules = files shadow
create_modules = files shadow
# modules = files shadow ldap
# create_modules = ldap
[userdefaults]
LU_USERNAME = %n
# LU_UIDNUMBER = 500
LU_GIDNUMBER = %u
# LU_USERPASSWORD = !!
# LU_GECOS = %n
# LU_HOMEDIRECTORY = /home/%n
# LU_LOGINSHELL = /bin/bash
# LU_SHADOWNAME = %n
# LU_SHADOWPASSWORD = !!
# LU_SHADOWLASTCHANGE = %d
# LU_SHADOWMIN = 0
# LU_SHADOWMAX = 99999
# LU_SHADOWWARNING = 7
# LU_SHADOWINACTIVE = -1
# LU_SHADOWEXPIRE = -1
# LU_SHADOWFLAG = -1
[groupdefaults]
LU_GROUPNAME = %n
# LU_GIDNUMBER = 500
# LU_GROUPPASSWORD = !!
# LU_MEMBERUID =
# LU_ADMINISTRATORUID =
[files]
# This is useful for the case where some master files are used to
# populate a different NSS mechanism which this workstation uses.
# directory = /etc
[shadow]
# This is useful for the case where some master files are used to
# populate a different NSS mechanism which this workstation uses.
# directory = /etc
[ldap]
# Setting these is always necessary.
# server = ldap
# basedn = dc=example,dc=com
# Setting these is rarely necessary, since it's usually correct.
# userBranch = ou=People
# groupBranch = ou=Group
# Set only if your administrative user uses simple bind operations to
# connect to the server.
# binddn = cn=Manager,dc=example,dc=com
# Set this only if the default user (as determined by SASL) is incorrect
# for SASL bind operations. Usually, it's correct, so you'll rarely need
# to set these.
# user = Manager
# authuser = Manager
[sasl]
# Set these only if your sasldb is only used by a particular application, and
# in a particular domain. The default (all applications, all domains) is
# probably correct for most installations.
# appname = imap
# domain = EXAMPLE.COM

View file

@ -1,216 +0,0 @@
{{ ansible_managed | comment }}
# Configuration control definitions for the login package.
#
# Three items must be defined: `MAIL_DIR`, `ENV_SUPATH`, and `ENV_PATH`. If unspecified, some arbitrary (and possibly incorrect) value will be assumed. All other items are optional - if not specified then the described action or option will be inhibited.
#
# Comment lines (lines beginning with `#`) and blank lines are ignored.
#
#-- Modified for Linux. --marekm
{% if os_useradd_mail_dir is defined %}
# *REQUIRED for useradd/userdel/usermod*
#
# Directory where mailboxes reside, _or_ name of file, relative to the home directory. If you _do_ define `MAIL_DIR` and `MAIL_FILE`, `MAIL_DIR` takes precedence.
# Essentially:
#
# * `MAIL_DIR` defines the location of users mail spool files (for mbox use) by appending the username to `MAIL_DIR` as defined below.
# * `MAIL_FILE` defines the location of the users mail spool files as the fully-qualified filename obtained by prepending the user home directory before `$MAIL_FILE`
#
# *NOTE*: This is no more used for setting up users MAIL environment variable which is, starting from shadow 4.0.12-1 in Debian, entirely the job of the pam_mail PAM modules.
#
# See default PAM configuration files provided for login, su, etc.
# This is a temporary situation: setting these variables will soon move to `/etc/default/useradd` and the variables will then be no more supported
MAIL_DIR {{ os_useradd_mail_dir }}
{% endif %}
{% if os_useradd_create_home is defined %}
# If useradd should create home directories for users by default
CREATE_HOME {{ 'yes' if os_useradd_create_home else 'no' }}
{% endif %}
# Enable logging and display of `/var/log/faillog` login failure info. This option conflicts with the `pam_tally` PAM module.
FAILLOG_ENAB yes
# Enable display of unknown usernames when login failures are recorded.
#
# *WARNING*: Unknown usernames may become world readable. See #290803 and #298773 for details about how this could become a security concern
LOG_UNKFAIL_ENAB no
# Enable logging of successful logins
LOG_OK_LOGINS yes
# Enable "syslog" logging of su activity - in addition to sulog file logging.
SYSLOG_SU_ENAB yes
# Enable "syslog" logging of newgrp and sg.
SYSLOG_SG_ENAB yes
# If defined, all su activity is logged to this file.
#SULOG_FILE /var/log/sulog
# If defined, file which maps tty line to `TERM` environment parameter. Each line of the file is in a format something like "vt100 tty01".
#TTYTYPE_FILE /etc/ttytype
# If defined, login failures will be logged here in a utmp format last, when invoked as lastb, will read `/var/log/btmp`, so...
FTMP_FILE /var/log/btmp
# If defined, the command name to display when running "su -". For # example, if this is defined as "su" then a "ps" will display the command is "-su". If not defined, then "ps" would display the name of the shell actually being run, e.g. something like "-sh".
SU_NAME su
# If defined, file which inhibits all the usual chatter during the login sequence. If a full pathname, then hushed mode will be enabled if the user's name or shell are found in the file. If not a full pathname, then hushed mode will be enabled if the file exists in the user's home directory.
#HUSHLOGIN_FILE /etc/hushlogins
HUSHLOGIN_FILE .hushlogin
# *REQUIRED*: The default PATH settings, for superuser and normal users. (they are minimal, add the rest in the shell startup files)
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:{{ os_env_extra_user_paths | join (':') }}
# Terminal permissions
# --------------------
# Login tty will be assigned this group ownership.
# If you have a "write" program which is "setgid" to a special group which owns the terminals, define `TTYGROUP` to the group number and `TTYPERM` to `0620`. Otherwise leave `TTYGROUP` commented out and assign `TTYPERM` to either `622` or `600`.
TTYGROUP tty
# Login tty will be set to this permission.
# In Debian `/usr/bin/bsd-write` or similar programs are setgid tty. However, the default and recommended value for `TTYPERM` is still `0600` to not allow anyone to write to anyone else console or terminal
# Users can still allow other people to write them by issuing the `mesg y` command.
TTYPERM 0600
# Login conf initializations
# --------------------------
# Terminal ERASE character ('\010' = backspace). Only used on System V.
ERASECHAR 0177
# Terminal KILL character ('\025' = CTRL/U). Only used on System V.
KILLCHAR 025
# The default umask value for `pam_umask` and is used by useradd and newusers to set the mode of the new home directories.
# If `USERGROUPS_ENAB` is set to `yes`, that will modify this `UMASK` default value for private user groups, i. e. the uid is the same as gid, and username is the same as the primary group name: for these, the user permissions will be used as group permissions, e. g. `022` will become `002`.
# Prefix these values with `0` to get octal, `0x` to get hexadecimal.
# `022` is the "historical" value in Debian for UMASK
# `027`, or even `077`, could be considered better for privacy.
UMASK {{ os_env_umask }}
# Enable setting of the umask group bits to be the same as owner bits (examples: `022` -> `002`, `077` -> `007`) for non-root users, if the uid is the same as gid, and username is the same as the primary group name.
# If set to yes, userdel will remove the user´s group if it contains no more members, and useradd will create by default a group with the name of the user.
USERGROUPS_ENAB yes
# Password aging controls
# -----------------------
# Maximum number of days a password may be used.
PASS_MAX_DAYS {{ os_auth_pw_max_age }}
# Minimum number of days allowed between password changes.
PASS_MIN_DAYS {{ os_auth_pw_min_age }}
# Number of days warning given before a password expires.
PASS_WARN_AGE 7
# Min/max values for automatic uid selection in useradd
UID_MIN {{ os_auth_uid_min }}
UID_MAX 60000
# System accounts
SYS_UID_MIN {{ os_auth_sys_uid_min }}
SYS_UID_MAX {{ os_auth_sys_uid_max }}
# Min/max values for automatic gid selection in groupadd
GID_MIN {{ os_auth_gid_min }}
GID_MAX 60000
# System accounts
SYS_GID_MIN {{ os_auth_sys_gid_min }}
SYS_GID_MAX {{ os_auth_sys_gid_max }}
# Max number of login retries if password is bad. This will most likely be overriden by PAM, since the default pam_unix module has it's own built in of 3 retries. However, this is a safe fallback in case you are using an authentication module that does not enforce PAM_MAXTRIES.
LOGIN_RETRIES {{ os_auth_retries }}
# Max time in seconds for login
LOGIN_TIMEOUT {{ os_auth_timeout }}
# Which fields may be changed by regular users using chfn - use any combination of letters "frwh" (full name, room number, work phone, home phone). If not defined, no changes are allowed.
# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
{% if os_chfn_restrict %}
CHFN_RESTRICT {{ os_chfn_restrict }}
{% endif %}
# Should login be allowed if we can't cd to the home directory?
DEFAULT_HOME {{ 'yes' if os_auth_allow_homeless else 'no' }}
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#USERDEL_CMD /usr/sbin/userdel_local
# Instead of the real user shell, the program specified by this parameter will be launched, although its visible name (`argv[0]`) will be the shell's. The program may do whatever it wants (logging, additional authentification, banner, ...) before running the actual shell.
#FAKE_SHELL /bin/fakeshell
# If defined, either full pathname of a file containing device names or a ":" delimited list of device names. Root logins will be allowed only upon these devices.
# This variable is used by login and su.
#CONSOLE /etc/consoles
#CONSOLE console:tty01:tty02:tty03:tty04
# List of groups to add to the user's supplementary group set when logging in on the console (as determined by the `CONSOLE` setting). Default is none.
# Use with caution - it is possible for users to gain permanent access to these groups, even when not logged in on the console. How to do it is left as an exercise for the reader...
# This variable is used by login and su.
#CONSOLE_GROUPS floppy:audio:cdrom
# If set to `MD5`, MD5-based algorithm will be used for encrypting password
# If set to `SHA256`, SHA256-based algorithm will be used for encrypting password
# If set to `SHA512`, SHA512-based algorithm will be used for encrypting password
# If set to `DES`, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
# Note: It is recommended to use a value consistent with
# the PAM modules configuration.
MD5_CRYPT_ENAB no
ENCRYPT_METHOD SHA512
# Only used if `ENCRYPT_METHOD` is set to `SHA256` or `SHA512`: Define the number of SHA rounds.
# With a lot of rounds, it is more difficult to brute forcing the password. But note also that it more CPU resources will be needed to authenticate users.
# If not specified, the libc will choose the default number of rounds (5000). The values must be inside the 1000-999999999 range. If only one of the MIN or MAX values is set, then this value will be used.
# If MIN > MAX, the highest value will be used.
#SHA_CRYPT_MIN_ROUNDS 5000
#SHA_CRYPT_MAX_ROUNDS 5000
# Obsoleted by PAM
# ================
# These options are now handled by PAM. Please edit the appropriate file in `/etc/pam.d/` to enable the equivelants of them.
#MOTD_FILE
#DIALUPS_CHECK_ENAB
#LASTLOG_ENAB
#MAIL_CHECK_ENAB
#OBSCURE_CHECKS_ENAB
#PORTTIME_CHECKS_ENAB
#SU_WHEEL_ONLY
#CRACKLIB_DICTPATH
#PASS_CHANGE_TRIES
#PASS_ALWAYS_WARN
#ENVIRON_FILE
#NOLOGINS_FILE
#ISSUE_FILE
#PASS_MIN_LEN
#PASS_MAX_LEN
#ULIMIT
#ENV_HZ
#CHFN_AUTH
#CHSH_AUTH
#FAIL_DELAY
# Obsoleted
# =========
# These options are no more handled by shadow.
# Shadow utilities will display a warning if they still appear.
#CLOSE_SESSIONS
#LOGIN_STRING
#NO_PASSWORD_CONSOLE
#QMAIL_DIR
# If set to `yes`, new passwords will be encrypted using the MD5-based algorithm compatible with the one used by recent releases of FreeBSD. It supports passwords of unlimited length and longer salt strings.
# Set to `no` if you need to copy encrypted passwords to other systems which don't understand the new algorithm. Default is `no`.
# This variable is deprecated. You should use ENCRYPT_METHOD.
#
#MD5_CRYPT_ENAB no

View file

@ -1,5 +0,0 @@
{{ ansible_managed | comment }}
{% for fs in os_unused_filesystems | difference(os_filesystem_whitelist) %}
install {{fs}} /bin/true
{% endfor %}

View file

@ -1,39 +0,0 @@
{{ ansible_managed | comment }}
#%PAM-1.0
{% if os_auth_retries > 0 %}
auth required pam_tally2.so deny={{ os_auth_retries }} onerr=fail unlock_time={{ os_auth_lockout_time }}
{% endif %}
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
{% if os_auth_retries > 0 %}
account required pam_tally2.so
{% endif %}
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 500 quiet
account required pam_permit.so
{% if (os_auth_pam_passwdqc_enable|bool) %}
{%- if ((ansible_facts.os_family == 'RedHat' and ansible_facts.distribution_version|int is version('7', '>=')) or ansible_facts.distribution == 'Amazon') %}
password required pam_pwquality.so {{ os_auth_pam_pwquality_options }}
{%- else %}
password requisite pam_passwdqc.so {{ os_auth_pam_passwdqc_options }}
{%- endif %}
{% else %}
password requisite pam_cracklib.so try_first_pass retry=3 type=
{% endif %}
# NSA 2.3.3.5 Upgrade Password Hashing Algorithm to SHA-512
# NSA 2.3.3.6 Limit Password Reuse
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so

View file

@ -1,4 +0,0 @@
{{ ansible_managed | comment }}
# Disable core dumps via soft limits for all users. Compliance to this setting is voluntary and can be modified by users up to a hard limit. This setting is a sane default.
ulimit -S -c 0 > /dev/null 2>&1

View file

@ -1,5 +0,0 @@
{{ ansible_managed | comment }}
# A list of TTYs, from which root can log in
# see `man securetty` for reference
{{ "\n".join(os_auth_root_ttys) }}

View file

@ -1,31 +0,0 @@
{{ ansible_managed | comment }}
# color => new RH6.0 bootup
# verbose => old-style bootup
# anything else => new style bootup without ANSI colors or positioning
BOOTUP=color
# column to start "[ OK ]" label in
RES_COL=60
# terminal sequence to move to that column. You could change this
# to something like "tput hpa ${RES_COL}" if your terminal supports it
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
# terminal sequence to set color to a 'success' color (currently: green)
SETCOLOR_SUCCESS="echo -en \\033[0;32m"
# terminal sequence to set color to a 'failure' color (currently: red)
SETCOLOR_FAILURE="echo -en \\033[0;31m"
# terminal sequence to set color to a 'warning' color (currently: yellow)
SETCOLOR_WARNING="echo -en \\033[0;33m"
# terminal sequence to reset to the default color.
SETCOLOR_NORMAL="echo -en \\033[0;39m"
# Set to anything other than 'no' to allow hotkey interactive startup...
PROMPT={{ 'yes' if (os_security_init_prompt|bool) else 'no' }}
# Set to 'yes' to allow probing for devices with swap signatures
AUTOSWAP=no
# What ttys should gettys be started on?
ACTIVE_CONSOLES=/dev/tty[1-6]
# Set to '/sbin/sulogin' to prompt for password on single-user mode
# Set to '/sbin/sushell' otherwise
SINGLE={{ '/sbin/sulogin' if os_security_init_single else '/sbin/sushell' }}
# NSA 2.2.4.1 Set Daemon umask
umask 027

View file

@ -1,9 +0,0 @@
{{ ansible_managed | comment }}
Name: passwdqc password strength enforcement
Default: yes
Priority: 1024
Conflicts: cracklib
Password-Type: Primary
Password:
requisite pam_passwdqc.so {{ os_auth_pam_passwdqc_options }}

View file

@ -1,12 +0,0 @@
{{ ansible_managed | comment }}
Name: tally2 lockout after failed attempts enforcement
Default: yes
Priority: 1024
Conflicts: cracklib
Auth-Type: Primary
Auth-Initial:
required pam_tally2.so deny={{ os_auth_retries }} onerr=fail unlock_time={{ os_auth_lockout_time }}
Account-Type: Primary
Account-Initial:
required pam_tally2.so

View file

@ -1,9 +0,0 @@
---
# system accounts that do not get their login disabled and pasword changed
os_always_ignore_users: ['root', 'sync', 'shutdown', 'halt', 'ec2-user']
sysctl_rhel_config:
# ExecShield protection against buffer overflows
kernel.exec-shield: 1
# Syncookies is used to prevent SYN-flooding attacks.
net.ipv4.tcp_syncookies: 1

View file

@ -1,37 +0,0 @@
---
os_packages_pam_ccreds: 'libpam-ccreds'
os_packages_pam_passwdqc: 'libpam-passwdqc'
os_packages_pam_cracklib: 'libpam-cracklib'
os_nologin_shell_path: '/usr/sbin/nologin'
# Different distros use different standards for /etc/shadow perms, e.g.
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: shadow
mode: '0640'
os_passwd_perms:
owner: root
group: root
mode: '0644'
os_env_umask: '027'
os_auth_uid_min: 1000
os_auth_gid_min: 1000
os_auth_sys_uid_min: 100
os_auth_sys_uid_max: 999
os_auth_sys_gid_min: 100
os_auth_sys_gid_max: 999
# defaults for useradd
os_useradd_mail_dir: /var/mail
modprobe_package: 'kmod'
auditd_package: 'auditd'
tally2_path: '/usr/share/pam-configs/tally2'
passwdqc_path: '/usr/share/pam-configs/passwdqc'

View file

@ -1,31 +0,0 @@
---
os_packages_pam_ccreds: 'pam_ccreds'
os_packages_pam_passwdqc: 'pam_passwdqc'
os_packages_pam_cracklib: 'pam_cracklib'
os_nologin_shell_path: '/sbin/nologin'
# Different distros use different standards for /etc/shadow perms, e.g.
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: '0000'
os_passwd_perms:
owner: root
group: root
mode: '0644'
os_env_umask: '027'
os_auth_uid_min: 1000
os_auth_gid_min: 1000
os_auth_sys_uid_min: 201
os_auth_sys_uid_max: 999
os_auth_sys_gid_min: 201
os_auth_sys_gid_max: 999
modprobe_package: 'module-init-tools'
auditd_package: 'audit'

View file

@ -1,28 +0,0 @@
---
os_packages_pam_ccreds: 'pam_ccreds'
os_packages_pam_passwdqc: 'pam_passwdqc'
os_packages_pam_cracklib: 'pam_cracklib'
os_nologin_shell_path: '/sbin/nologin'
# Different distros use different standards for /etc/shadow perms, e.g.
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: '0000'
os_passwd_perms:
owner: root
group: root
mode: '0644'
os_env_umask: '077'
os_auth_uid_min: 1000
os_auth_gid_min: 1000
os_auth_sys_uid_min: 201
os_auth_sys_uid_max: 999
os_auth_sys_gid_min: 201
os_auth_sys_gid_max: 999

View file

@ -1,7 +0,0 @@
---
sysctl_rhel_config:
# ExecShield protection against buffer overflows
kernel.exec-shield: 1
# Syncookies is used to prevent SYN-flooding attacks.
net.ipv4.tcp_syncookies: 1

View file

@ -1,35 +0,0 @@
---
os_packages_pam_ccreds: 'pam_ccreds'
os_packages_pam_passwdqc: 'pam_passwdqc'
os_packages_pam_cracklib: 'pam_cracklib'
os_nologin_shell_path: '/sbin/nologin'
# Different distros use different standards for /etc/shadow perms, e.g.
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: '0000'
os_passwd_perms:
owner: root
group: root
mode: '0644'
os_env_umask: '077'
os_auth_uid_min: 1000
os_auth_gid_min: 1000
os_auth_sys_uid_min: 201
os_auth_sys_uid_max: 999
os_auth_sys_gid_min: 201
os_auth_sys_gid_max: 999
# defaults for useradd
os_useradd_mail_dir: /var/spool/mail
os_useradd_create_home: true
modprobe_package: 'module-init-tools'
auditd_package: 'audit'

View file

@ -1,34 +0,0 @@
---
os_packages_pam_ccreds: 'pam_ccreds'
os_packages_pam_passwdqc: 'pam_passwdqc'
os_packages_pam_cracklib: 'cracklib'
os_nologin_shell_path: '/sbin/nologin'
# Different distros use different standards for /etc/shadow perms, e.g.
# RHEL derivatives use root:root 0000, whereas Debian-based use root:shadow 0640.
# You must provide key/value pairs for owner, group, and mode if overriding.
os_shadow_perms:
owner: root
group: root
mode: '0600'
os_passwd_perms:
owner: root
group: root
mode: '0644'
os_env_umask: '027'
os_auth_uid_min: 1000
os_auth_gid_min: 1000
os_auth_sys_uid_min: 100
os_auth_sys_uid_max: 499
os_auth_sys_gid_min: 100
os_auth_sys_gid_max: 499
# defaults for useradd
os_useradd_create_home: false
modprobe_package: 'kmod-compat'
auditd_package: 'audit'

View file

@ -1,111 +0,0 @@
# SYSTEM CONFIGURATION
# ====================
# These are not meant to be modified by the user
# suid and sgid blacklists and whitelists
# ---------------------------------------
# don't change values in the system_blacklist/whitelist
# adjust values for blacklist/whitelist instead, they can override system_blacklist/whitelist
# list of suid/sgid entries that must be removed
os_security_suid_sgid_system_blacklist:
# blacklist as provided by NSA
- '/usr/bin/rcp'
- '/usr/bin/rlogin'
- '/usr/bin/rsh'
# sshd must not use host-based authentication (see ssh cookbook)
- '/usr/libexec/openssh/ssh-keysign'
- '/usr/lib/openssh/ssh-keysign'
# misc others
- '/sbin/netreport' # not normally required for user
- '/usr/sbin/usernetctl' # modify interfaces via functional accounts
# connecting to ...
- '/usr/sbin/userisdnctl' # no isdn...
- '/usr/sbin/pppd' # no ppp / dsl ...
# lockfile
- '/usr/bin/lockfile'
- '/usr/bin/mail-lock'
- '/usr/bin/mail-unlock'
- '/usr/bin/mail-touchlock'
- '/usr/bin/dotlockfile'
# need more investigation blacklist for now
- '/usr/bin/arping'
- '/usr/sbin/uuidd'
- '/usr/bin/mtr' # investigate current state...
- '/usr/lib/evolution/camel-lock-helper-1.2' # investigate current state...
- '/usr/lib/pt_chown' # pseudo-tty needed?
- '/usr/lib/eject/dmcrypt-get-device'
- '/usr/lib/mc/cons.saver' # midnight commander screensaver
# list of suid/sgid entries that can remain untouched
os_security_suid_sgid_system_whitelist:
# whitelist as provided by NSA
- '/bin/mount'
- '/bin/ping'
- '/bin/su'
- '/usr/bin/su'
- '/bin/umount'
- '/sbin/pam_timestamp_check'
- '/sbin/unix_chkpwd'
- '/usr/bin/at'
- '/usr/bin/gpasswd'
- '/usr/bin/locate'
- '/usr/bin/newgrp'
- '/usr/bin/passwd'
- '/usr/bin/ssh-agent'
- '/usr/libexec/utempter/utempter'
- '/usr/sbin/lockdev'
- '/usr/sbin/sendmail.sendmail'
- '/usr/bin/expiry'
# whitelist ipv6
- '/bin/ping6'
- '/usr/bin/traceroute6.iputils'
# whitelist nfs
- '/sbin/mount.nfs'
- '/sbin/umount.nfs'
# whitelist nfs4
- '/sbin/mount.nfs4'
- '/sbin/umount.nfs4'
# whitelist cron
- '/usr/bin/crontab'
# whitelist consolemssaging
- '/usr/bin/wall'
- '/usr/bin/write'
# whitelist: only SGID with utmp group for multi-session access
# impact is limited; installation/usage has some remaining risk
- '/usr/bin/screen'
# whitelist locate
- '/usr/bin/mlocate'
# whitelist usermanagement
- '/usr/bin/chage'
- '/usr/bin/chfn'
- '/usr/bin/chsh'
# whitelist fuse
- '/bin/fusermount'
# whitelist pkexec
- '/usr/bin/pkexec'
# whitelist sudo
- '/usr/bin/sudo'
- '/usr/bin/sudoedit'
# whitelist postfix
- '/usr/sbin/postdrop'
- '/usr/sbin/postqueue'
# whitelist apache
- '/usr/sbin/suexec'
# whitelist squid
- '/usr/lib/squid/ncsa_auth'
- '/usr/lib/squid/pam_auth'
# whitelist kerberos
- '/usr/kerberos/bin/ksu'
# whitelist pam_caching
- '/usr/sbin/ccreds_validate'
# whitelist Xorg
- '/usr/bin/Xorg' # xorg
- '/usr/bin/X' # xorg
- '/usr/lib/dbus-1.0/dbus-daemon-launch-helper' # freedesktop ipc
- '/usr/lib/vte/gnome-pty-helper' # gnome
- '/usr/lib/libvte9/gnome-pty-helper' # gnome
- '/usr/lib/libvte-2.90-9/gnome-pty-helper' # gnome
# system accounts that do not get their login disabled and pasword changed
os_always_ignore_users: ['root', 'sync', 'shutdown', 'halt']