Files
stoat/harden_fedora44.yml
2026-09-13 13:12:07 -06:00

186 lines
6.4 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# --------------------------------------------------------------
# Ansible playbook: Harden a Fedora 44 server & install Fail2Ban
# --------------------------------------------------------------
# Requirements:
# - Ansible >= 2.14
# - A reachable Fedora 44 host with SSH access (password or key)
# - `sudo` rights for the control user (via become: true)
# --------------------------------------------------------------
- name: Harden Fedora 44 & install Fail2Ban
hosts: all
become: true # elevates to root for package/service ops
vars:
# ---- Tunables -------------------------------------------------
# Change these to match your environment
fail2ban_port: "22" # default SSH jail; can be "http","https",etc.
fail2ban_maxretry: 3 # how many attempts before ban
fail2ban_bantime: 3600 # seconds (1 h)
# -----------------------------------------------------------------
# Ensure we are on Fedora 44 (you can relax this if you wish)
fedora_release: "44"
tasks:
# --------------------------------------------------------------
# Verify OS version (informational, can be removed)
# --------------------------------------------------------------
- name: Gather os fact
ansible.builtin.debug:
var: ansible_distribution_version
- name: Ensure we are running Fedora {{ fedora_release }}
ansible.builtin.assert:
that:
- ansible_distribution == "Fedora"
- ansible_distribution_version == fedora_release
fail_msg: "This playbook targets Fedora {{ fedora_release }} only."
success_msg: "Running on the correct Fedora version."
# --------------------------------------------------------------
# Update / upgrade all packages
# --------------------------------------------------------------
- name: Update all packages to latest versions
ansible.builtin.dnf:
name: "*"
state: latest
update_cache: true
# --------------------------------------------------------------
# Install essential hardening packages
# --------------------------------------------------------------
- name: Install fail2ban, firewalld, and sudo
ansible.builtin.dnf:
name:
- fail2ban
- firewalld
- sudo
state: present
# --------------------------------------------------------------
# Start & enable firewalld (default-deny all, allow SSH)
# --------------------------------------------------------------
- name: Start and enable firewalld
ansible.builtin.systemd:
name: firewalld
state: started
enabled: true
- name: Allow SSH service through firewalld
ansible.builtin.command:
cmd: firewall-cmd --permanent --add-service=ssh
changed_when: false # idempotent check handled by firewall_cmd
- name: Reload firewalld to apply rules
ansible.builtin.command:
cmd: firewall-cmd --reload
changed_when: false
# --------------------------------------------------------------
# Harden SSH (disable root login, enforce key‑only auth)
# --------------------------------------------------------------
- name: Ensure SSH config directory exists
ansible.builtin.file:
path: /etc/ssh/sshd_config.d
state: directory
mode: "0755"
- name: Disable root login via SSH
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/00-disable-root.conf
create: true
mode: "0644"
line: "PermitRootLogin no"
state: present
- name: Enforce password-auth disabled (key-only)
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/00-key-only.conf
create: true
mode: "0644"
line: "PasswordAuthentication no"
state: present
- name: Require MFA (optional) — add if you use Duo, etc.
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config.d/00-mfa.conf
create: true
mode: "0644"
line: "AuthenticationMethods publickey,keyboard-interactive:pam"
state: present
- name: Restart sshd to apply changes
ansible.builtin.service:
name: sshd
state: restarted
# --------------------------------------------------------------
# Configure Fail2Ban
# --------------------------------------------------------------
- name: template fail2ban jail.local
ansible.builtin.template:
src: jail.local.j2
dest: /etc/fail2ban/jail.local
mode: "0644"
notify: Restart fail2ban
- name: Ensure fail2ban is started & enabled
ansible.builtin.service:
name: fail2ban
state: started
enabled: true
# --------------------------------------------------------------
# (Optional) Install & configure unattended‑security updates
# --------------------------------------------------------------
- name: Install dnf-automatic (security-only)
ansible.builtin.dnf:
name: dnf-automatic
state: present
- name: Enable security-only automatic updates
ansible.builtin.lineinfile:
path: /etc/dnf/automatic.conf
regexp: "^update_type"
line: "update_type = security"
state: present
- name: Enable and start dnf-automatic.timer
ansible.builtin.systemd:
name: "@dnf-automatic.timer"
state: started
enabled: true
# --------------------------------------------------------------
# Log rotation for security‑relevant logs
# --------------------------------------------------------------
- name: Ensure rsyslog is running
ansible.builtin.service:
name: rsyslog
state: started
enabled: true
- name: Add logrotate rule for fail2ban logs
ansible.builtin.lineinfile:
path: /etc/logrotate.d/fail2ban
create: true
mode: "0644"
content: |
/var/log/fail2ban/*.log {
daily
rotate 7
compress
missingok
notifempty
postrotate
/usr/bin/fail2ban-client reload >/dev/null 2>&1 || true
endscript
}
# --------------------------------------------------------------
# 9 Handlers
# --------------------------------------------------------------
handlers:
- name: Restart fail2ban
ansible.builtin.service:
name: fail2ban
state: restarted