From 37ab8a58dffccac424789358fd915cdc798af09d Mon Sep 17 00:00:00 2001 From: Kian Kasad Date: Sun, 11 Aug 2024 17:27:36 -0700 Subject: [PATCH] Configure fail2ban --- README.md | 3 ++ main.yml | 6 ++++ roles/fail2ban/handlers/main.yml | 5 ++++ roles/fail2ban/tasks/main.yml | 35 ++++++++++++++++++++++ roles/fail2ban/templates/fail2ban.local | 5 ++++ roles/fail2ban/templates/jail.d/sshd.local | 10 +++++++ roles/fail2ban/templates/jail.local | 21 +++++++++++++ 7 files changed, 85 insertions(+) create mode 100644 roles/fail2ban/handlers/main.yml create mode 100644 roles/fail2ban/tasks/main.yml create mode 100644 roles/fail2ban/templates/fail2ban.local create mode 100644 roles/fail2ban/templates/jail.d/sshd.local create mode 100644 roles/fail2ban/templates/jail.local diff --git a/README.md b/README.md index 5a4a65e..f125eb9 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ necessary nonetheless. to export Docker container performance metrics. - [Promtail](https://grafana.com/docs/loki/latest/send-data/promtail/), to export system & Docker container logs to Loki. +- [Fail2ban](https://github.com/fail2ban/fail2ban), a log-based intrusion + prevention system. Monitors logs for authentication failures and blocks + IPs that have too many failures. ### Planned diff --git a/main.yml b/main.yml index 3f9abe7..857db75 100644 --- a/main.yml +++ b/main.yml @@ -26,9 +26,15 @@ - role: setup_ssh tags: - setup + - ssh + + - role: fail2ban + tags: + - fail2ban - role: setup_docker tags: + - setup - docker - role: dnsmasq diff --git a/roles/fail2ban/handlers/main.yml b/roles/fail2ban/handlers/main.yml new file mode 100644 index 0000000..a4e3750 --- /dev/null +++ b/roles/fail2ban/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart fail2ban.service + ansible.builtin.service: + name: fail2ban + state: restarted diff --git a/roles/fail2ban/tasks/main.yml b/roles/fail2ban/tasks/main.yml new file mode 100644 index 0000000..81dc7ab --- /dev/null +++ b/roles/fail2ban/tasks/main.yml @@ -0,0 +1,35 @@ +--- +- name: Install fail2ban + ansible.builtin.package: + name: fail2ban + state: present + +- name: Render fail2ban configuration files + ansible.builtin.template: + src: "{{ item }}" + dest: /etc/fail2ban/{{ item }} + owner: root + group: root + mode: 0644 + loop: + - fail2ban.local + - jail.local + register: config_changed + notify: Restart fail2ban.service + +- name: Render fail2ban jail drop-ins + ansible.builtin.template: + src: "{{ item }}" + dest: /etc/fail2ban/jail.d/{{ item | basename }} + owner: root + group: root + mode: 0644 + with_fileglob: + - templates/jail.d/* + notify: Restart fail2ban.service + +- name: Enable and start fail2ban + ansible.builtin.systemd: + name: fail2ban + enabled: yes + state: started diff --git a/roles/fail2ban/templates/fail2ban.local b/roles/fail2ban/templates/fail2ban.local new file mode 100644 index 0000000..c673941 --- /dev/null +++ b/roles/fail2ban/templates/fail2ban.local @@ -0,0 +1,5 @@ +[Definition] + +# Setting this here to prevent fail2ban from warning that this is unset every +# time it starts up. +allowipv6 = auto diff --git a/roles/fail2ban/templates/jail.d/sshd.local b/roles/fail2ban/templates/jail.d/sshd.local new file mode 100644 index 0000000..7fca9c1 --- /dev/null +++ b/roles/fail2ban/templates/jail.d/sshd.local @@ -0,0 +1,10 @@ +[sshd] +enabled = true + +# Flag public key mismatches. This can cause false positives: A legitimate user +# could have >5 private keys, in which case SSH will try each sequentially until +# one works, triggering a ban. +filter = sshd[publickey='any'] + +# Also ban access to our custom port +port = 22,50519 diff --git a/roles/fail2ban/templates/jail.local b/roles/fail2ban/templates/jail.local new file mode 100644 index 0000000..ea40936 --- /dev/null +++ b/roles/fail2ban/templates/jail.local @@ -0,0 +1,21 @@ +[DEFAULT] + +# Use systemd-journal to find logs. +backend = systemd + +# Ban hosts for 5 minutes on first fail. +bantime = 5m + +# Randomly add up to 2 minutes to the ban time to prevent bots from timing +# their attacks. +bantime.rndtime = 120 + +# Increase ban time for each subsequent fail. +bantime.increment = true + +# Formula for calculating ban time. +# This one doubles the ban time for each subsequent fail. +bantime.formula = ban.Time * (1 << ban.Count) + +# Don't use hostnames for banning, but log as info. +usedns = no