Initial ansible onboard

This commit is contained in:
2024-09-24 15:19:51 +02:00
parent 7366659355
commit f445996797
492 changed files with 2214589 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
name: Validate ansible playbooks
on:
pull_request:
branches:
- main
paths:
- "ansible/**"
types:
- closed
jobs:
plan:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Sectool
uses: a13labs/setup-sectool@v1
- name: Install Python and required packages
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
python3 -m pip install -r requirements.txt
- name: Setup SSH Key
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
run: |
sectool ssh unlock ansible
cp ssh-keys/ansible ~/.ssh/id_rsa
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
- name: Apply Ansible Playbook
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
ANSIBLE_USER: ${{ secrets.ANSIBLE_USER }}
ANSIBLE_HOST_KEY_CHECKING: False
run: |
cd ansible
sectool exec ansible-playbook -i inventory/hosts playbook_microk8s.yml
sectool exec ansible-playbook -i inventory/hosts playbook_gitea.yml
sectool exec ansible-playbook -i inventory/hosts playbook_nextcloud.yml
sectool exec ansible-playbook -i inventory/hosts playbook_wordpress.yml
+40
View File
@@ -0,0 +1,40 @@
name: Build and Release
on:
push:
branches:
- main
paths:
- "k8sapps/**"
jobs:
apply:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.9.6
- name: Setup Sectool
uses: a13labs/setup-sectool@v1
with:
version: 0.0.3
- name: Terraform Init
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
run: |
cd k8sapps
sectool exec terraform init
- name: Terraform Apply
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
run: |
cd k8sapps
sectool exec terraform apply --auto-approve
+40
View File
@@ -0,0 +1,40 @@
name: Validate Terraform
on:
push:
branches:
- feature/**
paths:
- "k8sapps/**"
jobs:
plan:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.9.6
- name: Setup Sectool
uses: a13labs/setup-sectool@v1
with:
version: 0.0.3
- name: Terraform Init
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
run: |
cd k8sapps
sectool exec terraform init
- name: Terraform Plan
env:
VAULT_MASTER_PASSWORD: ${{ secrets.VAULT_MASTER_PASSWORD }}
run: |
cd k8sapps
sectool exec terraform plan
+10
View File
@@ -0,0 +1,10 @@
---
exclude_paths:
- .git/
- .github/
- tests/
enable_list:
- fqcn-builtins # opt-in
warn_list:
- line-length
- yaml[line-length]
+1
View File
@@ -0,0 +1 @@
../repository.vault
+15
View File
@@ -0,0 +1,15 @@
---
extends: default
ignore: ".tox*\n.git*"
rules:
line-length:
max: 120
level: warning
comments:
min-spaces-from-content: 1
comments-indentation: false
braces:
max-spaces-inside: 1
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
+54
View File
@@ -0,0 +1,54 @@
Vagrant.require_version ">= 1.8.0"
Vagrant.configure(2) do |config|
config.vm.define "jammy.simple_server" do |web|
config.vm.box = "jaredeh/ubuntu2204-server"
config.vm.box_version = "0.1.1"
config.vm.provider :libvirt do |libvirt|
libvirt.video_type = 'vga'
libvirt.host = 'localhost'
libvirt.uri = 'qemu:///system'
libvirt.nested = false
libvirt.memory = 4096
libvirt.cpus = 4
libvirt.cpuset = '1-4,^3,6'
libvirt.cputopology :sockets => '2', :cores => '2', :threads => '1'
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbooks/simple_server.yml"
ansible.groups = { "vagrant" => ["jammy.simple_server"] }
ansible.extra_vars = {
target: "jammy.simple_server",
}
end
end
config.vm.define "jammy.virtualization_server" do |web|
config.vm.box = "jaredeh/ubuntu2204-server"
config.vm.box_version = "0.1.1"
config.vm.provider :libvirt do |libvirt|
libvirt.video_type = 'vga'
libvirt.host = 'localhost'
libvirt.uri = 'qemu:///system'
libvirt.nested = true
libvirt.memory = 4096
libvirt.cpus = 4
libvirt.cpuset = '1-4,^3,6'
libvirt.cputopology :sockets => '2', :cores => '2', :threads => '1'
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "playbooks/virtualization_server.yml"
ansible.groups = { "vagrant" => ["jammy.virtualization_server"] }
ansible.extra_vars = {
target: "jammy.virtualization_server",
}
end
end
end
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
# check if sectool is available
command -v sectool >/dev/null 2>&1 || { echo >&2 "sectool is not installed. Aborting."; exit 1; }
# check if ansible is available
command -v ansible >/dev/null 2>&1 || { echo >&2 "ansible is not installed. Aborting."; exit 1; }
# check if ansible-playbook is available
command -v ansible-playbook >/dev/null 2>&1 || { echo >&2 "ansible-playbook is not installed. Aborting."; exit 1; }
function help {
echo "Usage: $0 -d <playbook>"
echo "Options:"
echo " -d, --dry-run: Run ansible-playbook in dry run mode (don't apply changes)"
exit 1
}
# parse arguments
while [ "$1" != "" ]; do
case $1 in
-d | --dry-run ) shift
DRY_RUN="-DC"
;;
-h | --help ) help
;;
* ) PLAYBOOK=$1
break
;;
esac
done
if [ -z "$PLAYBOOK" ]; then
echo "Playbook not specified"
help
else
if [ ! -f "$PLAYBOOK" ]; then
echo "Playbook $PLAYBOOK not found"
help
fi
fi
if [ -z "$DRY_RUN" ]; then
echo "Applying playbook $PLAYBOOK"
else
echo "Dry run playbook $PLAYBOOK"
fi
# execute ansible-playbook
sectool exec ansible-playbook -i inventory/hosts $DRY_RUN $PLAYBOOK
@@ -0,0 +1,3 @@
Match User git
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /usr/local/bin/gitea-auth -u %u -t %t -k %k
+1
View File
@@ -0,0 +1 @@
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAD2EbNMt6U8KkXykm6cR9D7N6l1xjyAnN+4rzNK2PHbl0ZmrDa/4+zAjS83a5IV3+FcbdsGmBx/m+k0P/i26D5srAF6IPQpgm5bbUv0Izz2BUK7c+SILNRwovd1cYppdZnP4U670JuwmkyKOS6rmht28XmkKqVrRQLsCR7Kesa5D40JKQ==
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
NAMESPACE=gitea
PREFIX=gitea-app
# Get the list of running pod names in the given namespace and filter by prefix
POD_NAME=$(/usr/local/bin/kubectl get pods -n "$NAMESPACE" -o json | jq -r --arg PREFIX "$PREFIX" '.items[] | select(.metadata.name | startswith($PREFIX)) | select(.status.phase == "Running") | .metadata.name' | head -n 1)
# Check if a running pod matching the prefix is found
if [ -z "$POD_NAME" ]; then
exit 1
else
/usr/local/bin/kubectl exec -n "$NAMESPACE" "$POD_NAME" -i -- su -s /bin/bash git -- /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git "$@"
fi
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
NAMESPACE=gitea
PREFIX=gitea-app
# Get the list of running pod names in the given namespace and filter by prefix
POD_NAME=$(/usr/local/bin/kubectl get pods -n "$NAMESPACE" -o json | jq -r --arg PREFIX "$PREFIX" '.items[] | select(.metadata.name | startswith($PREFIX)) | select(.status.phase == "Running") | .metadata.name' | head -n 1)
# Remove the -c flag from the command
COMMAND=$(echo "$@" | sed "s/-c //g")
# Check if a running pod matching the prefix is found
if [ ! -z "$POD_NAME" ]; then
/usr/local/bin/kubectl exec -n "$NAMESPACE" "$POD_NAME" -i -- env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" su -s /bin/bash git -- $COMMAND
fi
@@ -0,0 +1,99 @@
# Hostname and other host settings
hostname: contabo01.alexpires.me
# SSH Connection and security
sshd_port: 22
ssh_allowed_networks:
- "0.0.0.0/0"
sshd_admin_net: "0.0.0.0/0"
sshd_allow_groups: "provision git users"
sshd_permit_root_login: "no"
sshd_password_authentication: "no"
sshd_allow_tcp_forwarding: "yes"
ansible_user: "{{ lookup('env', 'ANSIBLE_USER') }}"
ssh_users:
- username: operator
comment: "Managed by Ansible"
sudoer: true
pubkey: "{{ lookup('file', 'keys/operator.pub') }}"
- username: git
comment: "Managed by Ansible"
shell: "/usr/local/bin/gitea-shell"
# Due to an issue increase the number of max auth tries
sshd_max_auth_tries: 10
# Firewall ports
ufw_enable: true
fw_allowed_ports:
- { rule: "allow", port: "80", proto: "tcp" }
- { rule: "allow", port: "443", proto: "tcp" }
- { rule: "allow", port: "22", proto: "tcp" }
- { rule: "allow", port: "16443", proto: "tcp", from: "10.1.0.0/16" }
- { rule: "allow", port: "10254", proto: "tcp", from: "10.1.0.0/16" }
- { rule: "allow", port: "10254", proto: "tcp", from: "147.78.131.194" }
ufw_outgoing_traffic:
- 22 # SSH
- 53 # DNS
- 80 # HTTP
- 123 # NTP
- 443 # HTTPS
- 853 # DNS over TLS
- 10250 # Kubelet
- 16443 # Kube API Server
- 4443
- 9443
ufw_delete_unmanaged: false
ufw_default_forward_policy: "ACCEPT"
ipv4_sysctl_settings:
net.ipv4.ip_forward: 1
disable_ipv6: true
# geoip will override hosts_allow and hosts_deny (so it's disabled - CIS hardening)
custom_hosts_acls: true
# GeoIP subscription
geoip_sshd_enabled: true
ssh_allowed_zones:
- "BE"
- "PT"
# fail2ban
fail2ban_jails:
ssh:
enabled: true
port: "{{ sshd_port }}"
filter: "sshd"
logpath: "/var/log/auth.log"
maxretry: 5
findtime: 600
bantime: 3600
# Unattended upgrades
unattended_reboot: true
unattended_reboot_time: "04:30"
# Kubernetes specific settings
microk8s_alt_names: "{{ hostname }}"
k8s_version: 1.29
k8s_allowed_hosts:
- 87.67.163.177
k8s_users:
- username: operator
enabled: true
- username: git
namespace: "gitea"
enabled: true
# - username: iac
# enabled: true
# Let's encrypt issuer
issuer_email: c.alexandre.pires@alexpires.me
duo_users: ["*", "!provision", "!git"]
duo_api_hostname: api-7cda1654.duosecurity.com
+26
View File
@@ -0,0 +1,26 @@
[all]
contabo01.a13labs.pt
[a13labs]
contabo01.a13labs.pt
[vms]
contabo01.a13labs.pt
[linux]
contabo01.a13labs.pt
[ubuntu]
contabo01.a13labs.pt
[contabo]
contabo01.a13labs.pt
[gitea]
contabo01.a13labs.pt
[wordpress]
contabo01.a13labs.pt
[nextcloud]
contabo01.a13labs.pt
+70
View File
@@ -0,0 +1,70 @@
---
- name: Gitea Playbook (K8s)
hosts: gitea
gather_facts: true
# Specific tasks for this playbook
tasks:
- name: Set required facts
ansible.builtin.set_fact:
gitea_home: "/var/lib/gitea"
gitea_mysql_home: "/var/lib/mysql.gitea"
gitea_user_id: 1000
gitea_group_id: 1000
mysql_user_id: 999
mysql_group_id: 107
gitea_sshd_config: "/etc/ssh/sshd_config.d/03-gitea.conf"
gitea_scripts:
- "scripts/gitea-auth"
- "scripts/gitea-shell"
tags: always
- name: Copy local scripts to remote
become: true
ansible.builtin.copy:
src: "{{ item }}"
dest: "/usr/local/bin/{{ item | basename }}"
owner: root
group: root
mode: "0755"
loop: "{{ gitea_scripts }}"
tags:
- tasks
- tasks::scripts
- name: Copy sshd_config.d gitea files to remote
become: true
ansible.builtin.copy:
src: "configs/sshd_config.d/gitea.conf"
dest: "{{ gitea_sshd_config }}"
owner: root
group: root
mode: "0600"
tags:
- tasks
- tasks::sshd_config
- tasks::configs
- name: Create required gitea data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ gitea_home }}"
mode: "0750"
owner: "{{ gitea_user_id }}"
group: "{{ gitea_group_id }}"
tags:
- tasks
- tasks::folders
- name: Create required mysql data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ gitea_mysql_home }}"
mode: "0750"
owner: "{{ mysql_user_id }}"
group: "{{ mysql_group_id }}"
tags:
- tasks
- tasks::folders
+36
View File
@@ -0,0 +1,36 @@
---
- name: CIS Hardening
hosts: contabo
gather_facts: true
roles:
- role: "bootstrap"
tags:
- roles
- roles::bootstrap
- role: "manage_users"
tags:
- roles
- roles::users
- role: "cis_hardening"
vars:
# currently aide is failing
install_aide: false
tags:
- roles
- roles::cis
- roles::cis::ufw
- roles::cis::sysctl
- role: "fail2ban"
tags:
- roles
- roles::fail2ban
- role: "geoip"
tags:
- roles
- roles::geoip
- role: "duo_security"
tags:
- roles
- roles::duosecurity
+39
View File
@@ -0,0 +1,39 @@
---
- name: Virtualization Server
hosts: kvm
gather_facts: true
roles:
- role: "bootstrap"
tags:
- roles
- roles::bootstrap
- role: "manage_users"
tags:
- roles
- roles::users
- role: "cis_hardening"
vars:
# currently aide is failing
install_aide: false
tags:
- roles
- roles::cis
- roles::cis::ufw
- roles::cis::sysctl
- role: "fail2ban"
tags:
- roles
- roles::fail2ban
- role: "geoip"
tags:
- roles
- roles::geoip
- role: "duo_security"
tags:
- roles
- roles::duosecurity
- role: "virtualization"
tags:
- role::virtualization
+38
View File
@@ -0,0 +1,38 @@
---
- name: Microk8s Setup
hosts: microk8s
gather_facts: true
roles:
- role: "bootstrap"
tags:
- roles
- roles::bootstrap
- role: "manage_users"
tags:
- roles
- roles::users
- role: "cis_hardening"
vars:
# currently aide is failing
install_aide: false
tags:
- roles
- roles::cis
- roles::cis::ufw
- roles::cis::sysctl
- role: "fail2ban"
tags:
- roles
- roles::fail2ban
- role: "geoip"
tags:
- roles
- roles::geoip
- role: "duo_security"
tags:
- roles
- roles::duosecurity
- role: "microk8s"
tags:
- role::microk8s
+40
View File
@@ -0,0 +1,40 @@
---
- name: Nextcloud Playbook (K8s)
hosts: nextcloud
gather_facts: true
# Specific tasks for this playbook
tasks:
- name: Set required facts
ansible.builtin.set_fact:
nextcloud_home: "/var/lib/nextcloud"
nextcloud_mysql_home: "/var/lib/mysql.nextcloud"
nextcloud_user_id: 33
nextcloud_group_id: 26
mysql_user_id: 999
mysql_group_id: 107
tags: always
- name: Create required nextcloud data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ nextcloud_home }}"
mode: "0750"
owner: "{{ nextcloud_user_id }}"
group: "{{ nextcloud_group_id }}"
tags:
- tasks
- tasks::folders
- name: Create required mysql data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ nextcloud_mysql_home }}"
mode: "0750"
owner: "{{ mysql_user_id }}"
group: "{{ mysql_group_id }}"
tags:
- tasks
- tasks::folders
+40
View File
@@ -0,0 +1,40 @@
---
- name: Wordpress Playbook (K8s)
hosts: wordpress
gather_facts: true
# Specific tasks for this playbook
tasks:
- name: Set required facts
ansible.builtin.set_fact:
wordpress_home: "/var/lib/wordpress"
wordpress_mysql_home: "/var/lib/mysql.wordpress"
wordpress_user_id: 33
wordpress_group_id: 26
mysql_user_id: 999
mysql_group_id: 107
tags: always
- name: Create required wordpress data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ wordpress_home }}"
mode: "0750"
owner: "{{ wordpress_user_id }}"
group: "{{ wordpress_group_id }}"
tags:
- tasks
- tasks::folders
- name: Create required mysql data folder
become: true
ansible.builtin.file:
state: directory
path: "{{ wordpress_mysql_home }}"
mode: "0750"
owner: "{{ mysql_user_id }}"
group: "{{ mysql_group_id }}"
tags:
- tasks
- tasks::folders
+5
View File
@@ -0,0 +1,5 @@
---
collections:
- ansible.posix
- community.general
- community.libvirt
+10
View File
@@ -0,0 +1,10 @@
---
exclude_paths:
- .git/
- .github/
- tests/
enable_list:
- fqcn-builtins # opt-in
warn_list:
- line-length
- yaml[line-length]
+15
View File
@@ -0,0 +1,15 @@
---
extends: default
ignore: ".tox*\n.git*"
rules:
line-length:
max: 120
level: warning
comments:
min-spaces-from-content: 1
comments-indentation: false
braces:
max-spaces-inside: 1
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
+130
View File
@@ -0,0 +1,130 @@
---
- name: Check if we're using the default SSH port
ansible.builtin.wait_for:
port: 22
state: started
host: "{{ ansible_ssh_host }}"
connect_timeout: 5
timeout: 10
register: default_ssh
ignore_errors: true
ignore_unreachable: true
- name: Check custom SSH port
when: sshd_port is defined
block:
- name: Change to port '{{ sshd_port }}'
ansible.builtin.set_fact:
ansible_port: "{{ sshd_port }}"
- name: Check if we're using the SSH port '{{ sshd_port }}'
ansible.builtin.wait_for:
port: "{{ sshd_port }}"
state: started
host: "{{ ansible_ssh_host }}"
connect_timeout: 5
timeout: 10
ignore_errors: true
register: configured_ssh
ignore_unreachable: true
- name: Set inventory ansible_port to default
ansible.builtin.set_fact:
ansible_port: 22
when: default_ssh is defined
and default_ssh.state | d() == "started"
register: sshd_port_set
- name: SSH is properly configured at port '{{ sshd_port }}'
ansible.builtin.set_fact:
ansible_port: "{{ sshd_port }}"
when: configured_ssh is defined
and configured_ssh.state is defined
and configured_ssh.state | d() == "started"
register: sshd_port_set
- name: Configure custom SSH port
when: sshd_port is defined
and default_ssh is defined
and default_ssh.state | d() == "started"
block:
- name: Changing default ssh port to '{{ sshd_port }}'
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
regexp: '^Port\s'
line: "Port {{ sshd_port }}"
state: present
register: sshd_port_config
- name: Force sshd to restart # noqa no-handler
when: sshd_port_config.changed
become: true
ansible.builtin.service:
name: ssh
state: restarted
- name: Change to port '{{ sshd_port }}' # noqa no-handler
when: sshd_port_config.changed
ansible.builtin.set_fact:
ansible_port: "{{ sshd_port }}"
- name: Check if we're using the SSH port '{{ sshd_port }}' # noqa no-handler
when: sshd_port_config.changed
ansible.builtin.wait_for:
port: "{{ sshd_port }}"
state: started
host: "{{ ansible_ssh_host }}"
connect_timeout: 5
timeout: 10
ignore_errors: true
register: configured_ssh
- name: SSH is properly configured at port '{{ sshd_port }}'
when: sshd_port_config.changed
and configured_ssh is defined
and configured_ssh.state is defined
and configured_ssh.state | d() == "started"
ansible.builtin.set_fact:
ansible_port: "{{ sshd_port }}"
register: sshd_port_set
- name: Fail if SSH port was not auto-detected (unknown)
ansible.builtin.fail:
msg: "Host was unreachable! Check ssh port!"
when: sshd_port_set is undefined
- name: Confirm host connection works
ansible.builtin.ping:
- name: Run deferred setup to gather facts
ansible.builtin.setup:
- name: Setting hostname '{{ hostname }}'
become: true
ansible.builtin.hostname:
name: "{{ hostname }}"
- name: Update Package Cache (apt/Ubuntu)
become: true
tags: always
ansible.builtin.apt:
update_cache: true
changed_when: false
when: ansible_distribution == "Ubuntu"
- name: Update Package Cache (dnf/CentOS)
become: true
tags: always
ansible.builtin.dnf:
update_cache: true
changed_when: false
when: ansible_distribution == "CentOS"
- name: Update Package Cache (yum/Amazon)
become: true
tags: always
ansible.builtin.dnf:
update_cache: true
changed_when: false
when: ansible_distribution == "Amazon"
+12
View File
@@ -0,0 +1,12 @@
---
exclude_paths:
- .git/
- .github/
- tests/
enable_list:
- fqcn-builtins # opt-in
warn_list:
- line-length
- yaml[line-length]
skip_list:
- yaml[comments]
+15
View File
@@ -0,0 +1,15 @@
---
extends: default
ignore: ".tox*\n.git*"
rules:
line-length:
max: 290
level: warning
comments:
min-spaces-from-content: 1
comments-indentation: false
braces:
max-spaces-inside: 1
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true
@@ -0,0 +1,15 @@
---
auditd_apply_audit_rules: true
auditd_action_mail_acct: root
auditd_admin_space_left_action: suspend
auditd_disk_error_action: suspend
auditd_disk_full_action: suspend
auditd_max_log_file: 8
auditd_max_log_file_action: keep_logs
auditd_mode: 1
auditd_num_logs: 5
auditd_space_left: 75
auditd_space_left_action: email
grub_audit_backlog_cmdline: audit_backlog_limit=8192
grub_audit_cmdline: audit=1
...
@@ -0,0 +1,13 @@
---
compilers:
- as
- cargo
- cc
- cc-[0-9]*
- clang-[0-9]*
- gcc
- gcc-[0-9]*
- go
- make
- rustc
...
@@ -0,0 +1,3 @@
---
disable_wireless: false
...
@@ -0,0 +1,6 @@
---
dns: 127.0.0.1 1.1.1.1
fallback_dns: 9.9.9.9 1.0.0.1
dnssec: allow-downgrade
dns_over_tls: opportunistic
...
@@ -0,0 +1,6 @@
---
disable_ipv6: false
ipv6_disable_sysctl_settings:
net.ipv6.conf.all.disable_ipv6: 1
net.ipv6.conf.default.disable_ipv6: 1
...
@@ -0,0 +1,6 @@
---
limit_nofile_hard: 1024
limit_nofile_soft: 512
limit_nproc_hard: 1024
limit_nproc_soft: 512
...
@@ -0,0 +1,13 @@
---
install_aide: true
reboot_ubuntu: false
redhat_signing_keys:
- 567E347AD0044ADE55BA8A5F199E2F91FD431D51
- 47DB287789B21722B6D95DDE5326810137017186
epel7_signing_keys:
- 91E97D7C4A5E96F17F3E888F6A2FAEA2352C64E5
epel8_signing_keys:
- 94E279EB8D8F25B21810ADF121EA45AB2F86D6A1
epel9_signing_keys:
- FF8AD1344597106ECE813B918A3872BF3228467C
...
@@ -0,0 +1,35 @@
---
block_blacklisted: false
fs_modules_blocklist:
- cramfs
- freevxfs
- hfs
- hfsplus
- jffs2
- squashfs
- udf
misc_modules_blocklist:
- bluetooth
- bnep
- btusb
- can
- cpia2
- firewire-core
- floppy
- ksmbd
- n_hdlc
- net-pf-31
- pcspkr
- soundcore
- thunderbolt
- usb-midi
- usb-storage
- uvcvideo
- v4l2_common
net_modules_blocklist:
- atm
- dccp
- sctp
- rds
- tipc
...
@@ -0,0 +1,4 @@
---
hide_pid: 2
process_group: root
...
@@ -0,0 +1,4 @@
---
fallback_ntp: 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org
ntp: 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org
...
@@ -0,0 +1,71 @@
---
system_upgrade: true
packages_blocklist:
- apport*
- autofs
- avahi*
- avahi-*
- beep
- git
- pastebinit
- popularity-contest
- prelink
- rpcbind
- rsh*
- rsync
- talk*
- telnet*
- tftp*
- tuned
- whoopsie
- xinetd
- yp-tools
- ypbind
packages_debian:
- acct
- apparmor-profiles
- apparmor-utils
- apt-show-versions
- audispd-plugins
- auditd
- cracklib-runtime
- debsums
- gnupg2
- haveged
- libpam-apparmor
- libpam-cap
- libpam-modules
- libpam-pwquality
- libpam-tmpdir
- lsb-release
- needrestart
- openssh-server
- postfix
- rkhunter
- rsyslog
- sysstat
- tcpd
- vlock
- wamerican
packages_redhat:
- audispd-plugins
- audit
- cracklib
- gnupg2
- haveged
- libpwquality
- openssh-server
- needrestart
- postfix
- psacct
- rkhunter
- rsyslog
- rsyslog-gnutls
- vlock
- words
packages_ubuntu:
- fwupd
- secureboot-db
unattended_reboot: true
unattended_reboot_time: "04:00"
...
@@ -0,0 +1,15 @@
---
crypto_policy: "DEFAULT:NO-SHA1"
pwquality_config:
dcredit: -1
dictcheck: 1
difok: 8
enforcing: 1
lcredit: -1
maxclassrepeat: 4
maxrepeat: 3
minclass: 4
minlen: 15
ocredit: -1
ucredit: -1
...
@@ -0,0 +1,43 @@
---
sshd_accept_env: LANG LC_*
ssh_allowed_networks:
- 192.168.0.0/24
- 192.168.1.0/24
sshd_allow_agent_forwarding: "no"
sshd_allow_groups: sudo
sshd_allow_tcp_forwarding: "no"
sshd_authentication_methods: any
sshd_banner: /etc/issue.net
sshd_challenge_response_authentication: "no"
sshd_ciphers: chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr
sshd_client_alive_count_max: 1
sshd_client_alive_interval: 200
sshd_compression: "no"
sshd_gssapi_authentication: "no"
sshd_hostbased_authentication: "no"
sshd_host_key_algorithms: ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256
sshd_ignore_user_known_hosts: "yes"
sshd_kerberos_authentication: "no"
sshd_kex_algorithms: curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
sshd_login_grace_time: 20
sshd_log_level: VERBOSE
sshd_macs: hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
sshd_max_auth_tries: 3
sshd_max_sessions: 3
sshd_max_startups: 10:30:60
sshd_password_authentication: "no"
sshd_permit_empty_passwords: "no"
sshd_permit_root_login: "no"
sshd_permit_user_environment: "no"
sshd_port: 22
sshd_print_last_log: "yes"
sshd_print_motd: "no"
sshd_rekey_limit: 512M 1h
sshd_required_rsa_size: 2048
sshd_strict_modes: "yes"
sshd_subsystem: sftp internal-sftp
sshd_tcp_keep_alive: "no"
sshd_use_dns: "no"
sshd_use_pam: "yes"
sshd_x11_forwarding: "no"
custom_hosts_acls: false
@@ -0,0 +1,390 @@
---
suid_sgid_permissions: true
suid_sgid_blocklist:
- 7z
- ab
- agetty
- alpine
- ansible-playbook
- aoss
- apt
- apt-get
- ar
- aria2c
- arj
- arp
- as
- ascii-xfr
- ascii85
- ash
- aspell
- at
- atobm
- awk
- aws
- base32
- base58
- base64
- basenc
- basez
- bash
- batcat
- bc
- bconsole
- bpftrace
- bridge
- bsd-write
- bundle
- bundler
- busctl
- busybox
- byebug
- bzip2
- c89
- c99
- cabal
- cancel
- capsh
- cat
- cdist
- certbot
- chage
- check_by_ssh
- check_cups
- check_log
- check_memory
- check_raid
- check_ssl_cert
- check_statusfile
- chfn
- chmod
- choom
- chown
- chroot
- chsh
- cmp
- cobc
- column
- comm
- composer
- cowsay
- cowthink
- cp
- cpan
- cpio
- cpulimit
- crash
- crontab
- csh
- csplit
- csvtool
- cupsfilter
- curl
- cut
- dash
- date
- dd
- debugfs
- dialog
- diff
- dig
- distcc
- dmesg
- dmidecode
- dmsetup
- dnf
- docker
- dosbox
- dpkg
- dstat
- dvips
- easy_install
- eb
- ed
- efax
- emacs
- env
- eqn
- espeak
- ex
- exiftool
- expand
- expect
- facter
- file
- find
- finger
- fish
- flock
- fmt
- fold
- fping
- ftp
- fusermount
- gawk
- gcc
- gcloud
- gcore
- gdb
- gem
- genie
- genisoimage
- ghc
- ghci
- gimp
- ginsh
- git
- grc
- grep
- gtester
- gzip
- hd
- head
- hexdump
- highlight
- hping3
- iconv
- iftop
- install
- ionice
- ip
- irb
- ispell
- jjs
- joe
- join
- journalctl
- jq
- jrunscript
- jtag
- knife
- ksh
- ksshell
- ksu
- kubectl
- latex
- latexmk
- ld.so
- ldconfig
- less
- lftp
- ln
- loginctl
- logsave
- look
- lp
- ltrace
- lua
- lualatex
- luatex
- lwp-download
- lwp-request
- mail
- make
- man
- mawk
- mksh
- mksh-static
- mlocate
- more
- mosquitto
- mount
- mount.nfs
- msfconsole
- msgattrib
- msgcat
- msgconv
- msgfilter
- msgmerge
- msguniq
- mtr
- multitime
- mv
- mysql
- nano
- nasm
- nawk
- nc
- neofetch
- netfilter-persistent
- newgrp
- nft
- nice
- nl
- nm
- nmap
- node
- nohup
- npm
- nroff
- nsenter
- ntfs-3g
- octave
- od
- openssl
- openvpn
- openvt
- opkg
- pandoc
- paste
- pax
- pdb
- pdflatex
- pdftex
- perf
- perl
- perlbug
- pexec
- pg
- php
- pic
- pico
- pidstat
- ping
- ping6
- pip
- pkexec
- pkg
- posh
- pppd
- pr
- pry
- psad
- psftp
- psql
- ptx
- puppet
- python
- rake
- rbash
- readelf
- red
- redcarpet
- redis
- restic
- rev
- rlogin
- rlwrap
- rpm
- rpmdb
- rpmquery
- rpmverify
- rsync
- rtorrent
- ruby
- run-mailcap
- run-parts
- rview
- rvim
- sash
- scanmem
- scp
- screen
- script
- scrot
- sed
- service
- setarch
- setfacl
- setlock
- sftp
- sg
- sh
- shuf
- slsh
- smbclient
- snap
- socat
- socket
- soelim
- softlimit
- sort
- split
- sqlite3
- sqlmap
- ss
- ssh
- ssh-keygen
- ssh-keyscan
- sshpass
- start-stop-daemon
- stdbuf
- strace
- strings
- su
- sysctl
- systemctl
- systemd-resolve
- tac
- tail
- tar
- task
- taskset
- tasksh
- tbl
- tclsh
- tcpdump
- tcsh
- tee
- telnet
- tex
- tftp
- tic
- time
- timedatectl
- timeout
- tmate
- tmux
- top
- torify
- torsocks
- traceroute6.iputils
- troff
- tshark
- ul
- umount
- unexpand
- uniq
- unshare
- unzip
- update-alternatives
- uudecode
- uuencode
- valgrind
- vi
- view
- vigr
- vim
- vimdiff
- vipw
- virsh
- volatility
- w3m
- wall
- watch
- wc
- wget
- whiptail
- whois
- wireshark
- wish
- write
- xargs
- xdotool
- xelatex
- xetex
- xmodmap
- xmore
- xpad
- xxd
- xz
- yarn
- yash
- yelp
- yum
- zathura
- zip
- zsh
- zsoelim
- zypper
...
@@ -0,0 +1,69 @@
---
sysctl_dev_tty_ldisc_autoload: 0
sysctl_net_ipv6_conf_accept_ra_rtr_pref: 0
ipv4_sysctl_settings:
net.ipv4.conf.all.accept_redirects: 0
net.ipv4.conf.all.accept_source_route: 0
net.ipv4.conf.all.log_martians: 1
net.ipv4.conf.all.rp_filter: 1
net.ipv4.conf.all.secure_redirects: 0
net.ipv4.conf.all.send_redirects: 0
net.ipv4.conf.all.shared_media: 0
net.ipv4.conf.default.accept_redirects: 0
net.ipv4.conf.default.accept_source_route: 0
net.ipv4.conf.default.log_martians: 1
net.ipv4.conf.default.rp_filter: 1
net.ipv4.conf.default.secure_redirects: 0
net.ipv4.conf.default.send_redirects: 0
net.ipv4.conf.default.shared_media: 0
net.ipv4.icmp_echo_ignore_broadcasts: 1
net.ipv4.icmp_ignore_bogus_error_responses: 1
net.ipv4.ip_forward: 0
net.ipv4.tcp_challenge_ack_limit: 2147483647
net.ipv4.tcp_invalid_ratelimit: 500
net.ipv4.tcp_max_syn_backlog: 20480
net.ipv4.tcp_rfc1337: 1
net.ipv4.tcp_syn_retries: 5
net.ipv4.tcp_synack_retries: 2
net.ipv4.tcp_syncookies: 1
ipv6_sysctl_settings:
net.ipv6.conf.all.accept_ra: 0
net.ipv6.conf.all.accept_redirects: 0
net.ipv6.conf.all.accept_source_route: 0
net.ipv6.conf.all.forwarding: 0
net.ipv6.conf.all.use_tempaddr: 2
net.ipv6.conf.default.accept_ra: 0
net.ipv6.conf.default.accept_ra_defrtr: 0
net.ipv6.conf.default.accept_ra_pinfo: 0
net.ipv6.conf.default.accept_ra_rtr_pref: 0
net.ipv6.conf.default.accept_redirects: 0
net.ipv6.conf.default.accept_source_route: 0
net.ipv6.conf.default.autoconf: 0
net.ipv6.conf.default.dad_transmits: 0
net.ipv6.conf.default.max_addresses: 1
net.ipv6.conf.default.router_solicitations: 0
net.ipv6.conf.default.use_tempaddr: 2
generic_sysctl_settings:
fs.protected_fifos: 2
fs.protected_hardlinks: 1
fs.protected_symlinks: 1
fs.suid_dumpable: 0
kernel.core_uses_pid: 1
kernel.dmesg_restrict: 1
kernel.kptr_restrict: 2
kernel.panic: 60
kernel.panic_on_oops: 60
kernel.perf_event_paranoid: 3
kernel.randomize_va_space: 2
kernel.sysrq: 0
kernel.unprivileged_bpf_disabled: 1
kernel.yama.ptrace_scope: 2
net.core.bpf_jit_harden: 2
conntrack_sysctl_settings:
net.netfilter.nf_conntrack_max: 2000000
net.netfilter.nf_conntrack_tcp_loose: 0
...
@@ -0,0 +1,16 @@
---
ufw_enable: true
ufw_outgoing_traffic:
- 22
- 53
- 80
- 123
- 443
- 853
fw_allowed_ports: []
ufw_default_forward_policy: DROP
ufw_incoming_devices: []
ufw_outgoing_devices: []
fw_loopback_traffic_deny: true
ufw_delete_unmanaged: true
@@ -0,0 +1,2 @@
---
umask_value: "077"
@@ -0,0 +1,10 @@
---
delete_users:
- games
- gnats
- irc
- list
- news
- sync
- uucp
...
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,156 @@
---
- name: Restart Debian auditd
become: true
ansible.builtin.service:
name: auditd
state: restarted
when: ansible_os_family == "Debian"
tags:
- CCE-80872-5
# https://github.com/ansible/ansible/issues/22171
- name: Restart RedHat auditd # noqa command-instead-of-module no-changed-when
become: true
ansible.builtin.command: service auditd restart
when: ansible_os_family == "RedHat"
tags:
- CCE-80872-5
- name: Generate auditd rules # noqa no-changed-when
become: true
ansible.builtin.command: augenrules
- name: Restart sysctl
become: true
ansible.builtin.service:
name: systemd-sysctl
state: restarted
- name: Reload systemd
become: true
ansible.builtin.systemd:
daemon_reload: true
- name: Run rkhunter propupd # noqa no-changed-when
become: true
ansible.builtin.command: rkhunter --propupd
- name: Enable aidecheck
become: true
ansible.builtin.systemd:
name: aidecheck.timer
enabled: true
state: started
- name: Disable aidecheck
become: true
ansible.builtin.systemd:
name: aidecheck.timer
state: stopped
enabled: false
- name: Mask aidecheck
become: true
ansible.builtin.systemd:
name: aidecheck.timer
masked: true
state: stopped
enabled: false
- name: Restart ssh service
become: true
ansible.builtin.service:
name: ssh
state: restarted
register: ssh_service
failed_when: ssh_service is not success and not 'Could not find the requested service' in ssh_service.msg
- name: Restart sshd service
become: true
ansible.builtin.service:
name: sshd
state: restarted
register: sshd_service
failed_when: sshd_service is not success and not 'Could not find the requested service' in sshd_service.msg
- name: Restart Postfix
become: true
ansible.builtin.service:
name: postfix
state: restarted
- name: Run apt-get autoremove
become: true
ansible.builtin.apt:
autoremove: true
- name: Run apt-get clean
become: true
ansible.builtin.apt:
autoclean: true
clean: true
- name: Mask apport
become: true
ansible.builtin.systemd:
name: apport.service
masked: true
enabled: false
state: stopped
- name: Mask motdnews timer
become: true
ansible.builtin.systemd:
name: motd-news.timer
masked: true
enabled: false
state: stopped
- name: Mask motdnews service
become: true
ansible.builtin.systemd:
name: motd-news.service
masked: true
enabled: false
state: stopped
- name: Run dnf autoremove
ansible.builtin.dnf:
autoremove: true
when: ansible_os_family == "RedHat"
tags:
- dnf
- packages
- name: Enable haveged
become: true
ansible.builtin.systemd:
name: haveged
enabled: true
state: started
- name: Reboot node
become: true
ansible.builtin.reboot:
pre_reboot_delay: "{{ 3600 | random(start=1) }}"
- name: Update Debian cracklib # noqa no-changed-when
become: true
ansible.builtin.shell: |
update-cracklib
when: ansible_os_family == "Debian"
- name: Update RedHat cracklib # noqa no-changed-when
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
become: true
ansible.builtin.command: create-cracklib-dict /usr/share/dict/*
when: ansible_os_family == "RedHat"
- name: Update GRUB # noqa no-changed-when
become: true
ansible.builtin.command: update-grub
- name: Update GRUB2 # noqa no-changed-when
become: true
ansible.builtin.command: grub2-mkconfig
@@ -0,0 +1,8 @@
---
- name: Converge
hosts: all
any_errors_fatal: true
tasks:
- name: "Include cis_hardening"
ansible.builtin.include_role:
name: "cis_hardening"
@@ -0,0 +1,89 @@
---
dependency:
name: galaxy
enabled: true
driver:
name: vagrant
provider:
name: libvirt
provisioner:
name: ansible
config_options:
defaults:
callbacks_enabled: profile_tasks
log: true
inventory:
host_vars:
jammy:
disable_wireless: true
ssh_allowed_networks: "0.0.0.0/0"
sshd_allow_groups: "vagrant sudo"
suid_sgid_permissions: false
platforms:
- name: jammy
box: "jaredeh/ubuntu2204-server"
box_version: "0.1.1"
interfaces:
- auto_config: true
network_name: private_network
type: dhcp
instance_raw_config_args:
# use single quotes to avoid YAML parsing as dict due to ':'
- 'vm.synced_folder ".", "/vagrant", type: "rsync"'
# Run 'uname' a provisionning step **needs 'provision: true' to work**
- 'vm.provision :shell, inline: "uname"'
# Dictionary of `config` options. Note that string values need to be
# explicitly enclosed in quotes.
config_options:
vm.boot_timeout: 600
ssh.keep_alive: true
ssh.remote_user: 'ansible'
synced_folder: true
provider_options:
video_type: 'vga'
host: 'localhost'
uri: 'qemu:///system'
memory: 4096
verifier:
name: ansible
lint: |
set -e
ansible-lint
scenario:
name: default
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- dependency
- cleanup
- destroy
test_sequence:
- dependency
- lint
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy
@@ -0,0 +1,753 @@
---
- name: Verify
hosts: all
any_errors_fatal: true
tasks:
- name: Reboot host
become: true
ansible.builtin.reboot:
- name: Wait for the host and reconnect
ansible.builtin.wait_for:
port: 22
host: '{{ (ansible_ssh_host | default(ansible_host)) | default(inventory_hostname) }}'
delay: 10
timeout: 120
- name: Include default vars
ansible.builtin.include_vars:
dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/defaults/"
extensions:
- 'yml'
- name: Include host vars
ansible.builtin.include_vars:
file: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/host_vars/{{ ansible_hostname }}"
- name: Set sysctl configuration directory as fact
tags:
- fact
- sysctl
block:
- name: Stat /usr/lib/sysctl.d/ exists
ansible.builtin.stat:
path: "/usr/lib/sysctl.d/"
register: usr_lib_sysctl_d
- name: Set sysctl fact
ansible.builtin.set_fact:
sysctl_conf_dir: "{{ '/usr/lib/sysctl.d' if usr_lib_sysctl_d.stat.exists else '/etc/sysctl.d' }}"
- name: Debug sysctl
ansible.builtin.debug:
msg: "{{ sysctl_conf_dir }}"
- name: Get installed ssh version
ansible.builtin.command:
cmd: ssh -V
changed_when: false
failed_when: false
register: ssh_version
tags:
- sshd
- sshd_config
- name: Set ssh version as fact
ansible.builtin.set_fact:
ssh_installed_version: "{{ ssh_version.stderr | regex_search('^OpenSSH_([0-9+].[0-9]+)', '\\1') | join('.') | float }}" # noqa jinja[spacing]
tags:
- sshd
- sshd_config
- name: Stat IPv6 status
become: true
ansible.builtin.stat:
path: /proc/sys/net/ipv6
register: stat_ipv6
- name: Set IPv6 fact
ansible.builtin.set_fact:
system_has_ipv6: "{{ stat_ipv6.stat.exists }}"
- name: Update current facts
ansible.builtin.setup: ~
- name: Verify auditd configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/audit/auditd.conf
line: "{{ item }}"
state: present
check_mode: true
register: auditd_conf
failed_when: auditd_conf is changed
with_items:
- action_mail_acct = {{ auditd_action_mail_acct }}
- admin_space_left_action = {{ auditd_admin_space_left_action }}
- disk_error_action = {{ auditd_disk_error_action }}
- disk_full_action = {{ auditd_disk_full_action }}
- max_log_file = {{ auditd_max_log_file }}
- max_log_file_action = {{ auditd_max_log_file_action }}
- name_format = hostname
- num_logs = {{ auditd_num_logs }}
- space_left = {{ auditd_space_left }}
- space_left_action = {{ auditd_space_left_action }}
- name: Verify systemd system.conf
become: true
ansible.builtin.lineinfile:
dest: /etc/systemd/system.conf
line: "{{ item }}"
state: present
check_mode: true
register: systemd_system_conf
failed_when: systemd_system_conf is changed
with_items:
- DumpCore=no
- CrashShell=no
- CtrlAltDelBurstAction=none
- DefaultLimitCORE=0
- DefaultLimitNOFILE={{ limit_nofile_hard }}
- DefaultLimitNPROC={{ limit_nproc_hard }}
- name: Verify systemd user.conf
become: true
ansible.builtin.lineinfile:
dest: /etc/systemd/user.conf
line: "{{ item }}"
state: present
check_mode: true
register: systemd_user_conf
failed_when: systemd_user_conf is changed
with_items:
- DefaultLimitCORE=0
- DefaultLimitNOFILE={{ limit_nofile_hard }}
- DefaultLimitNPROC={{ limit_nproc_hard }}
- name: Verify postfix configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/postfix/main.cf
line: "{{ item }}"
state: present
check_mode: true
register: postfix_conf
failed_when: postfix_conf is changed
with_items:
- disable_vrfy_command = yes
- inet_interfaces = loopback-only
- smtpd_banner = \$myhostname - ESMTP
- smtpd_client_restrictions = permit_mynetworks,reject
- name: Stat /etc/ssh/sshd_config
ansible.builtin.stat:
path: '/etc/ssh/sshd_config'
register: sshd_config_file
- name: Stat /etc/ssh/ssh_config
ansible.builtin.stat:
path: '/etc/ssh/ssh_config'
register: ssh_config_file
- name: Stat /etc/ssh/sshd_config.d/01-hardening.conf
become: true
ansible.builtin.stat:
path: '/etc/ssh/sshd_config.d/01-hardening.conf'
register: sshd_config_directory
- name: Assert /etc/ssh/ssh_config permissions
ansible.builtin.assert:
that:
- ssh_config_file.stat.mode == "0644"
success_msg: "{{ ssh_config_file.stat.path }} has correct permissions: {{ ssh_config_file.stat.mode }}"
fail_msg: "{{ ssh_config_file.stat.path }} permissions are incorrect: {{ ssh_config_file.stat.mode }}"
- name: Assert /etc/ssh/sshd_config permissions
ansible.builtin.assert:
that:
- sshd_config_file.stat.mode == "0600"
success_msg: "{{ sshd_config_file.stat.path }} has correct permissions: {{ sshd_config_file.stat.mode }}"
fail_msg: "{{ sshd_config_file.stat.path }} permissions are incorrect: {{ sshd_config_file.stat.mode }}"
- name: Assert /etc/ssh/sshd_config.d/01-hardening.conf permissions
ansible.builtin.assert:
that:
- sshd_config_directory.stat.mode == "0600"
success_msg: "{{ sshd_config_directory.stat.path }} has correct permissions: {{ sshd_config_directory.stat.mode }}"
fail_msg: "{{ sshd_config_directory.stat.path }} permissions are incorrect: {{ sshd_config_directory.stat.mode }}"
when: sshd_config_directory.stat.exists
- name: Verify sshd_config PermitRootLogin configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
line: "PermitRootLogin yes"
state: absent
check_mode: true
register: sshd_config
failed_when: sshd_config is changed
- name: Verify sshd_config.d PermitRootLogin configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config.d/01-hardening.conf
line: "PermitRootLogin yes"
state: absent
check_mode: true
register: sshd_config_d
failed_when: sshd_config_d is changed
when: sshd_config_directory.stat.exists
- name: Verify sshd_config configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config
line: "{{ item }}"
state: present
check_mode: true
register: sshd_config
failed_when: sshd_config is changed
with_items:
- AllowGroups vagrant sudo
- AllowAgentForwarding {{ sshd_allow_agent_forwarding }}
- AllowTcpForwarding {{ sshd_allow_tcp_forwarding }}
- AuthenticationMethods {{ sshd_authentication_methods }}
- Banner {{ sshd_banner }}
- ChallengeResponseAuthentication {{ sshd_challenge_response_authentication }}
- Ciphers {{ sshd_ciphers }}
- ClientAliveCountMax {{ sshd_client_alive_count_max | int }}
- ClientAliveInterval {{ sshd_client_alive_interval | int }}
- Compression {{ sshd_compression }}
- GSSAPIAuthentication {{ sshd_gssapi_authentication }}
- HostbasedAuthentication {{ sshd_hostbased_authentication }}
- IgnoreUserKnownHosts {{ sshd_ignore_user_known_hosts }}
- KerberosAuthentication {{ sshd_kerberos_authentication }}
- HostKeyAlgorithms {{ sshd_host_key_algorithms }}
- KexAlgorithms {{ sshd_kex_algorithms }}
- LogLevel {{ sshd_log_level }}
- LoginGraceTime {{ sshd_login_grace_time | int }}
- Macs {{ sshd_macs }}
- MaxAuthTries {{ sshd_max_auth_tries | int }}
- MaxSessions {{ sshd_max_sessions | int }}
- MaxStartups {{ sshd_max_startups }}
- PasswordAuthentication {{ sshd_password_authentication }}
- PermitEmptyPasswords {{ sshd_permit_empty_passwords }}
- PermitRootLogin {{ sshd_permit_root_login }}
- PermitUserEnvironment {{ sshd_permit_user_environment }}
- Port {{ sshd_port | int }}
- PrintLastLog {{ sshd_print_last_log }}
- PrintMotd {{ sshd_print_motd }}
- RekeyLimit {{ sshd_rekey_limit }}
- StrictModes {{ sshd_strict_modes }}
- TCPKeepAlive {{ sshd_tcp_keep_alive }}
- UseDNS {{ sshd_use_dns }}
- UsePAM {{ sshd_use_pam }}
- X11Forwarding {{ sshd_x11_forwarding }}
when: not sshd_config_directory.stat.exists
- name: Verify sshd_config.d configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config.d/01-hardening.conf
line: "{{ item }}"
state: present
check_mode: true
register: sshd_config
failed_when: sshd_config is changed
with_items:
- AllowGroups vagrant sudo
- AllowAgentForwarding {{ sshd_allow_agent_forwarding }}
- AllowTcpForwarding {{ sshd_allow_tcp_forwarding }}
- AuthenticationMethods {{ sshd_authentication_methods }}
- Banner {{ sshd_banner }}
- ChallengeResponseAuthentication {{ sshd_challenge_response_authentication }}
- Ciphers {{ sshd_ciphers }}
- ClientAliveCountMax {{ sshd_client_alive_count_max | int }}
- ClientAliveInterval {{ sshd_client_alive_interval | int }}
- Compression {{ sshd_compression }}
- GSSAPIAuthentication {{ sshd_gssapi_authentication }}
- HostbasedAuthentication {{ sshd_hostbased_authentication }}
- IgnoreUserKnownHosts {{ sshd_ignore_user_known_hosts }}
- KerberosAuthentication {{ sshd_kerberos_authentication }}
- HostKeyAlgorithms {{ sshd_host_key_algorithms }}
- KexAlgorithms {{ sshd_kex_algorithms }}
- LogLevel {{ sshd_log_level }}
- LoginGraceTime {{ sshd_login_grace_time | int }}
- Macs {{ sshd_macs }}
- MaxAuthTries {{ sshd_max_auth_tries | int }}
- MaxSessions {{ sshd_max_sessions | int }}
- MaxStartups {{ sshd_max_startups }}
- PasswordAuthentication {{ sshd_password_authentication }}
- PermitEmptyPasswords {{ sshd_permit_empty_passwords }}
- PermitRootLogin {{ sshd_permit_root_login }}
- PermitUserEnvironment {{ sshd_permit_user_environment }}
- Port {{ sshd_port | int }}
- PrintLastLog {{ sshd_print_last_log }}
- PrintMotd {{ sshd_print_motd }}
- RekeyLimit {{ sshd_rekey_limit }}
- StrictModes {{ sshd_strict_modes }}
- Subsystem {{ sshd_subsystem }}
- TCPKeepAlive {{ sshd_tcp_keep_alive }}
- UseDNS {{ sshd_use_dns }}
- UsePAM {{ sshd_use_pam }}
- X11Forwarding {{ sshd_x11_forwarding }}
when: sshd_config_directory.stat.exists
- name: Verify sshd RequiredRSASize
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/sshd_config.d/01-hardening.conf
line: "RequiredRSASize {{ sshd_required_rsa_size }}"
state: present
check_mode: true
register: sshd_config_rsasize
failed_when: sshd_config_rsasize is changed
when: sshd_config_directory.stat.exists and ssh_installed_version is version('9.1', '>')
- name: Verify sshd runtime configuration
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.command: sshd -T
register: sshd_config
changed_when: false
failed_when: item not in sshd_config.stdout_lines
with_items:
- allowgroups sudo
- allowgroups vagrant
- allowagentforwarding {{ sshd_allow_agent_forwarding }}
- allowtcpforwarding {{ sshd_allow_tcp_forwarding }}
- authenticationmethods {{ sshd_authentication_methods }}
- banner {{ sshd_banner }}
- clientalivecountmax {{ sshd_client_alive_count_max | int }}
- clientaliveinterval {{ sshd_client_alive_interval | int }}
- compression {{ sshd_compression }}
- logingracetime {{ sshd_login_grace_time | int }}
- macs {{ sshd_macs }}
- maxauthtries {{ sshd_max_auth_tries | int }}
- maxsessions {{ sshd_max_sessions | int }}
- maxstartups {{ sshd_max_startups }}
- permitrootlogin {{ sshd_permit_root_login }}
- port {{ sshd_port | int }}
- subsystem {{ sshd_subsystem }}
- usedns {{ sshd_use_dns }}
- usepam {{ sshd_use_pam }}
- x11forwarding {{ sshd_x11_forwarding }}
- name: Verify ssh_config configuration
become: true
ansible.builtin.lineinfile:
dest: /etc/ssh/ssh_config
line: " {{ item }}"
state: present
check_mode: true
register: ssh_config
failed_when: ssh_config is changed
with_items:
- Ciphers {{ sshd_ciphers }}
- GSSAPIAuthentication {{ sshd_gssapi_authentication }}
- HashKnownHosts yes
- HostKeyAlgorithms {{ sshd_host_key_algorithms }}
- KexAlgorithms {{ sshd_kex_algorithms }}
- MACs {{ sshd_macs }}
- RekeyLimit {{ sshd_rekey_limit }}
- name: Merge sysctl settings
ansible.builtin.set_fact:
sysctl_settings: "{{ generic_sysctl_settings | combine(ipv4_sysctl_settings) }}"
- name: Verify sysctl configuration
become: true
ansible.builtin.shell: |
set -o pipefail
grep -R "^{{ item.key }}.*{{ item.value | int }}$" "{{ sysctl_conf_dir }}/"
args:
executable: /bin/bash
with_dict: "{{ sysctl_settings | dict2items | rejectattr('key', 'search', 'nf_conntrack') | items2dict }}"
register: sysctl_file_config
failed_when: sysctl_file_config.rc != 0
changed_when: sysctl_file_config.rc != 0
- name: Verify sysctl runtime configuration
become: true
ansible.builtin.shell: |
set -o pipefail
sysctl -a | grep "^{{ item.key }}.*{{ item.value | int }}$"
args:
executable: /bin/bash
with_dict: "{{ sysctl_settings | dict2items | rejectattr('key', 'search', 'nf_conntrack') | items2dict }}"
register: sysctl_runtime_config
failed_when: sysctl_runtime_config.rc != 0
changed_when: sysctl_runtime_config.rc != 0
- name: Stat crypto-policies config
become: true
ansible.builtin.stat:
path: /etc/crypto-policies/config
register: crypto_policies_config
- name: Get crypto-policies value
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: grep "^{{ crypto_policy | upper }}$" /etc/crypto-policies/config
register: crypto_policy_set
when: crypto_policies_config.stat.exists
failed_when: crypto_policy_set.rc != 0
changed_when: crypto_policy_set.rc != 0
- name: Verify noexec /dev/shm
ansible.builtin.shell: grep '^tmpfs\s/dev/shm.*noexec' /proc/mounts
register: dev_shm_noexec
failed_when: dev_shm_noexec.rc != 0
changed_when: dev_shm_noexec.rc != 0
- name: Verify /proc
ansible.builtin.shell: |
set -o pipefail
grep -E '^proc\s/proc proc rw,nosuid,nodev,noexec,relatime.*hidepid=({{ hide_pid }}|invisible)' /proc/mounts
args:
executable: /bin/bash
register: proc_opts
failed_when: proc_opts.rc != 0
changed_when: proc_opts.rc != 0
tags:
- skip_ansible_lint
- name: Verify tmp.mount
become: true
ansible.builtin.systemd:
name: tmp.mount
register: tmp_mount
failed_when: not 'nosuid,nodev,noexec' in tmp_mount.status.Options
changed_when: not 'nosuid,nodev,noexec' in tmp_mount.status.Options
- name: Verify /tmp
become: true
ansible.builtin.shell: grep '^tmpfs\s/tmp\s.*nosuid,nodev,noexec' /proc/mounts
register: mounts_tmp
failed_when: mounts_tmp.rc != 0
changed_when: mounts_tmp.rc != 0
- name: Verify login.defs settings
become: true
ansible.builtin.shell: grep "^{{ item }}$" /etc/login.defs
register: login_defs
failed_when: login_defs.rc != 0
changed_when: login_defs.rc != 0
with_items:
- ENCRYPT_METHOD SHA512
- FAILLOG_ENAB yes
- LOG_OK_LOGINS yes
- PASS_MAX_DAYS 60
- PASS_MIN_DAYS 1
- PASS_WARN_AGE 7
- SHA_CRYPT_MAX_ROUNDS 65536
- SHA_CRYPT_MIN_ROUNDS 10000
- SU_NAME su
- SYSLOG_SG_ENAB yes
- SYSLOG_SU_ENAB yes
- UMASK {{ umask_value }}
- name: Verify pwquality.conf settings
become: true
ansible.builtin.lineinfile:
path: /etc/security/pwquality.conf
line: "{{ item.key }} = {{ item.value }}"
state: present
mode: "0644"
owner: root
group: root
check_mode: true
register: pwquality_conf
failed_when: pwquality_conf is changed
with_dict: "{{ pwquality_config }}"
- name: Verify RedHat GRUB audit settings
become: true
ansible.builtin.shell: |
set -o pipefail
grubby --info="/boot/vmlinuz-$(uname -r)" | grep "^args.*{{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}"
register: audit_grubenv
failed_when: audit_grubenv.rc != 0
changed_when: audit_grubenv.rc != 0
when: ansible_os_family == "RedHat"
- name: Verify Debian audit GRUB settings
become: true
ansible.builtin.shell: grep "linux.*{{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}" /boot/grub/grub.cfg
register: audit_grub_cfg
failed_when: audit_grub_cfg.rc != 0
changed_when: audit_grub_cfg.rc != 0
when: ansible_os_family == "Debian"
- name: Verify RedHat GRUB IPv6 settings
become: true
ansible.builtin.shell:
cmd: |
set -o pipefail
grubby --info="/boot/vmlinuz-$(uname -r)" | grep "ipv6.disable=1"
register: audit_grubenv
failed_when: audit_grubenv.rc != 0
changed_when: audit_grubenv.rc != 0
when: ansible_os_family == "RedHat" and disable_ipv6
- name: Verify Debian GRUB IPv6 settings
become: true
ansible.builtin.shell:
cmd: grep "linux.*ipv6.disable=1" /boot/grub/grub.cfg
register: audit_grub_cfg
failed_when: audit_grub_cfg.rc != 0
changed_when: audit_grub_cfg.rc != 0
when: ansible_os_family == "Debian" and disable_ipv6
- name: Verify IPv6 sysctl configuration
become: true
ansible.builtin.shell: grep -R "^{{ item }}$" /etc/sysctl.* /usr/lib/sysctl.d/*
register: sysctl_ipv6_config
failed_when: sysctl_ipv6_config.rc != 0
changed_when: sysctl_ipv6_config.rc != 0
with_items:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv6.conf.default.disable_ipv6=1
when: disable_ipv6
- name: Verify IPv6 sysctl runtime configuration
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
become: true
ansible.builtin.shell: |
set -o pipefail
sysctl -a | grep "^{{ item.key }}.*{{ item.value | int }}$"
args:
executable: /bin/bash
with_dict: "{{ ipv6_disable_sysctl_settings }}"
register: sysctl_ipv6
changed_when: sysctl_ipv6.rc != 0
failed_when: sysctl_ipv6.rc != 0
when: system_has_ipv6 and disable_ipv6
- name: Find GRUB config files
become: true
ansible.builtin.find:
paths: /boot
patterns: "*.cfg,grubenv"
recurse: true
register: perm_grub_cfg
- name: Verify GRUB config files permission
become: true
ansible.builtin.stat:
path: "{{ item.path }}"
changed_when: item.mode | int > 644
failed_when: item.mode | int > 644
with_items:
- "{{ perm_grub_cfg.files | reject('search', '/boot/efi/EFI/ubuntu/grub.cfg') | list }}"
loop_control:
label: "{{ item.path }}"
- name: Verify systemd resolved.conf
become: true
ansible.builtin.shell: grep "^{{ item }}$" /etc/systemd/resolved.conf
register: systemd_resolved_conf
failed_when: systemd_resolved_conf.rc != 0
changed_when: systemd_resolved_conf.rc != 0
with_items:
- DNS={{ dns }}
- FallbackDNS={{ fallback_dns }}
- DNSSEC={{ dnssec }}
- DNSOverTLS={{ dns_over_tls }}
- name: Verify systemd timesyncd.conf
become: true
ansible.builtin.shell: grep "^{{ item }}$" /etc/systemd/timesyncd.conf
register: systemd_timesyncd_conf
failed_when: systemd_timesyncd_conf.rc != 0
changed_when: systemd_timesyncd_conf.rc != 0
with_items:
- NTP={{ ntp }}
- FallbackNTP={{ fallback_ntp }}
- name: Stat /etc/default/motd-news
ansible.builtin.stat:
path: /etc/default/motd-news
register: motd_news
- name: Verify masked motdnews service
become: true
ansible.builtin.systemd:
name: motd-news.service
masked: true
enabled: false
state: stopped
check_mode: true
register: motdnews_service
failed_when: motdnews_service is changed
when: ansible_os_family == "Debian" and motd_news.stat.exists
- name: Stat /usr/bin/pro
ansible.builtin.stat:
path: /usr/bin/pro
register: ubuntu_advantage_pro
when: ansible_os_family == "Debian"
- name: Verify that apt_news is disabled
ansible.builtin.shell: |
set -o pipefail
pro config show | grep '^apt_news.*False'
args:
executable: /bin/bash
register: ubuntu_advantage_pro_state
changed_when: ubuntu_advantage_pro_state.rc != 0
failed_when: ubuntu_advantage_pro_state.rc != 0
when: ansible_os_family == "Debian" and ubuntu_advantage_pro.stat.exists
- name: Efi fact
ansible.builtin.set_fact:
booted_with_efi: "{{ ansible_mounts | selectattr('mount', 'equalto', '/boot/efi') | list | length > 0 }}"
- name: Verify cracklib password list
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: |
set -o pipefail
grep '/usr/share/dict/passwords' /var/cache/cracklib/src-dicts
args:
executable: /bin/bash
register: cracklib_passwords
failed_when: cracklib_passwords.rc != 0
changed_when: cracklib_passwords.rc != 0
when: ansible_os_family == "Debian"
- name: Index blacklisted kernel modules
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: |
set -o pipefail
modprobe -c | grep -o '^blacklist .*' | awk '{print $2}'
args:
executable: /bin/bash
changed_when: false
failed_when: modprobe_blacklist.rc != 0
register: modprobe_blacklist
when: block_blacklisted | bool
- name: Verify blocked blacklisted kernel modules
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: |
set -o pipefail
grep 'install {{ item }} /bin/true' /etc/modprobe.d/blockblacklisted.conf
args:
executable: /bin/bash
register: modprobe_blockblacklisted
failed_when: modprobe_blockblacklisted.rc != 0
changed_when: modprobe_blockblacklisted.rc != 0
with_items:
- "{{ modprobe_blacklist.stdout_lines | sort }}"
when: block_blacklisted | bool
- name: Verify sudo settings
ansible.builtin.shell: |
set -o pipefail
sudo -l | grep "{{ item }}"
register: sudo_settings
failed_when: sudo_settings.rc != 0
changed_when: sudo_settings.rc != 0
args:
executable: /bin/bash
with_items:
- 'use_pty'
- 'logfile="/var/log/sudo.log"'
- '!pwfeedback'
- '!visiblepw'
- 'passwd_timeout=1'
- 'timestamp_timeout=5'
- 'timestamp_type=tty'
- "!rootpw"
- "!runaspw"
- "!targetpw"
- name: Stat faillock.conf
become: true
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: faillockconf
- name: Verify faillock.conf
become: true
ansible.builtin.lineinfile:
dest: /etc/security/faillock.conf
mode: "0644"
state: present
line: "{{ item }}"
check_mode: true
register: verify_faillock
failed_when: verify_faillock is changed
with_items:
- "audit"
- "local_users_only"
- "deny = 5"
- "fail_interval = 900"
when: faillockconf.stat.exists
- name: Verify wireless state
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.command: nmcli -t radio
register: wireless_state
changed_when: not 'disabled' in wireless_state.stdout
failed_when: not 'disabled' in wireless_state.stdout
when: disable_wireless
- name: Stat firewall rules when UFW is enabled
become: true
ansible.builtin.shell: |
set -o pipefail
ufw show added | grep '^ufw' | grep -v "'ansible\smanaged'" | sed 's/ufw //g'
args:
executable: /bin/bash
failed_when: ufw_not_managed.rc > 1
changed_when: false
register: ufw_not_managed
when: ufw_enable
- name: Stat firewall rules when UFW is disabled
become: true
ansible.builtin.shell: |
set -o pipefail
ufw show added | grep '^ufw' | grep "'ansible\smanaged'" | sed 's/ufw //g'
args:
executable: /bin/bash
failed_when: ufw_not_managed.rc > 1
changed_when: false
register: ufw_not_managed
when: not ufw_enable
- name: Create test user
become: true
ansible.builtin.user:
name: roletestuser
password: "{{ 'Ansible Role Test User' | password_hash('sha512') }}"
state: present
shell: /bin/bash
- name: Create test user salt
ansible.builtin.set_fact:
test_user_salt: "{{ lookup('password', '/dev/null chars=ascii_lowercase,ascii_uppercase,digits length=16') }}"
- name: Change test user password
become: true
ansible.builtin.user:
name: roletestuser
password: "{{ 'roletestuser' | password_hash('sha512', test_user_salt, rounds=656000) }}"
register: test_user_pass
- name: Debug test user salt
ansible.builtin.debug:
msg: "{{ test_user_salt }}"
- name: Debug test user password
ansible.builtin.debug:
msg: "{{ test_user_pass }}"
...
@@ -0,0 +1,76 @@
---
# https://access.redhat.com/solutions/253273
# sudo subscription-manager register --username=USER --password=PASSWORD --auto-attach
# sudo subscription-manager unregister
dependency:
name: galaxy
enabled: true
driver:
name: vagrant
provider:
name: virtualbox
provisioner:
name: ansible
config_options:
defaults:
callbacks_enabled: profile_tasks
playbooks:
converge: ../default/converge.yml
verify: ../default/verify.yml
log: true
inventory:
host_vars:
redhat:
ssh_allowed_networks: "0.0.0.0/0"
sshd_allow_groups: "vagrant sudo"
platforms:
- name: redhat
box: "generic/rhel8"
config_options:
vm.boot_timeout: 600
instance_raw_config_args:
- 'vbguest.auto_update = false'
memory: 1024
verifier:
name: ansible
lint: |
set -e
ansible-lint
scenario:
name: redhat
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- dependency
- cleanup
- destroy
test_sequence:
- dependency
- lint
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy
@@ -0,0 +1,113 @@
---
dependency:
name: galaxy
enabled: true
driver:
name: vagrant
provider:
name: libvirt
provisioner:
name: ansible
config_options:
defaults:
callbacks_enabled: profile_tasks
playbooks:
converge: ../default/converge.yml
verify: ../default/verify.yml
log: true
inventory:
host_vars:
jammy:
ssh_allowed_networks: "0.0.0.0/0"
sshd_allow_groups: "vagrant sudo"
platforms:
- name: focal
box: "jaredeh/ubuntu2004-server"
box_version: "0.1.5"
interfaces:
- auto_config: true
network_name: private_network
type: dhcp
instance_raw_config_args:
# use single quotes to avoid YAML parsing as dict due to ':'
- 'vm.synced_folder ".", "/vagrant", type: "rsync"'
# Run 'uname' a provisionning step **needs 'provision: true' to work**
- 'vm.provision :shell, inline: "uname"'
# Dictionary of `config` options. Note that string values need to be
# explicitly enclosed in quotes.
config_options:
vm.boot_timeout: 600
ssh.keep_alive: true
ssh.remote_user: 'ansible'
synced_folder: true
provider_options:
video_type: 'vga'
host: 'localhost'
uri: 'qemu:///system'
memory: 4096
- name: jammy
box: "techchad2022/ubuntu2204"
interfaces:
- auto_config: true
network_name: private_network
type: dhcp
instance_raw_config_args:
# use single quotes to avoid YAML parsing as dict due to ':'
- 'vm.synced_folder ".", "/vagrant", type: "rsync"'
# Run 'uname' a provisionning step **needs 'provision: true' to work**
- 'vm.provision :shell, inline: "uname"'
# Dictionary of `config` options. Note that string values need to be
# explicitly enclosed in quotes.
config_options:
vm.boot_timeout: 600
ssh.keep_alive: true
ssh.remote_user: 'ansible'
synced_folder: true
provider_options:
video_type: 'vga'
host: 'localhost'
uri: 'qemu:///system'
memory: 4096
verifier:
name: ansible
lint: |
set -e
ansible-lint
scenario:
name: ubuntu
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- dependency
- cleanup
- destroy
test_sequence:
- dependency
- lint
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy
@@ -0,0 +1,4 @@
---
collections:
- ansible.posix
- community.general
@@ -0,0 +1,31 @@
---
- name: Add configuration file for adduser and addgroup
become: true
ansible.builtin.template:
src: etc/adduser.conf.j2
dest: /etc/adduser.conf
backup: true
mode: "0644"
owner: root
group: root
tags:
- adduser
- users
- name: Add configuration file for useradd
become: true
ansible.builtin.template:
src: etc/default/useradd.j2
dest: /etc/default/useradd
backup: true
mode: "0644"
owner: root
group: root
tags:
- useradd
- users
- CCE-27355-7
- CCE-80954-1
- CCE-83627-0
- CIS-UBUNTU2004-5.5.1.4
- UBTU-20-010409
+161
View File
@@ -0,0 +1,161 @@
---
- name: Debian family AIDE installation
become: true
ansible.builtin.apt:
name: aide-common
state: present
install_recommends: false
when: ansible_os_family == "Debian"
tags:
- aide
- CIS-UBUNTU2004-1.3.1
- name: RedHat family AIDE package installation
become: true
ansible.builtin.package:
name: aide
state: present
when: ansible_os_family == "RedHat"
tags:
- aide
- CCE-80844-4
- name: Stat AIDE cron.daily
become: true
ansible.builtin.stat:
path: /etc/cron.daily/aide
register: aidecron
tags:
- aide
- CCE-80844-4
- CIS-UBUNTU2004-1.3.1
- name: Install AIDE service
become: true
ansible.builtin.template:
src: lib/systemd/system/aidecheck.service.j2
dest: /lib/systemd/system/aidecheck.service
backup: true
mode: "0644"
owner: root
group: root
when: not aidecron.stat.exists
tags:
- aide
- name: Install AIDE timer
become: true
ansible.builtin.template:
src: lib/systemd/system/aidecheck.timer.j2
dest: /lib/systemd/system/aidecheck.timer
backup: true
mode: "0644"
owner: root
group: root
when: not aidecron.stat.exists
notify:
- Reload systemd
- Enable aidecheck
tags:
- aide
- CCE-80676-0
- CIS-UBUNTU2004-1.3.2
- name: Add AIDE Debian dir exclusions
become: true
ansible.builtin.blockinfile:
path: /etc/aide/aide.conf
marker: "# {mark} ANSIBLE MANAGED BLOCK"
backup: true
insertafter: EOF
block: |
!/var/lib/docker
!/var/lib/lxcfs
!/var/lib/private/systemd
!/var/log/audit
!/var/log/journal
when: ansible_os_family == "Debian"
tags:
- aide
- name: Stat Debian aide.db
become: true
ansible.builtin.stat:
path: /var/lib/aide/aide.db
register: ubuaidedb
when: ansible_os_family == "Debian"
tags:
- aide
- name: Add AIDE RedHat dir exclusions
become: true
ansible.builtin.blockinfile:
path: /etc/aide.conf
marker: "# {mark} ANSIBLE MANAGED BLOCK"
backup: true
insertafter: EOF
block: |
!/var/lib/docker
!/var/lib/lxcfs
!/var/lib/private/systemd
!/var/log/audit
!/var/log/journal
when: ansible_os_family == "RedHat"
tags:
- aide
- name: Stat RedHat aide.db
become: true
ansible.builtin.stat:
path: /var/lib/aide/aide.db.gz
register: rhelaidedb
changed_when: false
failed_when: false
when: ansible_os_family == "RedHat"
tags:
- aide
- name: Initialize RedHat AIDE
become: true
ansible.builtin.command:
cmd: aide --init -B 'database_out=file:/var/lib/aide/aide.db.gz'
register: init_redhat_aide
changed_when: init_redhat_aide.rc != 0
failed_when: init_redhat_aide.rc != 0
when: ansible_os_family == "RedHat" and not rhelaidedb.stat.exists
tags:
- aide
- CCE-80675-2
- name: Stat RedHat aide.db.new.gz
become: true
ansible.builtin.stat:
path: /var/lib/aide/aide.db.new.gz
register: rhelaidedbnew
changed_when: false
failed_when: false
when: ansible_os_family == "RedHat"
tags:
- aide
- name: Copy RedHat AIDE database
become: true
ansible.builtin.command:
cmd: cp /var/lib/aide/aide.db.gz /var/lib/aide/aide.db.new.gz
register: cp_redhat_aide_db
changed_when: cp_redhat_aide_db.rc != 0
failed_when: cp_redhat_aide_db.rc != 0
when: ansible_os_family == "RedHat" and not rhelaidedbnew.stat.exists
tags:
- aide
- name: Initialize Debian AIDE
become: true
ansible.builtin.command:
cmd: aideinit --force --yes
register: init_debian_aide
changed_when: init_debian_aide.rc != 0
failed_when: init_debian_aide.rc != 0
when: ansible_os_family == "Debian" and not ubuaidedb.stat.exists
tags:
- aide
@@ -0,0 +1,67 @@
---
- name: Set Debian family AppArmor grub cmdline
become: true
ansible.builtin.lineinfile:
line: 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX apparmor=1 security=apparmor"'
dest: /etc/default/grub.d/99-hardening-apparmor.cfg
state: present
create: true
mode: "0640"
owner: root
group: root
when: ansible_os_family == "Debian"
notify:
- Update GRUB
tags:
- apparmor
- CIS-UBUNTU2004-1.6.1.2
- name: Configure pam_apparmor
become: true
ansible.builtin.lineinfile:
line: "session optional pam_apparmor.so order=user,group,default"
dest: /etc/pam.d/apparmor
state: present
create: true
mode: "0640"
owner: root
group: root
when: ansible_os_family == "Debian"
notify:
- Update GRUB
tags:
- apparmor
- name: Get AppArmor status
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.command: aa-status --complaining
register: get_apparmor_complaining
changed_when: get_apparmor_complaining.stdout != "0"
when: ansible_os_family == "Debian"
tags:
- apparmor
- name: Enforce AppArmor profiles
become: true
ansible.builtin.command:
cmd: find /etc/apparmor.d/ -maxdepth 1 -type f -exec aa-enforce {} \;
register: enforce_apparmor_profiles
changed_when: enforce_apparmor_profiles.rc != 0
failed_when: enforce_apparmor_profiles.rc != 0
when: ansible_os_family == "Debian" and (get_apparmor_complaining.stdout != "0")
tags:
- apparmor
- CIS-UBUNTU2004-1.6.1.3
- CIS-UBUNTU2004-1.6.1.4
- name: Enable apparmor
become: true
ansible.builtin.systemd:
name: apparmor
enabled: true
state: started
when: ansible_os_family == "Debian"
tags:
- apparmor
@@ -0,0 +1,21 @@
---
- name: Disable apport
become: true
ansible.builtin.lineinfile:
regexp: "^enabled="
line: "enabled=0"
dest: /etc/default/apport
mode: "0644"
state: present
create: false
backrefs: true
register: default_apport
notify:
- Mask apport
when: ansible_os_family == "Debian"
failed_when:
- default_apport.rc is defined
- default_apport.rc !=0
- not default_apport.rc == 257
tags:
- apport
@@ -0,0 +1,204 @@
---
- name: Configure Debian auditd GRUB cmdline
become: true
ansible.builtin.lineinfile:
line: 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX {{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}"'
dest: /etc/default/grub.d/99-hardening-audit.cfg
state: present
create: true
mode: "0640"
owner: root
group: root
when: ansible_os_family == "Debian"
tags:
- auditd
- CIS-UBUNTU2004-4.1.1.3
- CIS-UBUNTU2004-4.1.1.4
- name: Configure RedHat auditd GRUB cmdline
become: true
ansible.builtin.command:
cmd: 'grubby --update-kernel=ALL --args="{{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}"'
register: grubby_update_kernel
when: ansible_os_family == "RedHat"
changed_when: grubby_update_kernel.rc != 0
failed_when: grubby_update_kernel.rc != 0
tags:
- auditd
- CCE-80825-3
- CCE-80943-4
- name: Configure auditd action_mail_acct
become: true
ansible.builtin.lineinfile:
regexp: "^action_mail_acct ="
line: "action_mail_acct = {{ auditd_action_mail_acct }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CCE-80678-6
- name: Configure auditd admin_space_left_action
become: true
ansible.builtin.lineinfile:
regexp: "^admin_space_left_action = "
line: "admin_space_left_action = {{ auditd_admin_space_left_action }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- name: Configure auditd disk_error_action
become: true
ansible.builtin.lineinfile:
regexp: "^disk_error_action ="
line: "disk_error_action = {{ auditd_disk_error_action }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CCE-84046-2
- name: Configure auditd disk_full_action
become: true
ansible.builtin.lineinfile:
regexp: "^disk_full_action ="
line: "disk_full_action = {{ auditd_disk_full_action }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CCE-84045-4
- name: Configure auditd max_log_file
become: true
ansible.builtin.lineinfile:
regexp: "^max_log_file ="
line: "max_log_file = {{ auditd_max_log_file }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CIS-UBUNTU2004-4.1.2.1
- name: Configure auditd max_log_file_action
become: true
ansible.builtin.lineinfile:
regexp: "^max_log_file_action ="
line: "max_log_file_action = {{ auditd_max_log_file_action }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CCE-80682-8
- CIS-UBUNTU2004-4.1.2.2
- name: Configure auditd num_logs
become: true
ansible.builtin.lineinfile:
regexp: "^num_logs ="
line: "num_logs = {{ auditd_num_logs }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- name: Configure auditd space_left
become: true
ansible.builtin.lineinfile:
regexp: "^space_left ="
line: "space_left = {{ auditd_space_left }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- name: Configure auditd space_left_action
become: true
ansible.builtin.lineinfile:
regexp: "^space_left_action ="
line: "space_left_action = {{ auditd_space_left_action }}"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- CCE-80684-4
- name: Configure auditd name_format
become: true
ansible.builtin.lineinfile:
regexp: "^name_format ="
line: "name_format = hostname"
dest: /etc/audit/auditd.conf
mode: "0640"
state: present
create: false
tags:
- auditd
- name: Enable auditd syslog plugin
become: true
ansible.builtin.lineinfile:
dest: /etc/audit/plugins.d/syslog.conf
regexp: "^active"
line: "active = yes"
state: present
mode: "0640"
create: true
tags:
- auditd
- name: Add auditd rules
become: true
ansible.builtin.template:
src: etc/audit/rules.d/hardening.rules.j2
dest: /etc/audit/rules.d/hardening.rules
backup: true
mode: "0600"
owner: root
group: root
when: auditd_apply_audit_rules | bool
notify:
- Generate auditd rules
- Restart Debian auditd
- Restart RedHat auditd
tags:
- auditd
- CCE-80708-1
- CIS-UBUNTU2004-4.1.1.2
- CIS-UBUNTU2004-4.1.3
- CIS-UBUNTU2004-4.1.4
- CIS-UBUNTU2004-4.1.5
- CIS-UBUNTU2004-4.1.6
- CIS-UBUNTU2004-4.1.7
- CIS-UBUNTU2004-4.1.8
- CIS-UBUNTU2004-4.1.9
- CIS-UBUNTU2004-4.1.10
- CIS-UBUNTU2004-4.1.11
- CIS-UBUNTU2004-4.1.12
- CIS-UBUNTU2004-4.1.13
- CIS-UBUNTU2004-4.1.14
- CIS-UBUNTU2004-4.1.15
- CIS-UBUNTU2004-4.1.16
- CIS-UBUNTU2004-4.1.17
- D3-SDM
- D3-SFA
@@ -0,0 +1,35 @@
---
- name: Stat available compilers
become: true
ansible.builtin.find:
paths:
[
"/usr/local/sbin",
"/usr/local/bin",
"/usr/sbin",
"/usr/bin",
"/sbin",
"/bin",
"/snap/bin",
]
patterns: "{{ compilers }}"
file_type: any
follow: true
recurse: true
register: compiler
tags:
- compilers
- name: Restrict compiler access
become: true
ansible.builtin.file:
path: "{{ item.path }}"
owner: root
group: root
mode: "0750"
state: file
follow: true
with_items:
- "{{ compiler.files }}"
tags:
- compilers
@@ -0,0 +1,88 @@
---
- name: Remove cron.deny and at.deny
become: true
ansible.builtin.file:
path: "{{ item }}"
state: absent
with_items:
- /etc/at.deny
- /etc/cron.deny
tags:
- at
- cron
- name: Clean cron and at
become: true
ansible.builtin.lineinfile:
path: "{{ item }}"
regexp: "^(?!root).*$"
state: absent
with_items:
- /etc/at.allow
- /etc/cron.allow
tags:
- at
- cron
- CIS-UBUNTU2004-5.1.8
- CIS-UBUNTU2004-5.1.9
- name: Allow root cron and at
become: true
ansible.builtin.lineinfile:
path: "{{ item }}"
line: "root"
mode: "0600"
state: present
create: true
with_items:
- /etc/at.allow
- /etc/cron.allow
tags:
- at
- cron
- name: Mask atd
become: true
ansible.builtin.systemd:
name: atd
masked: true
enabled: false
state: stopped
register: mask_atd
failed_when: mask_atd is not success and not "Could not find the requested service" in mask_atd.msg
tags:
- at
- systemd
- name: Set cron permissions
become: true
ansible.builtin.file:
path: "{{ item }}"
mode: "0700"
owner: root
group: root
with_items:
- /etc/cron.d
- /etc/cron.daily
- /etc/cron.hourly
- /etc/cron.weekly
- /etc/cron.monthly
tags:
- cron
- CIS-UBUNTU2004-5.1.3
- CIS-UBUNTU2004-5.1.4
- CIS-UBUNTU2004-5.1.5
- CIS-UBUNTU2004-5.1.6
- CIS-UBUNTU2004-5.1.7
- name: Set crontab permissions
become: true
ansible.builtin.file:
path: /etc/crontab
mode: "0600"
owner: root
group: root
tags:
- cron
- crontab
- CIS-UBUNTU2004-5.1.2
@@ -0,0 +1,28 @@
---
- name: Disable systemd ctrl-alt-del
become: true
ansible.builtin.systemd:
name: ctrl-alt-del.target
masked: true
enabled: false
state: stopped
when: not ansible_os_family == "RedHat"
tags:
- ctrl-alt-del
- CCE-80785-9
- systemd
- name: Disable systemd ctrl-alt-del - RedHat family
become: true
ansible.builtin.systemd:
name: ctrl-alt-del.target
masked: true
enabled: false
state: stopped
when: ansible_os_family == "RedHat"
changed_when: false
tags:
- ctrl-alt-del
- CCE-80785-9
- systemd
...
@@ -0,0 +1,27 @@
---
- name: Disable file system kernel modules
become: true
ansible.builtin.lineinfile:
dest: /etc/modprobe.d/disablefs.conf
line: "install {{ item }} /bin/true"
mode: "0644"
owner: root
group: root
state: present
create: true
with_items:
- "{{ fs_modules_blocklist }}"
tags:
- modprobe
- CCE-80835-2
- CCE-81031-7
- CIS-UBUNTU2004-1.1.1.1
- CIS-UBUNTU2004-1.1.1.2
- CIS-UBUNTU2004-1.1.1.3
- CIS-UBUNTU2004-1.1.1.4
- CIS-UBUNTU2004-1.1.1.5
- CIS-UBUNTU2004-1.1.1.5
- CIS-UBUNTU2004-1.1.1.6
- CIS-UBUNTU2004-1.1.1.7
- M1038
- M1042
@@ -0,0 +1,59 @@
---
- name: Disable misc kernel modules
become: true
ansible.builtin.lineinfile:
dest: /etc/modprobe.d/disablemod.conf
line: "install {{ item }} /bin/true"
mode: "0644"
owner: root
group: root
state: present
create: true
with_items:
- "{{ misc_modules_blocklist }}"
tags:
- modprobe
- CCE-80832-9
- CCE-82005-0
- CCE-82059-7
- CIS-UBUNTU2004-1.1.24
- M1034
- M1038
- M1042
- name: Stat blacklisted kernel modules
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: |
set -o pipefail
modprobe -c | grep -o '^blacklist .*' | awk '{print $2}'
args:
executable: /bin/bash
changed_when: false
failed_when: modprobe_blacklist.rc != 0
register: modprobe_blacklist
when: block_blacklisted | bool
tags:
- modprobe
- M1034
- M1038
- M1042
- name: Block blacklisted kernel modules
become: true
ansible.builtin.lineinfile:
dest: /etc/modprobe.d/blockblacklisted.conf
line: "install {{ item }} /bin/true"
mode: "0644"
owner: root
group: root
state: present
create: true
with_items:
- "{{ modprobe_blacklist.stdout_lines | sort }}"
when: block_blacklisted | bool
tags:
- modprobe
- M1034
- M1038
- M1042
@@ -0,0 +1,24 @@
---
- name: Disable kernel network modules
become: true
ansible.builtin.lineinfile:
dest: /etc/modprobe.d/disablenet.conf
line: "install {{ item }} /bin/true"
mode: "0644"
owner: root
group: root
state: present
create: true
with_items:
- "{{ net_modules_blocklist }}"
tags:
- modprobe
- CCE-80834-5
- CCE-82028-2
- CCE-82297-3
- CIS-UBUNTU2004-3.4.1
- CIS-UBUNTU2004-3.4.2
- CIS-UBUNTU2004-3.4.3
- CIS-UBUNTU2004-3.4.4
- M1038
- M1042
@@ -0,0 +1,30 @@
---
- name: Disable wireless interfaces
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
block:
- name: Install network-manager
become: true
ansible.builtin.apt:
name: network-manager
state: present
install_recommends: false
when: ansible_os_family == "Debian"
- name: Get WiFi state
ansible.builtin.command: nmcli -t radio
register: wifi_state_pre
changed_when: wifi_state_pre.rc != 0
failed_when: wifi_state_pre.rc != 0
- name: Turn off wireless interfaces
become: true
ansible.builtin.command: nmcli radio all off
register: nmcli_radio
changed_when: nmcli_radio.rc != 0
failed_when: nmcli_radio.rc != 0
tags:
- wireless
- CCE-83501-7
- CIS-UBUNTU2004-3.1.2
...
@@ -0,0 +1,21 @@
---
- name: Reboot if required
tags:
- reboot
- ubuntu
when: reboot_ubuntu
block:
- name: Stat /var/run/reboot-required
ansible.builtin.stat:
path: /var/run/reboot-required
register: stat_reboot_required
- name: Notify reboot handler
become: true
ansible.builtin.setup: ~
notify:
- Reboot node
when:
- ansible_distribution == "Ubuntu"
- stat_reboot_required.stat.exists
...
@@ -0,0 +1,84 @@
---
- name: Create custom facts directory
become: true
ansible.builtin.file:
path: /etc/ansible/facts.d
recurse: true
state: directory
mode: "0755"
owner: root
group: root
tags:
- fact
- name: Add systemd version fact
become: true
ansible.builtin.template:
src: etc/ansible/facts.d/systemd.fact
dest: /etc/ansible/facts.d/systemd.fact
mode: "0755"
owner: root
group: root
tags:
- fact
- systemd
- name: Add cpuinfo rdrand fact
become: true
ansible.builtin.template:
src: etc/ansible/facts.d/cpuinfo.fact
dest: /etc/ansible/facts.d/cpuinfo.fact
mode: "0755"
owner: root
group: root
tags:
- cpuinfo
- fact
- rdrand
- name: Add ssh keys fact
become: true
ansible.builtin.template:
src: etc/ansible/facts.d/sshkeys.fact
dest: /etc/ansible/facts.d/sshkeys.fact
mode: "0755"
owner: root
group: root
tags:
- fact
- sshd
- name: Stat IPv6 status
become: true
ansible.builtin.stat:
path: /proc/sys/net/ipv6
register: stat_ipv6
tags:
- fact
- ipv6
- name: Set IPv6 fact
ansible.builtin.set_fact:
system_has_ipv6: "{{ stat_ipv6.stat.exists }}"
tags:
- fact
- ipv6
- name: Set sysctl configuration directory as fact
tags:
- fact
- sysctl
block:
- name: Stat /usr/lib/sysctl.d/ exists
ansible.builtin.stat:
path: "/usr/lib/sysctl.d/"
register: usr_lib_sysctl_d
- name: Set sysctl fact
ansible.builtin.set_fact:
sysctl_conf_dir: "{{ '/usr/lib/sysctl.d' if usr_lib_sysctl_d.stat.exists else '/etc/sysctl.d' }}"
- name: Update current facts
ansible.builtin.setup: ~
tags:
- fact
@@ -0,0 +1,18 @@
---
- name: Remove /tmp from fstab
become: true
ansible.posix.mount:
path: /tmp
state: absent
tags:
- fstab
- name: Remove floppy from fstab
become: true
ansible.builtin.lineinfile:
path: /etc/fstab
state: absent
regexp: '^(.*)floppy(.*)$'
tags:
- fstab
...
@@ -0,0 +1,24 @@
---
- name: Configure hosts.allow
become: true
ansible.builtin.template:
src: etc/hosts.allow.j2
dest: /etc/hosts.allow
backup: true
mode: "0644"
owner: root
group: root
tags:
- hosts.allow
- name: Configure hosts.deny
become: true
ansible.builtin.template:
src: etc/hosts.deny.j2
dest: /etc/hosts.deny
backup: true
mode: "0644"
owner: root
group: root
tags:
- hosts.deny
@@ -0,0 +1,43 @@
---
- name: Set Debian ipv6.disable GRUB cmdline
become: true
ansible.builtin.lineinfile:
line: 'GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX ipv6.disable=1"'
dest: /etc/default/grub.d/99-hardening-ipv6.cfg
state: present
create: true
mode: "0640"
owner: root
group: root
when: ansible_os_family == "Debian"
tags:
- ipv6
- CIS-UBUNTU2004-3.1.1
- name: Set RedHat ipv6.disable GRUB cmdline
become: true
ansible.builtin.command:
cmd: 'grubby --update-kernel=ALL --args="ipv6.disable=1"'
register: grubby_update_kernel
when: ansible_os_family == "RedHat"
changed_when: grubby_update_kernel.rc != 0
failed_when: grubby_update_kernel.rc != 0
tags:
- ipv6
- name: Configure sysctl to disable IPv6
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value | int }}"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
when: system_has_ipv6 and disable_ipv6
with_dict: "{{ ipv6_disable_sysctl_settings }}"
notify:
- Restart sysctl
tags:
- ipv6
@@ -0,0 +1,35 @@
---
- name: Add motd file
become: true
ansible.builtin.template:
src: etc/motd.j2
dest: /etc/motd
backup: true
mode: "0644"
owner: root
group: root
tags:
- motd
- CCE-80763-6
- CIS-UBUNTU2004-1.7.1
- CIS-UBUNTU2004-1.7.4
- name: Add issue and issue.net files
become: true
ansible.builtin.template:
src: etc/issue.j2
dest: "{{ item }}"
backup: true
mode: "0644"
owner: root
group: root
with_items:
- /etc/issue
- /etc/issue.net
tags:
- issue
- CCE-80763-6
- CIS-UBUNTU2004-1.7.2
- CIS-UBUNTU2004-1.7.3
- CIS-UBUNTU2004-1.7.5
- CIS-UBUNTU2004-1.7.6
@@ -0,0 +1,87 @@
---
- name: Configure systemd journald.conf
become: true
ansible.builtin.template:
src: etc/systemd/journald.conf.j2
dest: /etc/systemd/journald.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- systemd
- journald
- CIS-UBUNTU2004-4.2.2.1
- CIS-UBUNTU2004-4.2.2.2
- CIS-UBUNTU2004-4.2.2.3
- name: Configure logrotate(8)
become: true
ansible.builtin.template:
src: etc/logrotate.conf.j2
dest: /etc/logrotate.conf
backup: true
mode: "0644"
owner: root
group: root
tags:
- logrotate
- name: Configure cron.daily logrotate
become: true
ansible.builtin.lineinfile:
line: "/usr/sbin/logrotate /etc/logrotate.conf"
dest: /etc/cron.daily/logrotate
mode: "0750"
state: present
create: true
tags:
- cron
- logrotate
- name: Stat rsyslog.conf
become: true
ansible.builtin.stat:
path: /etc/rsyslog.conf
register: rsyslogconf
tags:
- rsyslog
- name: Stat rsyslog.conf FileCreateMode
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.shell: grep "^$FileCreateMode" /etc/rsyslog.conf
register: rsyslog_filecreatemode
changed_when: false
when: rsyslogconf.stat.exists
tags:
- rsyslog
- name: Configure rsyslog.conf FileCreateMode
become: true
ansible.builtin.lineinfile:
regexp: '^\$FileCreateMode'
line: "$FileCreateMode 0600"
dest: /etc/rsyslog.conf
mode: "0640"
state: present
create: false
when: rsyslogconf.stat.exists and rsyslog_filecreatemode.stdout.find('FileCreateMode') != -1
tags:
- rsyslog
- CIS-UBUNTU2004-4.2.1.4
- name: Add FileCreateMode file to the rsyslog.d directory
become: true
ansible.builtin.lineinfile:
regexp: '^\$FileCreateMode'
line: "$FileCreateMode 0600"
dest: /etc/rsyslog.d/99-filecreatemode.conf
mode: "0644"
state: present
create: true
tags:
- rsyslog
@@ -0,0 +1,42 @@
---
- name: Configure limits.conf
become: true
ansible.builtin.template:
src: etc/security/limits.conf.j2
dest: /etc/security/limits.conf
backup: true
mode: "0644"
owner: root
group: root
tags:
- limits
- CCE-80955-8
- CCE-81038-2
- CIS-UBUNTU2004-1.5.4
- UBTU-20-010400
- name: Configure coredump.conf
become: true
ansible.builtin.template:
src: etc/systemd/coredump.conf.j2
dest: /etc/systemd/coredump.conf
backup: true
mode: "0644"
owner: root
group: root
tags:
- coredump
- systemd
- CCE-82251-0
- CCE-82252-8
- CIS-UBUNTU2004-1.5.4
- name: Disable kdump service
become: true
ansible.builtin.systemd:
name: kdump.service
enabled: "no"
state: stopped
masked: "yes"
register: mask_kdump
failed_when: mask_kdump is not success and not "Could not find the requested service" in mask_kdump.msg
@@ -0,0 +1,11 @@
---
- name: Lock the root account
become: true
ansible.builtin.user:
name: root
password_lock: true
no_log: true
tags:
- users
- lock_root
...
@@ -0,0 +1,15 @@
---
- name: Configure systemd logind
become: true
ansible.builtin.template:
src: etc/systemd/logind.conf.j2
dest: /etc/systemd/logind.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- systemd
- logind
@@ -0,0 +1,31 @@
---
- name: Configure login.defs
become: true
ansible.builtin.template:
src: etc/login.defs.j2
dest: /etc/login.defs
backup: true
mode: "0644"
owner: root
group: root
tags:
- login
- CCE-26486-1
- CCE-27002-5
- CCE-27051-2
- CCE-27123-9
- CCE-27124-7
- CCE-80205-8
- CCE-80647-1
- CCE-80648-9
- CCE-80652-1
- CCE-82888-9
- CCE-80892-3
- CIS-UBUNTU2004-5.5.1.1
- CIS-UBUNTU2004-5.5.1.2
- CIS-UBUNTU2004-5.5.1.3
- CIS-UBUNTU2004-5.5.4
- UBTU-20-010007
- UBTU-20-010008
- UBTU-20-010016
- UBTU-20-010409
+155
View File
@@ -0,0 +1,155 @@
---
- name: Install local facts
ansible.builtin.include_tasks: facts.yml
tags: always
- name: Configure systemd resolved
ansible.builtin.include_tasks: resolvedconf.yml
tags: always
- name: Install epel-release and python dependencies
ansible.builtin.include_tasks: pre.yml
tags: always
- name: Install and configure UFW
ansible.builtin.include_tasks:
file: ufw.yml
apply:
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
when: ufw_enable
tags:
- ufw
- name: Configure sysctl
ansible.builtin.include_tasks: sysctl.yml
- name: Disable kernel network modules
ansible.builtin.include_tasks: disablenet.yml
- name: Disable file system kernel modules
ansible.builtin.include_tasks: disablefs.yml
- name: Disable IPv6
ansible.builtin.include_tasks: ipv6.yml
when: disable_ipv6
- name: Configure systemd system and users
ansible.builtin.include_tasks: systemdconf.yml
- name: Configure systemd journald and logrotate
ansible.builtin.include_tasks: journalconf.yml
- name: Configure systemd timesyncd
ansible.builtin.include_tasks: timesyncd.yml
- name: Clean fstab
ansible.builtin.include_tasks: fstab.yml
- name: Configure shm and tmp mounts
ansible.builtin.include_tasks: mount.yml
- name: Disable prelink
ansible.builtin.include_tasks: prelink.yml
- name: Configure package managers, update caches and install updates
ansible.builtin.include_tasks: packagemgmt.yml
- name: Configure hosts.allow and hosts.deny
when: not custom_hosts_acls
ansible.builtin.include_tasks: hosts.yml
- name: Configure login.defs
ansible.builtin.include_tasks: logindefs.yml
- name: Set limits
ansible.builtin.include_tasks: limits.yml
- name: Configure adduser and useradd
ansible.builtin.include_tasks: adduser.yml
- name: Restrict root access
ansible.builtin.include_tasks: rootaccess.yml
- name: Configure needrestart, install and remove various packages
ansible.builtin.include_tasks: packages.yml
- name: Configure ssh server and client
ansible.builtin.include_tasks: sshconfig.yml
- name: Configure PAM
ansible.builtin.include_tasks: password.yml
- name: Configure and clean at and cron
ansible.builtin.include_tasks: cron.yml
- name: Disable systemd ctrl-alt-del.target
ansible.builtin.include_tasks: ctrlaltdel.yml
- name: Configure auditd
ansible.builtin.include_tasks: auditd.yml
- name: Configure AppArmor
ansible.builtin.include_tasks: apparmor.yml
- name: Disable misc kernel modules
ansible.builtin.include_tasks: disablemod.yml
- name: Disable wireless interfaces
ansible.builtin.include_tasks: disablewireless.yml
when: disable_wireless
# https://bugs.launchpad.net/ubuntu/+source/aide/+bug/1903298
- name: Configure AIDE
ansible.builtin.include_tasks: aide.yml
when: >
install_aide | bool and
(not (ansible_os_family == "Debian" and
(ansible_lsb.codename == "groovy" or
ansible_lsb.codename == "hirsute")))
- name: Manage users
ansible.builtin.include_tasks: users.yml
- name: Remove suid/sgid permissions
ansible.builtin.include_tasks: suid.yml
when: suid_sgid_permissions | bool
- name: Configure compiler permissions
ansible.builtin.include_tasks: compilers.yml
- name: Set umask
ansible.builtin.include_tasks: umask.yml
- name: Configure paths
ansible.builtin.include_tasks: path.yml
- name: Configure systemd logind
ansible.builtin.include_tasks: logindconf.yml
- name: Configure rkhunter
ansible.builtin.include_tasks: rkhunter.yml
- name: Add issue message
ansible.builtin.include_tasks: issue.yml
- name: Configure apport
ansible.builtin.include_tasks: apport.yml
- name: Lock root account
ansible.builtin.include_tasks: lockroot.yml
- name: Configure Postfix
ansible.builtin.include_tasks: postfix.yml
- name: Configure motdnews
ansible.builtin.include_tasks: motdnews.yml
- name: Configure sudo
ansible.builtin.include_tasks: sudo.yml
- name: Miscellaneous extra tasks
ansible.builtin.include_tasks: extras.yml
- name: Miscellaneous tasks after all handlers
ansible.builtin.include_tasks: post.yml
@@ -0,0 +1,92 @@
---
- name: Stat /etc/default/motd-news
ansible.builtin.stat:
path: /etc/default/motd-news
register: motd_news
when: ansible_os_family == "Debian"
tags:
- motd
- name: Disable motd-news
become: true
ansible.builtin.lineinfile:
regexp: "^ENABLED="
line: "ENABLED=0"
dest: /etc/default/motd-news
mode: "0644"
state: present
create: false
backrefs: true
notify:
- Mask motdnews timer
- Mask motdnews service
when: ansible_os_family == "Debian" and motd_news.stat.exists
tags:
- motd
- name: Find update-motd.d files
become: true
ansible.builtin.find:
paths: /etc/update-motd.d
file_type: file
register: update_motd_permissions
tags:
- motd
- name: Update motd permissions
become: true
ansible.builtin.file:
dest: "{{ item.path }}"
mode: "0444"
with_items:
- "{{ update_motd_permissions.files }}"
when: ansible_os_family == "Debian"
tags:
- motd
- name: Set /etc/update-motd.d permission
become: true
ansible.builtin.file:
dest: /etc/update-motd.d
mode: "0755"
when: ansible_os_family == "Debian"
tags:
- motd
- name: Stat /usr/bin/pro
ansible.builtin.stat:
path: /usr/bin/pro
register: ubuntu_advantage_pro
when: ansible_os_family == "Debian"
tags:
- apt_news
- ubuntu-pro
- name: Check apt_news status
ansible.builtin.shell: |
set -o pipefail
pro config show | grep '^apt_news.*False'
args:
executable: /bin/bash
register: ubuntu_advantage_pro_state
changed_when: ubuntu_advantage_pro_state.rc != 0
failed_when: ubuntu_advantage_pro_state.rc > 1
when: ansible_os_family == "Debian" and ubuntu_advantage_pro.stat.exists
tags:
- apt_news
- ubuntu-pro
- name: Disable apt_news
become: true
ansible.builtin.command:
cmd: pro config set apt_news=false
register: disable_apt_news
changed_when: disable_apt_news.rc != 0
failed_when: disable_apt_news.rc != 0
when:
- ansible_os_family == "Debian"
- ubuntu_advantage_pro.stat.exists
- ubuntu_advantage_pro_state.rc != 0
tags:
- apt_news
- ubuntu-pro
@@ -0,0 +1,85 @@
---
- name: Mount /proc with additional options
become: true
ansible.posix.mount:
name: /proc
src: none
fstype: proc
opts: rw,nosuid,nodev,noexec,relatime,hidepid={{ hide_pid | int }},gid={{ process_group }}
state: present
tags:
- mount
- proc
- name: Stat /dev/shm
ansible.builtin.stat:
path: /dev/shm
register: dev_shm
tags:
- mount
- shm
- name: Mount /dev/shm with noexec
become: true
ansible.posix.mount:
name: /dev/shm
src: none
fstype: tmpfs
opts: rw,nosuid,nodev,noexec
state: present
when: dev_shm.stat.exists
tags:
- mount
- shm
- CCE-80837-8
- CCE-80838-6
- CCE-80839-4
- CIS-UBUNTU2004-1.1.7
- CIS-UBUNTU2004-1.1.8
- CIS-UBUNTU2004-1.1.9
- name: Add systemd tmp.mount
become: true
ansible.builtin.template:
src: etc/systemd/tmp.mount.j2
dest: /etc/systemd/system/tmp.mount
backup: true
mode: "0644"
owner: root
group: root
tags:
- mount
- tmp
- CCE-82139-7
- CCE-82140-5
- CCE-82623-0
- name: Stat tmp.mount
ansible.builtin.stat:
path: /etc/systemd/system/tmp.mount
register: tmp_mount
tags:
- mount
- tmp
- name: Unmask tmp.mount
become: true
ansible.builtin.systemd:
name: tmp.mount
masked: false
when: tmp_mount.stat.exists
tags:
- mount
- tmp
- name: Start tmp.mount
become: true
ansible.builtin.systemd:
name: tmp.mount
daemon_reload: true
state: started
enabled: true
when: tmp_mount.stat.exists
tags:
- mount
- tmp
@@ -0,0 +1,264 @@
---
- name: Configure apt
become: true
ansible.builtin.lineinfile:
dest: /etc/apt/apt.conf.d/98-hardening-ubuntu
mode: "0644"
state: present
create: true
line: "{{ item }}"
with_items:
- 'Acquire::AllowDowngradeToInsecureRepositories "false";'
- 'Acquire::AllowInsecureRepositories "false";'
- 'Acquire::http::AllowRedirect "false";'
- 'APT::Get::AllowUnauthenticated "false";'
- 'APT::Get::AutomaticRemove "true";'
- 'APT::Install-Recommends "false";'
- 'APT::Install-Suggests "false";'
- 'APT::Periodic::AutocleanInterval "7";'
- 'APT::Sandbox::Seccomp "1";'
- 'Unattended-Upgrade::Remove-Unused-Dependencies "true";'
- 'Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";'
- 'Unattended-Upgrade::Automatic-Reboot "{{ unattended_reboot }}";'
- 'Unattended-Upgrade::Automatic-Reboot-WithUsers "true";'
- 'Unattended-Upgrade::Automatic-Reboot-Time "{{ unattended_reboot_time }}";'
when: ansible_os_family == "Debian"
tags:
- apt
- M1045
- name: Run apt update
become: true
ansible.builtin.apt:
update_cache: true
cache_valid_time: 1800
notify:
- Run apt-get clean
- Run apt-get autoremove
when: ansible_os_family == "Debian"
tags:
- apt
- name: Run apt upgrade
become: true
ansible.builtin.apt:
upgrade: safe
register: apt_upgrade_response
changed_when: apt_upgrade_response.stdout.find('0 upgraded') == -1
when: ansible_os_family == "Debian" and system_upgrade | bool
tags:
- apt
- CIS-UBUNTU2004-1.9
- D3-SU
- M1051
- name: Link dnf.conf
become: true
ansible.builtin.file:
src: /etc/dnf/dnf.conf
dest: /etc/yum.conf
owner: root
group: root
state: link
when: ansible_distribution == "Fedora"
tags:
- dnf
- yum
- name: Import RedHat RPM key
become: true
ansible.builtin.rpm_key:
state: present
key: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{{ item }}
with_items:
- "{{ redhat_signing_keys }}"
when: ansible_os_family == "RedHat"
tags:
- dnf
- yum
- CCE-80795-8
- name: Set yum.conf gpgcheck
become: true
ansible.builtin.lineinfile:
regexp: "^gpgcheck="
line: "gpgcheck=1"
dest: /etc/yum.conf
mode: "0644"
state: present
create: false
backrefs: true
when: ansible_os_family == "RedHat"
tags:
- dnf
- yum
- CCE-80790-9
- CCE-80792-5
- M1045
- name: Set yum.conf clean_requirements
become: true
ansible.builtin.lineinfile:
line: "clean_requirements_on_remove=True"
dest: /etc/yum.conf
mode: "0644"
state: present
create: true
insertafter: "[main]"
when: ansible_os_family == "RedHat"
tags:
- dnf
- yum
- CCE-82476-3
- name: Set yum.conf localpkg_gpgcheck
become: true
ansible.builtin.lineinfile:
line: "localpkg_gpgcheck=1"
dest: /etc/yum.conf
mode: "0644"
state: present
create: true
insertafter: "[main]"
when: ansible_os_family == "RedHat"
tags:
- dnf
- yum
- CCE-80791-7
- M1045
- name: Comment yum.conf repo_gpgcheck
become: true
ansible.builtin.lineinfile:
line: "# repo_gpgcheck=1"
dest: /etc/yum.conf
mode: "0644"
state: present
create: true
insertafter: "[main]"
when: ansible_os_family == "RedHat"
tags:
- dnf
- yum
- name: RHEL8 package management tasks
when: ansible_distribution == "RedHat" and ansible_distribution_major_version == "8"
block:
- name: Import RHEL8 necessary GPG keys
become: true
ansible.builtin.rpm_key:
state: present
key: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{{ item }}
with_items:
- "{{ epel8_signing_keys }}"
tags:
- dnf
- packages
- yum
- name: RHEL8 EPEL repo installation
become: true
ansible.builtin.dnf:
name: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
state: present
tags:
- dnf
- packages
- yum
- name: Install CodeReady repo for RHEL8
become: true
ansible.builtin.command: subscription-manager repos --enable "codeready-builder-for-rhel-8-{{ ansible_architecture }}-rpms"
changed_when: false
- name: RHEL7 repo tasks
when: ansible_distribution == "RedHat" and ansible_distribution_major_version == "7"
block:
- name: Import RHEL7 necessary GPG keys
become: true
ansible.builtin.rpm_key:
state: present
key: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x{{ item }}
with_items:
- "{{ epel7_signing_keys }}"
tags:
- dnf
- packages
- yum
- name: RHEL7 EPEL repo installation
become: true
ansible.builtin.dnf:
name: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
state: present
tags:
- dnf
- packages
- yum
- name: Install Extras and HA for RHEL7
become: true
ansible.builtin.command: subscription-manager repos --enable "rhel-*-optional-rpms" --enable "rhel-*-extras-rpms" --enable "rhel-ha-for-rhel-*-server-rpms"
changed_when: false
tags:
- dnf
- packages
- yum
- name: Stat PowerTools repository files
ansible.builtin.stat:
path: "{{ item }}"
with_items:
- /etc/yum.repos.d/almalinux-crb.repo
- /etc/yum.repos.d/almalinux-powertools.repo
- /etc/yum.repos.d/CentOS-Linux-PowerTools.repo
- /etc/yum.repos.d/CentOS-PowerTools.repo
- /etc/yum.repos.d/CentOS-Stream-PowerTools.repo
register: powertools_repo
when: ansible_os_family == "RedHat"
tags:
- dnf
- packages
- yum
- name: Enable the PowerTools repository
become: true
ansible.builtin.replace:
regexp: "^enabled=.*$"
replace: "enabled=1"
dest: "{{ item.stat.path }}"
with_items:
- "{{ powertools_repo.results }}"
when: ansible_os_family == "RedHat" and item.stat.exists
tags:
- dnf
- packages
- yum
- name: Update dnf cache
become: true
ansible.builtin.dnf:
update_cache: true
when: ansible_os_family == "RedHat"
notify:
- Run dnf autoremove
tags:
- dnf
- yum
- name: Run dnf upgrade
become: true
ansible.builtin.dnf:
name: "*" # noqa package-latest
state: latest
bugfix: true
security: true
nobest: true
when: ansible_os_family == "RedHat" and system_upgrade | bool
tags:
- dnf
- yum
- CCE-80865-9
- D3-SU
- M1051
@@ -0,0 +1,222 @@
---
- name: Merge package lists
ansible.builtin.set_fact:
packages_merged: "{{ packages_debian + packages_redhat + packages_ubuntu }}"
tags:
- packages
- name: Configure needrestart
tags:
- needrestart
- packages
block:
- name: Pre register needrestart configuration directory
become: true
ansible.builtin.stat:
path: /etc/needrestart/conf.d
register: needrestart_directory_created
- name: Create needrestart directory
become: true
ansible.builtin.file:
path: /etc/needrestart/conf.d
state: directory
owner: root
group: root
mode: "0755"
recurse: true
when: ("needrestart" in packages_merged) and not needrestart_directory_created.stat.exists
- name: Stat needrestart configuration directory
become: true
ansible.builtin.stat:
path: /etc/needrestart/conf.d
register: needrestart_directory
- name: Get needrestart restart value
ansible.builtin.command:
cmd: grep -Rqo "$nrconf{restart} = 'l';" /etc/needrestart/conf.d/
register: needrestart_restart_set
when: needrestart_directory.stat.exists
changed_when: needrestart_restart_set.rc != 0
failed_when: needrestart_restart_set.rc > 1
- name: Configure needrestart
become: true
ansible.builtin.lineinfile:
path: /etc/needrestart/conf.d/00-restart.conf
line: "$nrconf{restart} = 'l';"
create: true
owner: root
group: root
mode: "0644"
when: needrestart_directory.stat.exists and needrestart_restart_set.rc != 0
- name: Debian family package installation
become: true
ansible.builtin.apt:
name: "{{ packages_debian }}"
state: present
install_recommends: false
when: ansible_os_family == "Debian"
tags:
- packages
- CIS-UBUNTU2004-1.6.1.1
- CIS-UBUNTU2004-4.1.1.1
- CIS-UBUNTU2004-4.2.1.1
- M1049
- UBTU-20-010005
- name: Ubuntu package installation
become: true
ansible.builtin.apt:
name: "{{ packages_ubuntu }}"
state: present
install_recommends: false
when: ansible_distribution == "Ubuntu"
tags:
- packages
- name: Ubuntu update-notifier-common package installation
become: true
ansible.builtin.apt:
name: "update-notifier-common"
state: present
install_recommends: false
when: ansible_distribution == "Ubuntu"
tags:
- packages
- name: RedHat family package installation
become: true
ansible.builtin.dnf:
name: "{{ packages_redhat }}"
state: present
when: ansible_os_family == "RedHat"
notify:
- Enable haveged
tags:
- packages
- CCE-80847-7
- CCE-81043-2
- CCE-82859-0
- CCE-83303-8
- M1049
- name: Run apt purge
become: true
ansible.builtin.apt:
name: "{{ packages_blocklist }}"
state: absent
purge: true
when: ansible_os_family == "Debian"
register: apt_purge
failed_when: apt_purge is not success and not "No package" in apt_purge.msg
tags:
- packages
- M1042
- name: Generic package removal
become: true
ansible.builtin.package:
name: "{{ packages_blocklist }}"
state: absent
register: package_removal
failed_when: package_removal is not success and not "No package" in package_removal.msg
tags:
- packages
- CCE-80873-3
- CCE-82182-7
- CCE-82184-3
- CCE-82436-7
- CIS-UBUNTU2004-1.1.23
- CIS-UBUNTU2004-1.5.3
- CIS-UBUNTU2004-2.1.3
- CIS-UBUNTU2004-2.1.16
- CIS-UBUNTU2004-2.2.2
- CIS-UBUNTU2004-2.2.3
- CIS-UBUNTU2004-2.2.4
- CIS-UBUNTU2004-2.2.6
- M1042
- name: VirtualBox guest packages installation
become: true
ansible.builtin.apt:
name: "{{ packages }}"
state: present
install_recommends: false
vars:
packages:
- virtualbox-guest-dkms
- virtualbox-guest-utils
register: virtualbox_packages
when: ansible_virtualization_type == "VirtualBox" and
ansible_distribution == "Ubuntu"
failed_when: virtualbox_packages is not success and not "No package matching" in virtualbox_packages.msg
tags:
- packages
- virtualbox
- name: VMWare package installation
become: true
ansible.builtin.package:
name: open-vm-tools
state: present
when: ansible_virtualization_type == "VMware"
tags:
- packages
- vmware
- name: QEMU package installation
become: true
ansible.builtin.package:
name: qemu-guest-agent
state: present
when: ansible_system_vendor == "QEMU"
tags:
- packages
- qemu
- name: Install rng-tools
become: true
ansible.builtin.package:
name: rng-tools
state: present
when: ansible_local.cpuinfo.rdrand
tags:
- rng-tools
- packages
- CCE-82968-9
- name: Stat sysstat default
become: true
ansible.builtin.stat:
path: /etc/default/sysstat
register: default_sysstat
tags:
- packages
- sysstat
- name: Enable sysstat
become: true
ansible.builtin.lineinfile:
regexp: "^ENABLED"
line: 'ENABLED="true"'
dest: /etc/default/sysstat
mode: "0644"
state: present
create: false
backrefs: true
when: default_sysstat.stat.exists
tags:
- packages
- sysstat
- name: Remove unneeded Debian dependencies
become: true
ansible.builtin.apt:
autoclean: true
autoremove: true
when: ansible_os_family == "Debian"
tags:
- packages
@@ -0,0 +1,297 @@
---
- name: Stat faillock
become: true
ansible.builtin.find:
paths:
[
"/usr/local/sbin",
"/usr/local/bin",
"/usr/sbin",
"/usr/bin",
"/sbin",
"/bin",
"/snap/bin",
]
patterns: "faillock"
recurse: true
register: faillock
tags:
- common-account
- common-auth
- pam
- name: Stat faillock configuration file
become: true
ansible.builtin.stat:
path: /etc/security/faillock.conf
register: faillockconf
tags:
- common-account
- common-auth
- pam
- name: Configure faillock.conf
become: true
ansible.builtin.lineinfile:
dest: /etc/security/faillock.conf
mode: "0644"
state: present
line: "{{ item }}"
with_items:
- "audit"
- "local_users_only"
- "deny = 5"
- "fail_interval = 900"
when: faillockconf.stat.exists
tags:
- common-account
- common-auth
- pam
- name: Debian OS family PAM configuration
become: true
when: ansible_os_family == "Debian"
block:
- name: Configure common-password
ansible.builtin.template:
src: etc/pam.d/common-password.j2
dest: /etc/pam.d/common-password
backup: true
mode: "0644"
owner: root
group: root
tags:
- common-password
- pam
- CIS-UBUNTU2004-5.4.3
- CIS-UBUNTU2004-5.4.4
- UBTU-20-010070
- name: Configure common-auth
ansible.builtin.template:
src: etc/pam.d/common-auth.j2
dest: /etc/pam.d/common-auth
backup: true
mode: "0644"
owner: root
group: root
tags:
- common-auth
- pam
- CIS-UBUNTU2004-5.4.2
- M1036
- UBTU-20-010072
- name: Configure common-account
ansible.builtin.template:
src: etc/pam.d/common-account.j2
dest: /etc/pam.d/common-account
backup: true
mode: "0644"
owner: root
group: root
tags:
- common-account
- pam
- M1036
- name: Configure login
ansible.builtin.template:
src: etc/pam.d/login.j2
dest: /etc/pam.d/login
backup: true
mode: "0644"
owner: root
group: root
tags:
- login
- pam
- UBTU-20-010075
- name: RedHat OS family PAM configuration
become: true
when: ansible_os_family == "RedHat"
block:
- name: Remove nullok from system-auth
ansible.builtin.replace:
dest: /etc/pam.d/system-auth
regexp: "nullok"
mode: "0644"
owner: root
group: root
tags:
- system-auth
- pam
- CCE-80841-0
- name: Remove nullok from password-auth
ansible.builtin.replace:
dest: /etc/pam.d/password-auth
regexp: "nullok"
mode: "0644"
owner: root
group: root
tags:
- password-auth
- pam
- name: Remove nullok from sssd-shadowutils
become: true
ansible.builtin.replace:
dest: /etc/pam.d/sssd-shadowutils
regexp: "nullok"
mode: "0644"
owner: root
group: root
tags:
- sssd-shadowutils
- pam
- name: Set system-auth remember
ansible.builtin.replace:
regexp: 'use_authtok(\s+.*)'
replace: "use_authtok remember=5"
dest: /etc/pam.d/system-auth
mode: "0644"
owner: root
group: root
tags:
- system-auth
- CCE-80666-1
- name: Configure pwquality
become: true
ansible.builtin.lineinfile:
path: /etc/security/pwquality.conf
line: "{{ item.key }} = {{ item.value }}"
regexp: ".*{{ item.key }} = "
state: present
mode: "0644"
owner: root
group: root
with_dict: "{{ pwquality_config }}"
tags:
- pwquality
- pam
- CCE-80653-9
- CCE-80654-7
- CCE-80655-4
- CCE-80656-2
- CCE-80663-8
- CCE-80665-3
- CCE-82066-2
- CCE-82046-4
- CIS-UBUNTU2004-5.4.1
- D3-SPP
- M1027
- UBTU-20-010050
- UBTU-20-010051
- UBTU-20-010052
- UBTU-20-010053
- UBTU-20-010054
- UBTU-20-010055
- UBTU-20-010056
- UBTU-20-010057
- name: Stat libuser configuration
become: true
ansible.builtin.stat:
path: /etc/libuser.conf
register: libuser
tags:
- libuser
- name: Set libuser crypt_style to sha512
become: true
ansible.builtin.replace:
regexp: 'crypt_style(\s+.*)'
replace: "crypt_style = sha512"
dest: /etc/libuser.conf
mode: "0644"
owner: root
group: root
when: libuser.stat.exists
tags:
- libuser
- CCE-80891-5
- name: Stat crypto-policies config
become: true
ansible.builtin.stat:
path: /etc/crypto-policies/config
register: crypto_policies_config
tags:
- crypto-policy
- name: Get crypto-policies value
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.builtin.command: grep -qo "^{{ crypto_policy }}$" /etc/crypto-policies/config
register: crypto_policy_set
when: crypto_policies_config.stat.exists
changed_when: crypto_policy_set.rc != 0
failed_when: crypto_policy_set.rc > 1
tags:
- crypto-policy
- M1041
- name: Set crypto-policies
become: true
ansible.builtin.command: update-crypto-policies --set "{{ crypto_policy | upper }}"
register: set_crypto_policies
changed_when: set_crypto_policies.rc != 0
failed_when: set_crypto_policies.rc != 0
when: crypto_policies_config.stat.exists and crypto_policy_set.rc != 0
tags:
- crypto-policy
- CCE-80935-0
- M1041
- name: Set FIPS mode
become: true
ansible.builtin.command: fips-mode-setup --enable # noqa no-changed-when
when: crypto_policies_config.stat.exists and crypto_policy_set.rc != 0 and crypto_policy.upper == "FIPS"
tags:
- crypto-policy
- CCE-80935-0
- CCE-80942-6
- CCE-84027-2
- M1041
- name: Add cracklib password list
become: true
ansible.builtin.copy:
src: usr/share/dict/passwords.list
dest: /usr/share/dict/passwords
backup: true
mode: "0644"
owner: root
group: root
notify:
- Update Debian cracklib
- Update RedHat cracklib
tags:
- cracklib
- pam
- name: Add local information to password list
become: true
ansible.builtin.lineinfile:
dest: /usr/share/dict/passwords.local
mode: "0644"
owner: root
group: root
state: present
create: true
line: "{{ item }}"
notify:
- Update Debian cracklib
- Update RedHat cracklib
with_items:
- "{{ ansible_hostname | lower }}"
- "{{ ansible_hostname | upper }}"
- "{{ ansible_os_family | lower }}"
- "{{ ansible_os_family | upper }}"
tags:
- cracklib
- pam
@@ -0,0 +1,27 @@
---
- name: Set path
become: true
ansible.builtin.lineinfile:
regexp: "^PATH="
line: 'PATH="/usr/local/bin:/usr/sbin:/usr/bin:/bin:/snap/bin"'
dest: /etc/environment
mode: "0644"
state: present
create: false
backrefs: true
tags:
- path
- M1038
- name: Add path script
become: true
ansible.builtin.template:
src: etc/profile.d/initpath.sh.j2
dest: /etc/profile.d/initpath.sh
backup: true
mode: "0644"
owner: root
group: root
tags:
- path
- M1038
@@ -0,0 +1,94 @@
---
- name: Create /boot/grub directory if efi boot
become: true
ansible.builtin.file:
path: /boot/grub
state: directory
mode: "0755"
owner: root
group: root
when: booted_with_efi | bool
tags:
- grub
- name: Run all notified handlers
ansible.builtin.meta: flush_handlers
- name: Stat RedHat auditd GRUB settings
become: true
ansible.builtin.shell:
cmd: |
set -o pipefail
grubby --info="/boot/vmlinuz-$(uname -r)" | grep "^args.*{{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}"
changed_when: false
failed_when: false
args:
executable: /bin/bash
register: audit_grubenv
when: ansible_os_family == "RedHat"
ignore_errors: true
tags:
- auditd
- grub
- name: Update grub2 if missing GRUB settings
become: true
ansible.builtin.command:
cmd: grub2-mkconfig
register: update_grub_redhat
changed_when: update_grub_redhat.rc != 0
failed_when: update_grub_redhat.rc != 0
when: ansible_os_family == "RedHat" and audit_grubenv.rc != 0
tags:
- auditd
- grub
- name: Stat Debian auditd GRUB settings
become: true
ansible.builtin.shell: grep "linux.*{{ grub_audit_cmdline }} {{ grub_audit_backlog_cmdline }}" /boot/grub/grub.cfg
changed_when: audit_grub_cfg.rc != 0
failed_when: audit_grub_cfg.rc != 0
register: audit_grub_cfg
ignore_errors: true
when: ansible_os_family == "Debian"
tags:
- auditd
- grub
- name: Update GRUB if settings are missing
become: true
ansible.builtin.command:
cmd: update-grub
register: update_grub_debian
changed_when: update_grub_debian.rc != 0
failed_when: update_grub_debian.rc != 0
when: ansible_os_family == "Debian" and audit_grub_cfg.rc != 0
tags:
- auditd
- grub
- name: Find GRUB config files
become: true
ansible.builtin.find:
paths: /boot
patterns: "*.cfg,grubenv"
recurse: true
register: grub_cfg
tags:
- grub
- CIS-UBUNTU2004-1.4.3
- name: Set GRUB config permissions
become: true
ansible.builtin.file:
path: "{{ item.path }}"
mode: "0400"
when: item.mode | int > 400
changed_when: false
with_items:
- "{{ grub_cfg.files | reject('search', '/boot/efi/EFI/ubuntu/grub.cfg') | list }}"
loop_control:
label: "{{ item.path }}"
tags:
- grub
- CIS-UBUNTU2004-1.4.3
@@ -0,0 +1,56 @@
---
- name: Stat postfix main.cf
ansible.builtin.stat:
path: /etc/postfix/main.cf
register: postfix_main_cf
tags:
- packages
- postfix
- name: Configure Postfix disable_vrfy_command
become: true
ansible.builtin.lineinfile:
regexp: "^disable_vrfy_command"
dest: /etc/postfix/main.cf
line: "disable_vrfy_command = yes"
state: present
when: postfix_main_cf.stat.exists
tags:
- packages
- postfix
- name: Configure Postfix inet_interfaces
become: true
ansible.builtin.lineinfile:
regexp: "^inet_interfaces"
dest: /etc/postfix/main.cf
line: "inet_interfaces = loopback-only"
state: present
when: postfix_main_cf.stat.exists
tags:
- packages
- postfix
- name: Configure Postfix smtpd_banner
become: true
ansible.builtin.lineinfile:
regexp: "^smtpd_banner"
dest: /etc/postfix/main.cf
line: 'smtpd_banner = \$myhostname - ESMTP'
state: present
when: postfix_main_cf.stat.exists
tags:
- packages
- postfix
- name: Configure Postfix smtpd_client_restrictions
become: true
ansible.builtin.lineinfile:
regexp: "^smtpd_client_restrictions"
dest: /etc/postfix/main.cf
line: "smtpd_client_restrictions = permit_mynetworks,reject"
when: postfix_main_cf.stat.exists
tags:
- packages
- postfix
...
+119
View File
@@ -0,0 +1,119 @@
---
- name: Update subscription info on RHEL
become: true
ansible.builtin.command: subscription-manager refresh --force
changed_when: false
when: ansible_distribution == "RedHat"
tags:
- subscription
- name: RedHat family EPEL installation
become: true
ansible.builtin.dnf:
name: "epel-release"
state: present
update_cache: true
when: ansible_os_family == "RedHat" and (not (ansible_distribution == "Fedora" or ansible_distribution == "RedHat"))
tags:
- dnf
- packages
- yum
- name: Install python-pexpect
become: true
ansible.builtin.apt:
name: python-pexpect
state: present
update_cache: true
when: ansible_os_family == "Debian" and ansible_python.version.major <= 2
tags:
- apt
- packages
- python
- name: Install python3-pexpect
become: true
ansible.builtin.apt:
name: python3-pexpect
state: present
update_cache: true
when: ansible_os_family == "Debian" and ansible_python.version.major >= 3
tags:
- apt
- packages
- python
- name: Install python2-rpm
become: true
ansible.builtin.dnf:
name: "python2-rpm"
state: present
when: ansible_distribution == "RedHat" and ansible_python.version.major <= 2
tags:
- dnf
- packages
- python
- yum
- name: Install python3-rpm
become: true
ansible.builtin.dnf:
name: "python3-rpm"
state: present
when: ansible_distribution == "RedHat" and ansible_python.version.major >= 3
tags:
- dnf
- packages
- python
- yum
- name: Install python3-passlib
become: true
ansible.builtin.package:
name: python3-passlib
state: present
register: python3_passlib
failed_when:
- python3_passlib.rc is defined
- python3_passlib.rc != 0
- not ansible_distribution == "AlmaLinux"
tags:
- apt
- dnf
- packages
- python
- yum
- name: Install Python pip
when:
- python3_passlib.rc is defined
- python3_passlib.rc != 0
block:
- name: Python3-pip installation
become: true
ansible.builtin.package:
name: "python3-pip"
state: present
tags:
- dnf
- packages
- python
- yum
- name: Pip passlib installation
become: true
ansible.builtin.pip:
name: "passlib"
state: present
tags:
- dnf
- packages
- python
- yum
- name: EFI or UEFI booting check
ansible.builtin.set_fact:
booted_with_efi: "{{ ansible_mounts | selectattr('mount', 'equalto', '/boot/efi') | list | length > 0 }}"
tags:
- fact
...
@@ -0,0 +1,34 @@
---
- name: Configure sysconfig prelink
ansible.builtin.stat:
path: /etc/sysconfig/prelink
register: sysconfig_prelink
tags:
- prelink
- name: Stat prelink configuration file
ansible.builtin.stat:
path: /etc/prelink.conf
register: etc_prelink
tags:
- prelink
- name: Disable prelinking
become: true
ansible.builtin.lineinfile:
line: "PRELINKING=no"
dest: /etc/sysconfig/prelink
mode: "0644"
state: present
create: true
when: ansible_os_family == "RedHat" and sysconfig_prelink.stat.exists
tags:
- prelink
- name: Return to non-prelinked state
become: true
ansible.builtin.command: prelink -ua # noqa no-changed-when
when: sysconfig_prelink.stat.exists or etc_prelink.stat.exists
tags:
- prelink
- CIS-UBUNTU2004-1.5.3
@@ -0,0 +1,30 @@
---
- name: Configure systemd resolved
become: true
ansible.builtin.template:
src: etc/systemd/resolved.conf.j2
dest: /etc/systemd/resolved.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- resolved
- systemd
- CCE-84049-6
- name: Add nameservers to resolv.conf
become: true
ansible.builtin.lineinfile:
dest: /etc/resolv.conf
line: "nameserver {{ item }}"
mode: "0644"
owner: root
group: root
state: present
with_items: "{{ dns | split }}"
when: ansible_os_family == "RedHat"
tags:
- resolved
@@ -0,0 +1,51 @@
---
- name: Configure rkhunter
become: true
ansible.builtin.template:
src: etc/default/rkhunter.j2
dest: /etc/default/rkhunter
backup: true
mode: "0644"
owner: root
group: root
when: ansible_os_family == "Debian"
notify:
- Run rkhunter propupd
tags:
- packages
- rkhunter
- M1049
- name: SSH root access should be disabled
become: true
ansible.builtin.lineinfile:
regexp: "ALLOW_SSH_ROOT_USER"
line: "ALLOW_SSH_ROOT_USER=no"
dest: /etc/rkhunter.conf
mode: "0640"
state: present
create: false
backrefs: true
notify:
- Run rkhunter propupd
tags:
- packages
- rkhunter
- M1049
- name: SSH v1 should not be used
become: true
ansible.builtin.lineinfile:
regexp: "ALLOW_SSH_PROT_V1"
line: "ALLOW_SSH_PROT_V1=0"
dest: /etc/rkhunter.conf
mode: "0640"
state: present
create: false
backrefs: true
notify:
- Run rkhunter propupd
tags:
- packages
- rkhunter
- M1049
@@ -0,0 +1,70 @@
---
- name: Stat access.conf
become: true
ansible.builtin.stat:
path: /etc/security/access.conf
register: security_access_conf
tags:
- access_conf
- name: Stat securetty
become: true
ansible.builtin.stat:
path: /etc/securetty
register: etc_securetty
tags:
- securetty
- name: Clean access.conf
become: true
ansible.builtin.lineinfile:
path: /etc/security/access.conf
regexp: '^(?!\+:root:127.0.0.1)$'
mode: "0644"
state: absent
when: security_access_conf.stat.exists
tags:
- access_conf
- name: Allow localhost root in access.conf
become: true
ansible.builtin.lineinfile:
path: /etc/security/access.conf
line: "+:root:127.0.0.1"
mode: "0644"
state: present
when: security_access_conf.stat.exists
tags:
- access_conf
- name: Clean securetty
become: true
ansible.builtin.lineinfile:
path: /etc/securetty
regexp: "^(?!console).*$"
state: absent
when: etc_securetty.stat.exists
tags:
- securetty
- name: Allow console in securetty
become: true
ansible.builtin.lineinfile:
path: /etc/securetty
line: "console"
mode: "0644"
state: present
when: etc_securetty.stat.exists
tags:
- securetty
- CIS-UBUNTU2004-5.6
- name: Mask systemd debug-shell
become: true
ansible.builtin.systemd:
name: debug-shell.service
masked: true
tags:
- systemd
- debug-shell
- CCE-80876-6
@@ -0,0 +1,242 @@
---
- name: Get installed ssh version
ansible.builtin.command:
cmd: ssh -V
changed_when: false
failed_when: false
register: ssh_version
tags:
- sshd
- sshd_config
- name: Set ssh version as fact
ansible.builtin.set_fact:
ssh_installed_version: "{{ ssh_version.stderr | regex_search('^OpenSSH_([0-9+].[0-9]+)', '\\1') | join('.') | float }}" # noqa jinja[spacing]
tags:
- sshd
- sshd_config
- name: Stat sysconfig sshd configuration
ansible.builtin.stat:
path: /etc/sysconfig/sshd
register: sysconfig_sshd
tags:
- sshd
- sshd_config
- M1041
- name: Remove sshd system crypto policy
become: true
ansible.builtin.lineinfile:
dest: /etc/sysconfig/sshd
state: absent
regexp: ^\s*CRYPTO_POLICY.*$
when: sysconfig_sshd.stat.exists
tags:
- sshd
- CCE-80939-2
- M1041
- name: Get sshd Include config
become: true
ansible.builtin.command: grep -E "^Include " /etc/ssh/sshd_config
register: grep_include
changed_when: false
failed_when: false
tags:
- sshd
- sshd_config
- M1041
- name: Check if sshd_config.d exits
ansible.builtin.stat:
path: /etc/ssh/sshd_config.d
register: sshd_config_d
tags:
- sshd
- sshd_config
- M1041
- name: Ensure /etc/ssh/sshd_config permissions
become: true
ansible.builtin.file:
path: /etc/ssh/sshd_config
owner: root
group: root
mode: "0600"
tags:
- sshd
- sshd_config
- name: Configure sshd
become: true
ansible.builtin.template:
src: etc/ssh/sshd_config.j2
dest: /etc/ssh/sshd_config
backup: true
mode: "0600"
owner: root
group: root
validate: sshd -t -f %s
when: not sshd_config_d.stat.exists or grep_include.rc != 0
notify:
- Restart sshd service
- Restart ssh service
tags:
- sshd
- sshd_config
- CCE-80895-6
- CCE-80896-4
- CCE-80897-2
- CCE-80898-0
- CCE-80901-2
- CCE-80902-0
- CCE-80903-8
- CCE-80904-6
- CCE-80905-3
- CCE-80906-1
- CCE-82177-7
- CCE-82281-7
- CCE-83360-8
- CIS-UBUNTU2004-5.3.1
- CIS-UBUNTU2004-5.3.4
- CIS-UBUNTU2004-5.3.5
- CIS-UBUNTU2004-5.3.6
- CIS-UBUNTU2004-5.3.7
- CIS-UBUNTU2004-5.3.8
- CIS-UBUNTU2004-5.3.9
- CIS-UBUNTU2004-5.3.10
- CIS-UBUNTU2004-5.3.11
- CIS-UBUNTU2004-5.3.12
- CIS-UBUNTU2004-5.3.13
- CIS-UBUNTU2004-5.3.14
- CIS-UBUNTU2004-5.3.15
- CIS-UBUNTU2004-5.3.16
- CIS-UBUNTU2004-5.3.17
- CIS-UBUNTU2004-5.3.18
- CIS-UBUNTU2004-5.3.19
- CIS-UBUNTU2004-5.3.20
- CIS-UBUNTU2004-5.3.21
- CIS-UBUNTU2004-5.3.22
- M1041
- UBTU-20-010036
- UBTU-20-010037
- name: Configure sshd using sshd_config.d
become: true
ansible.builtin.template:
src: etc/ssh/sshd_config.j2
dest: /etc/ssh/sshd_config.d/01-hardening.conf
backup: true
mode: "0600"
owner: root
group: root
validate: sshd -t -f %s
when: sshd_config_d.stat.exists and grep_include.rc == 0
notify:
- Restart sshd service
- Restart ssh service
tags:
- sshd
- sshd_config
- CCE-80895-6
- CCE-80896-4
- CCE-80897-2
- CCE-80898-0
- CCE-80901-2
- CCE-80902-0
- CCE-80903-8
- CCE-80904-6
- CCE-80905-3
- CCE-80906-1
- CCE-82177-7
- CCE-82281-7
- CCE-83360-8
- CIS-UBUNTU2004-5.3.1
- CIS-UBUNTU2004-5.3.4
- CIS-UBUNTU2004-5.3.5
- CIS-UBUNTU2004-5.3.6
- CIS-UBUNTU2004-5.3.7
- CIS-UBUNTU2004-5.3.8
- CIS-UBUNTU2004-5.3.9
- CIS-UBUNTU2004-5.3.10
- CIS-UBUNTU2004-5.3.11
- CIS-UBUNTU2004-5.3.12
- CIS-UBUNTU2004-5.3.13
- CIS-UBUNTU2004-5.3.14
- CIS-UBUNTU2004-5.3.15
- CIS-UBUNTU2004-5.3.16
- CIS-UBUNTU2004-5.3.17
- CIS-UBUNTU2004-5.3.18
- CIS-UBUNTU2004-5.3.19
- CIS-UBUNTU2004-5.3.20
- CIS-UBUNTU2004-5.3.21
- CIS-UBUNTU2004-5.3.22
- M1041
- UBTU-20-010036
- UBTU-20-010037
- name: Remove possible Subsystem duplicate
become: true
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config
regexp: ^Subsystem.*
state: absent
when: sshd_config_d.stat.exists and grep_include.rc == 0
tags:
- sshd
- sshd_config
- name: Stat sshd host keys
become: true
ansible.builtin.find:
paths: /etc/ssh
file_type: file
patterns: "ssh_host_*"
excludes: "*.pub"
register: ssh_host_keys
tags:
- sshd
- M1022
- M1041
- name: Set sshd host key permissions
become: true
ansible.builtin.file:
owner: root
group: root
mode: "0600"
path: "{{ item.path }}"
with_items: "{{ ssh_host_keys.files }}"
loop_control:
label: "{{ item.path }}"
tags:
- sshd
- CCE-82424-3
- CIS-UBUNTU2004-5.3.2
- M1022
- M1041
- name: Check if ssh_config.d exits
ansible.builtin.stat:
path: /etc/ssh/ssh_config.d
register: ssh_config_d
tags:
- ssh
- ssh_config
- M1041
- name: Configure ssh client
become: true
ansible.builtin.template:
src: etc/ssh/ssh_config.j2
dest: /etc/ssh/ssh_config
backup: true
mode: "0644"
owner: root
group: root
tags:
- ssh
- ssh_config
- CCE-82880-6
- M1041
+128
View File
@@ -0,0 +1,128 @@
---
- name: Configure sudo
become: true
tags:
- sudo
block:
- name: Configure sudo use_pty
become: true
ansible.builtin.lineinfile:
line: "Defaults use_pty"
dest: /etc/sudoers.d/011_use_pty
mode: "0440"
state: present
create: true
validate: visudo -cf %s
tags:
- CIS-UBUNTU2004-5.2.2
- name: Configure sudo logfile
become: true
ansible.builtin.lineinfile:
line: 'Defaults logfile="/var/log/sudo.log"'
dest: /etc/sudoers.d/012_logfile
mode: "0440"
state: present
create: true
validate: visudo -cf %s
tags:
- CIS-UBUNTU2004-5.2.3
- name: Configure sudo disable pwfeedback
become: true
ansible.builtin.lineinfile:
line: "Defaults !pwfeedback"
dest: /etc/sudoers.d/013_pwfeedback
mode: "0440"
state: present
create: true
validate: visudo -cf %s
- name: Configure sudo disable visiblepw
become: true
ansible.builtin.lineinfile:
line: "Defaults !visiblepw"
dest: /etc/sudoers.d/014_visiblepw
mode: "0440"
state: present
create: true
validate: visudo -cf %s
- name: Remove inconsistently named sudoer file
become: true
ansible.builtin.file:
path: /etc/sudoers.d/15_timeout
state: absent
- name: Configure sudo passwd_timeout
become: true
ansible.builtin.lineinfile:
line: "Defaults passwd_timeout=1"
dest: /etc/sudoers.d/015_passwdtimeout
mode: "0440"
state: present
create: true
validate: visudo -cf %s
- name: Configure sudo timestamp_timeout
become: true
ansible.builtin.lineinfile:
line: "Defaults timestamp_timeout=5"
dest: /etc/sudoers.d/016_timestamptimeout
mode: "0440"
state: present
create: true
validate: visudo -cf %s
- name: Configure sudo timestamp_type
become: true
ansible.builtin.lineinfile:
line: "Defaults timestamp_type=tty"
dest: /etc/sudoers.d/017_timestamptype
mode: "0440"
state: present
create: true
validate: visudo -cf %s
tags:
- M1028
- name: Configure sudo user password for privilege escalation
become: true
ansible.builtin.lineinfile:
line: "Defaults {{ item }}"
dest: /etc/sudoers.d/018_userpassword
mode: "0440"
state: present
create: true
validate: visudo -cf %s
with_items:
- "!rootpw"
- "!runaspw"
- "!targetpw"
tags:
- V-237642
- name: Create su group sugroup
become: true
ansible.builtin.group:
name: sugroup
state: present
tags:
- pam
- su
- sudo
- CIS-UBUNTU2004-5.7
- name: Configure su group
become: true
ansible.builtin.lineinfile:
line: "auth required pam_wheel.so use_uid group=sugroup"
dest: /etc/pam.d/su
mode: "0644"
state: present
create: true
tags:
- pam
- su
- sudo
- CIS-UBUNTU2004-5.7
@@ -0,0 +1,42 @@
---
- name: Remove risky suid bits
tags:
- suid
- CIS-UBUNTU2004-6.1.13
- CIS-UBUNTU2004-6.1.14
block:
- name: Find possible suid binaries
ansible.builtin.shell: |
command -v "{{ item }}"
args:
executable: /bin/bash
with_items:
- "{{ suid_sgid_blocklist }}"
register: find_result
changed_when: false
failed_when: false
- name: Stat permissions
ansible.builtin.stat:
path: "{{ item.stdout }}"
check_mode: true
register: suid_file
when:
- item.rc == 0
with_items:
- "{{ find_result.results }}"
- name: Remove suid/sgid permissions
become: true
ansible.builtin.file:
path: "{{ item.stat.path }}"
mode: 'a-s'
state: file
follow: true
when:
- item.stat.mode is defined
- item.stat.mode | int >= 2000
- item.stat.mode | int <= 5000
with_items:
- "{{ suid_file.results }}"
...
@@ -0,0 +1,94 @@
---
- name: Set sysctl dev.tty.ldisc_autoload
become: true
ansible.posix.sysctl:
name: dev.tty.ldisc_autoload
value: "{{ sysctl_dev_tty_ldisc_autoload | int }}"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
when: ansible_kernel is version("5", ">=")
tags:
- sysctl
- name: Set sysctl net.ipv6.conf.accept_ra_rtr_pref
become: true
ansible.posix.sysctl:
name: net.ipv6.conf.{{ ansible_default_ipv4.interface }}.accept_ra_rtr_pref
value: "{{ sysctl_net_ipv6_conf_accept_ra_rtr_pref | int }}"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
when: system_has_ipv6
tags:
- ipv6
- sysctl
- name: Sysctl rules if the system has ipv6
ansible.builtin.set_fact:
sysctl_settings: "{{ generic_sysctl_settings | combine(ipv4_sysctl_settings) | combine(ipv6_sysctl_settings) }}"
when: system_has_ipv6
tags:
- ipv6
- sysctl
- name: Sysctl rules if the system does not have ipv6
ansible.builtin.set_fact:
sysctl_settings: "{{ generic_sysctl_settings | combine(ipv4_sysctl_settings) }}"
when: not system_has_ipv6
tags:
- sysctl
- name: Configure sysctl
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value | int }}"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
with_dict: "{{ sysctl_settings }}"
notify:
- Restart sysctl
tags:
- sysctl
- CCE-80913-7
- CCE-80915-2
- CCE-80916-0
- CCE-80917-8
- CCE-80918-6
- CCE-80919-4
- CCE-80920-2
- CCE-80921-0
- CCE-80922-8
- CCE-80953-3
- CCE-81006-9
- CCE-81007-7
- CCE-81009-3
- CCE-81010-1
- CCE-81011-9
- CCE-81013-5
- CCE-81021-8
- CCE-81024-2
- CCE-81027-5
- CCE-81030-9
- CCE-81054-9
- CCE-82974-7
- CIS-UBUNTU2004-1.5.2
- CIS-UBUNTU2004-1.5.4
- CIS-UBUNTU2004-3.2.1
- CIS-UBUNTU2004-3.2.2
- CIS-UBUNTU2004-3.3.1
- CIS-UBUNTU2004-3.3.2
- CIS-UBUNTU2004-3.3.3
- CIS-UBUNTU2004-3.3.4
- CIS-UBUNTU2004-3.3.5
- CIS-UBUNTU2004-3.3.6
- CIS-UBUNTU2004-3.3.7
- CIS-UBUNTU2004-3.3.8
- CIS-UBUNTU2004-3.3.9
- UBTU-20-010412
- UBTU-20-010448
...
@@ -0,0 +1,31 @@
---
- name: Configure systemd system.conf
become: true
ansible.builtin.template:
src: etc/systemd/system.conf.j2
dest: /etc/systemd/system.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- system
- systemd
- CCE-80784-2
- name: Configure systemd user.conf
become: true
ansible.builtin.template:
src: etc/systemd/user.conf.j2
dest: /etc/systemd/user.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- systemd
- users
@@ -0,0 +1,47 @@
---
- name: Configure systemd timesyncd
become: true
ansible.builtin.template:
src: etc/systemd/timesyncd.conf.j2
dest: /etc/systemd/timesyncd.conf
backup: true
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
tags:
- systemd
- timesyncd
- CIS-UBUNTU2004-2.1.1.1
- CIS-UBUNTU2004-2.1.1.2
- name: Stat timesyncd status
ansible.builtin.command: systemctl status systemd-timesyncd
register: timesyncd_status
changed_when: false
failed_when: false
tags:
- systemd
- timesyncd
- CIS-UBUNTU2004-2.1.1.1
- CIS-UBUNTU2004-2.1.1.2
- name: Stat timedatectl show
ansible.builtin.command: timedatectl show
register: timedatectl_show
changed_when: timedatectl_show.stdout.find('NTPSynchronized=yes') == -1 and timesyncd_status.rc == 0
tags:
- systemd
- timesyncd
- CIS-UBUNTU2004-2.1.1.1
- CIS-UBUNTU2004-2.1.1.2
- name: Run timedatectl set-ntp
become: true
ansible.builtin.command: timedatectl set-ntp true # noqa no-changed-when
when: timedatectl_show.stdout.find('NTPSynchronized=yes') == -1 and timesyncd_status.rc == 0
tags:
- systemd
- timesyncd
- CIS-UBUNTU2004-2.1.1.2
+237
View File
@@ -0,0 +1,237 @@
---
- name: Add the nf_conntrack module
become: true
community.general.modprobe:
name: nf_conntrack
state: present
tags:
- conntrack
- sysctl
- name: Stat nf_conntrack_tcp_be_liberal
become: true
ansible.builtin.stat:
path: /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal
register: conntrackliberal
tags:
- conntrack
- sysctl
# https://github.com/ansible/ansible/issues/45446
- name: Enable nf_conntrack_tcp_be_liberal to keep connections alive
become: true
ansible.posix.sysctl:
name: net.netfilter.nf_conntrack_tcp_be_liberal
value: "1"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
reload: true
when: conntrackliberal.stat.exists
tags:
- conntrack
- sysctl
- name: Debian family UFW installation
become: true
ansible.builtin.apt:
name: "ufw"
state: present
install_recommends: false
when: ansible_os_family == "Debian"
tags:
- ufw
- CCE-82998-6
- M1037
- CIS-UBUNTU2004-3.5.1.1
- CIS-UBUNTU2004-3.5.1.3
- name: RedHat family UFW installation
become: true
ansible.builtin.dnf:
name: "ufw"
state: present
when: ansible_os_family == "RedHat"
tags:
- ufw
- CCE-82998-6
- M1037
- name: Set UFW IPT_SYSCTL
become: true
ansible.builtin.lineinfile:
regexp: "^IPT_SYSCTL="
line: "IPT_SYSCTL={{ sysctl_conf_dir }}/zz-hardening.conf"
dest: /etc/default/ufw
mode: "0640"
state: present
create: false
backrefs: true
tags:
- ufw
- M1037
- name: Set UFW DEFAULT_FORWARD_POLICY
become: true
ansible.builtin.lineinfile:
regexp: "^DEFAULT_FORWARD_POLICY="
line: 'DEFAULT_FORWARD_POLICY="{{ ufw_default_forward_policy }}"'
dest: /etc/default/ufw
mode: "0640"
state: present
create: false
backrefs: true
tags:
- ufw
- M1037
- name: Enable UFW and set default deny incoming
become: true
community.general.ufw:
state: enabled
direction: incoming
policy: deny
log: true
comment: ansible managed
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.7
- D3-ITF
- M1037
- name: Enable UFW and set default deny outgoing
become: true
community.general.ufw:
state: enabled
direction: outgoing
policy: deny
log: true
logging: low
comment: ansible managed
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.7
- M1037
- name: Stat UFW rules
become: true
ansible.builtin.shell: |
set -o pipefail
ufw show added | grep '^ufw' | grep -v "'ansible\smanaged'" | sed 's/ufw //g'
args:
executable: /bin/bash
failed_when: ufw_not_managed.rc > 1
changed_when: false
register: ufw_not_managed
tags:
- ufw
- M1037
- name: Allow sshd port from administrator networks
become: true
community.general.ufw:
rule: limit
src: "{{ item }}"
port: "{{ sshd_port | int }}"
proto: tcp
comment: ansible managed
with_items:
- "{{ ssh_allowed_networks }}"
tags:
- ufw
- M1037
- name: Allow incoming specific ports
become: true
community.general.ufw:
rule: "{{ item.rule }}"
src: "{{ item.from | d('any') }}"
port: "{{ item.port | int }}"
proto: "{{ item.proto }}"
comment: ansible managed
with_items:
- "{{ fw_allowed_ports }}"
tags:
- ufw
- M1037
- name: Allow outgoing specified ports
become: true
community.general.ufw:
rule: allow
port: "{{ item | int }}"
direction: out
comment: ansible managed
with_items:
- "{{ ufw_outgoing_traffic }}"
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.5
- D3-OTF
- M1037
- name: Deny loopback network traffic
become: true
community.general.ufw:
rule: deny
src: "{{ item }}"
comment: ansible managed
loop:
- 127.0.0.0/8
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.4
- M1037
when: fw_loopback_traffic_deny
- name: Allow loopback traffic in
become: true
community.general.ufw:
rule: allow
interface: lo
direction: in
comment: ansible managed
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.4
- M1037
- name: Allow loopback traffic out
become: true
community.general.ufw:
rule: allow
interface: lo
direction: out
comment: ansible managed
tags:
- ufw
- CIS-UBUNTU2004-3.5.1.4
- M1037
- name: Delete unmanaged UFW rules
become: true
ansible.builtin.command: ufw delete {{ item }} # noqa no-changed-when
when: ufw_not_managed.stdout_lines | length > 0 and not ansible_os_family == "RedHat" and ufw_delete_unmanaged
with_items:
- "{{ ufw_not_managed.stdout_lines }}"
tags:
- ufw
- D3-OTF
- M1037
- name: Configure conntrack sysctl
become: true
environment:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value | int }}"
state: present
sysctl_set: true
sysctl_file: "{{ sysctl_conf_dir }}/zz-hardening.conf"
with_dict: "{{ conntrack_sysctl_settings }}"
notify:
- Restart sysctl
tags:
- conntrack
- sysctl
+125
View File
@@ -0,0 +1,125 @@
---
- name: Stat init.d/rc
become: true
ansible.builtin.stat:
path: /etc/init.d/rc
register: initdrc
tags:
- umask
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Set default rc umask
become: true
ansible.builtin.replace:
regexp: 'umask(\s+.*)'
replace: "umask {{ umask_value }}"
dest: /etc/init.d/rc
mode: "0755"
when: initdrc.stat.exists
tags:
- umask
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Stat bashrc
become: true
ansible.builtin.stat:
path: /etc/bashrc
register: bashrc
tags:
- bash
- umask
- CCE-81036-6
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Set default bashrc umask
become: true
ansible.builtin.replace:
regexp: 'umask(\s+.*)'
replace: "umask {{ umask_value }}"
dest: /etc/bashrc
mode: "0644"
when: bashrc.stat.exists
tags:
- bash
- umask
- CCE-81036-6
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Stat csh.cshrc
become: true
ansible.builtin.stat:
path: /etc/csh.cshrc
register: cshrc
tags:
- csh
- umask
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Set default csh.cshrc umask
become: true
ansible.builtin.replace:
regexp: 'umask(\s+.*)'
replace: "umask {{ umask_value }}"
dest: /etc/csh.cshrc
mode: "0644"
when: cshrc.stat.exists
tags:
- csh
- umask
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Set default profile umask
become: true
ansible.builtin.replace:
regexp: 'umask(\s+.*)'
replace: "umask {{ umask_value }}"
dest: /etc/profile
mode: "0644"
tags:
- umask
- CIS-UBUNTU2004-5.5.4
- M1022
- name: Configure readonly TMOUT
become: true
ansible.builtin.lineinfile:
line: "readonly TMOUT"
dest: /etc/profile
mode: "0644"
state: present
create: false
insertbefore: "^export"
tags:
- tmout
- name: Set TMOUT
become: true
ansible.builtin.lineinfile:
line: "TMOUT=600"
dest: /etc/profile
mode: "0644"
state: present
create: false
insertbefore: "^readonly TMOUT"
tags:
- tmout
- CIS-UBUNTU2004-5.5.5
- UBTU-20-010013
- name: Export TMOUT
become: true
ansible.builtin.lineinfile:
line: "export TMOUT"
dest: /etc/profile
mode: "0644"
state: present
create: false
insertafter: "^readonly TMOUT"
tags:
- tmout
@@ -0,0 +1,39 @@
---
- name: Remove users
become: true
ansible.builtin.user:
name: "{{ item }}"
state: absent
remove: true
register: remove_users
with_items:
- "{{ delete_users }}"
failed_when: >
remove_users is not success and
not ("not removing" in remove_users.msg or
"not found" in remove_users.msg)
tags:
- users
- name: Stat user /home directories
ansible.builtin.find:
paths: /home
file_type: directory
register: home_directories
tags:
- users
- CIS-UBUNTU2004-6.2.6
- M1022
- name: Set user /home directories permission
become: true
ansible.builtin.file:
mode: "0750"
path: "{{ item.path }}"
with_items: "{{ home_directories.files }}"
loop_control:
label: "{{ item.path }}"
tags:
- users
- CIS-UBUNTU2004-6.2.6
- M1022
@@ -0,0 +1,21 @@
# {{ ansible_managed }}
DSHELL=/bin/false
DHOME=/home
GROUPHOMES=no
LETTERHOMES=no
SKEL=/etc/skel
FIRST_SYSTEM_UID=100
LAST_SYSTEM_UID=999
FIRST_SYSTEM_GID=100
LAST_SYSTEM_GID=999
FIRST_UID=1000
LAST_UID=29999
FIRST_GID=1000
LAST_GID=29999
USERGROUPS=yes
USERS_GID=100
DIR_MODE=0750
SETGID_HOME=no
QUOTAUSER=""
SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"
@@ -0,0 +1,6 @@
#!/bin/sh
if grep -sqo rdrand /proc/cpuinfo; then
echo "{ \"rdrand\" : true }"
else
echo "{ \"rdrand\" : false }"
fi

Some files were not shown because too many files have changed in this diff Show More