Prototype a role for installing fail2ban on RHEL 9+

This commit is contained in:
Alexander Gorelyshev
2026-06-08 20:05:29 +04:00
parent fad0cb0abb
commit deaeb1f79e
9 changed files with 178 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
fail2ban_rhel
=============
A small role to deploy `fail2ban` on RHEL/Rocky 9+ hosts. Currently supports only a templated `sshd` jail.
Requirements
------------
- Target hosts must be RHEL-family or Rocky Linux 9+
Supported Platforms
-------------------
- RHEL 9+
- Rocky Linux 9+
Role Variables
--------------
sshd jail configuration
- `fail2ban_rhel_jail_sshd`:
`enabled`: enable the sshd jail. Default: `true`
`port`: fail2ban port for sshd. Default: `ssh`
`logpath`: path to the SSH log file. Default: `/var/log/secure`
`findtime`: time window for fail2ban. Default: `600`
`maxretry`: maximum retry count. Default: `5`
`bantime`: ban duration in seconds. Default: `600`
`ignoreips`: list of IPs and CIDRs that fail2ban should ignore. Default: `127.0.0.1/8`, `::1`
Behavior
--------
By default this role:
- installs `epel-release` on RedHat-family systems when enabled
- installs `fail2ban`
- creates `/etc/fail2ban/jail.d/sshd.conf` from a template
- enables and starts the `fail2ban` systemd service
Example Playbook
----------------
See: `molecule/default/converge.yml`
License
-------
MIT

View File

@@ -0,0 +1,13 @@
---
fail2ban_rhel_jail_sshd:
enabled: true
port: ssh
findtime: 600
maxretry: 5
bantime: 3600
logpath: "%(sshd_log)s"
backend: "%(sshd_backend)s"
banaction: firewallcmd-multiport
ignoreips:
- 127.0.0.1/8
- ::1

View File

@@ -0,0 +1,7 @@
---
- name: Restart fail2ban
ansible.builtin.systemd:
name: fail2ban
state: restarted
enabled: true
daemon_reload: true

View File

@@ -0,0 +1,19 @@
---
galaxy_info:
role_name: fail2ban_rhel
namespace: genlab
author: "Alexander Gorelyshev"
company: "Genlab, LLC"
description: "Deploy a lean Fail2Ban configuration for RHEL/Rocky 9+ hosts"
license: "MIT"
min_ansible_version: "2.1"
platforms:
- name: "EL"
versions: ["9"]
- name: "Rocky"
versions: ["9.2"]
galaxy_tags: []
dependencies: []

View File

@@ -0,0 +1,5 @@
---
- name: Converge
hosts: all
roles:
- role: genlab.common.fail2ban_rhel

View File

@@ -0,0 +1,27 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: rocky9
image: geerlingguy/docker-${MOLECULE_DISTRO:-rockylinux9}-ansible:latest
pre_build_image: true
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
provisioner:
name: ansible
verifier:
name: ansible
lint: |
set -e
yamllint .
ansible-lint .

View File

@@ -0,0 +1,17 @@
---
- name: Verify
hosts: all
gather_facts: false
any_errors_fatal: true
tasks:
- name: "Check that the fail2ban service is active"
register: sshd_rhel_fail2ban_service
ansible.builtin.systemd:
name: fail2ban
- name: "Assert fail2ban is running"
ansible.builtin.assert:
that: sshd_rhel_fail2ban_service.status.ActiveState == "active"
success_msg: "fail2ban service is running"
fail_msg: "fail2ban service is not active"

View File

@@ -0,0 +1,27 @@
---
- name: "Install EPEL release on RedHat-family systems"
ansible.builtin.dnf:
name: "epel-release"
state: present
- name: "Install fail2ban"
ansible.builtin.package:
name: "fail2ban"
state: present
- name: "Ensure Fail2Ban jail configuration directory exists"
ansible.builtin.file:
path: /etc/fail2ban/jail.d
state: directory
owner: root
group: root
mode: "0755"
- name: "Render sshd jail configuration"
notify: Restart fail2ban
ansible.builtin.template:
src: sshd.conf.j2
dest: /etc/fail2ban/jail.d/sshd.local
owner: root
group: root
mode: "0644"

View File

@@ -0,0 +1,14 @@
[sshd]
enabled = {{ fail2ban_rhel_jail_sshd.enabled | ternary('true', 'false') }}
port = {{ fail2ban_rhel_jail_sshd.port }}
logpath = {{ fail2ban_rhel_jail_sshd.logpath }}
backend = {{ fail2ban_rhel_jail_sshd.backend }}
banaction = {{ fail2ban_rhel_jail_sshd.banaction }}
findtime = {{ fail2ban_rhel_jail_sshd.findtime }}
maxretry = {{ fail2ban_rhel_jail_sshd.maxretry }}
bantime = {{ fail2ban_rhel_jail_sshd.bantime }}
ignoreip = {{ fail2ban_rhel.ignoreips | default([]) | join(' ') }}