initial commit
This commit is contained in:
186
harden_fedora44.yml
Normal file
186
harden_fedora44.yml
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
# --------------------------------------------------------------
|
||||
# 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
|
||||
Reference in New Issue
Block a user