roles/common: Add support for fail2ban

This is active banning of IPs that are brute forcing login attempts
to SSH, versus the passive banning of 10,000 abusive IPs from the
abuseipdb.com blacklist. For now I am banning IPs that fail to log
in successfully more than twelve times in a one-hour period, but
these settings might change, and I can override them at the group
and host level if needed.

Currently this works for CentOS 7, Ubuntu 16.04, and Ubuntu 18.04,
with minor differences in the systemd configuration due to older
versions on some distributions.

You can see the status of the jail like this:

    # fail2ban-client status sshd
    Status for the jail: sshd
    |- Filter
    |  |- Currently failed: 0
    |  |- Total failed:     0
    |  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
    `- Actions
       |- Currently banned: 1
       |- Total banned:     1
       `- Banned IP list:   106.13.112.20

You can unban IPs like this:

    # fail2ban-client set sshd unbanip 106.13.112.20
This commit is contained in:
Alan Orth 2019-10-26 16:36:07 +02:00
parent ebfdc7968c
commit 0605f70f2e
Signed by: alanorth
GPG Key ID: 0FB860CC9C45B1B9
7 changed files with 94 additions and 8 deletions

View File

@ -0,0 +1,11 @@
---
#file - roles/common/defaults/main.yml
fail2ban_maxretry: 6
# 1 hour in seconds
fail2ban_findtime: 3600
# 2 weeks in seconds
fail2ban_bantime: 1209600
fail2ban_ignoreip: 127.0.0.1/8,172.26.0.0/16,192.168.5.0/24
# vim: set ts=2 sw=2:

View File

@ -15,3 +15,9 @@
- name: restart firewalld - name: restart firewalld
systemd: name=firewalld state=restarted systemd: name=firewalld state=restarted
- name: restart fail2ban
systemd: name=fail2ban state=restarted
- name: reload systemd
systemd: daemon_reload=yes

View File

@ -0,0 +1,20 @@
---
- name: Configure fail2ban sshd filter
template: src=etc/fail2ban/jail.d/sshd.local.j2 dest=/etc/fail2ban/jail.d/sshd.local owner=root mode=0644
notify: restart fail2ban
- name: Create fail2ban service override directory
file: path=/etc/systemd/system/fail2ban.service.d state=directory owner=root mode=0755
# See Arch Linux's example: https://wiki.archlinux.org/index.php/Fail2ban
- name: Configure fail2ban service override
template: src=etc/systemd/system/fail2ban.service.d/override.conf.j2 dest=/etc/systemd/system/fail2ban.service.d/override.conf owner=root mode=0644
notify:
- reload systemd
- restart fail2ban
- name: Enable fail2ban service
systemd: name=fail2ban enabled=yes
# vim: set sw=2 ts=2:

View File

@ -1,12 +1,17 @@
--- ---
- block: - block:
- name: Install firewalld and deps - name: Set Debian firewall packages
when: ansible_distribution_major_version is version_compare('8', '>=') set_fact:
apt: pkg={{ item }} state=present debian_firewall_packages:
loop:
- firewalld - firewalld
- tidy - tidy
- fail2ban
- python3-systemd # for fail2ban systemd backend
- name: Install firewalld and deps
when: ansible_distribution_major_version is version_compare('8', '>=')
apt: pkg={{ debian_firewall_packages }} state=present
- name: Use nftables backend in firewalld - name: Use nftables backend in firewalld
when: ansible_distribution_major_version is version_compare('10', '>=') when: ansible_distribution_major_version is version_compare('10', '>=')
@ -47,6 +52,9 @@
- abusers-ipv6.xml - abusers-ipv6.xml
notify: notify:
- restart firewalld - restart firewalld
- include_tasks: fail2ban.yml
when: ansible_distribution_major_version is version_compare('9', '>=')
tags: firewall tags: firewall
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -1,12 +1,17 @@
--- ---
- block: - block:
- name: Install firewalld and deps - name: Set Ubuntu firewall packages
when: ansible_distribution_version is version_compare('15.04', '>=') set_fact:
apt: pkg={{ item }} state=present ubuntu_firewall_packages:
loop:
- firewalld - firewalld
- tidy - tidy
- fail2ban
- python3-systemd # for fail2ban systemd backend
- name: Install firewalld and deps
when: ansible_distribution_version is version_compare('15.04', '>=')
apt: pkg={{ ubuntu_firewall_packages }} state=present
- name: Copy firewalld public zone file - name: Copy firewalld public zone file
when: ansible_distribution_version is version_compare('15.04', '>=') when: ansible_distribution_version is version_compare('15.04', '>=')
@ -26,6 +31,9 @@
- abusers-ipv6.xml - abusers-ipv6.xml
notify: notify:
- restart firewalld - restart firewalld
- include_tasks: fail2ban.yml
when: ansible_distribution_version is version_compare('15.04', '>=')
tags: firewall tags: firewall
# vim: set sw=2 ts=2: # vim: set sw=2 ts=2:

View File

@ -0,0 +1,11 @@
[sshd]
enabled = true
# See: /etc/fail2ban/filter.d/sshd.conf
filter = sshd
# Integrate with firewalld and ipsets
banaction = firewallcmd-ipset
backend = systemd
maxretry = {{ fail2ban_maxretry }}
findtime = {{ fail2ban_findtime }}
bantime = {{ fail2ban_bantime }}
ignoreip = {{ fail2ban_ignoreip }}

View File

@ -0,0 +1,22 @@
[Service]
PrivateDevices=yes
PrivateTmp=yes
ProtectHome=read-only
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version_compare('18','==') %}
ProtectSystem=strict
{% else %}
{# Older systemd versions don't have ProtectSystem=strict #}
ProtectSystem=full
{% endif %}
NoNewPrivileges=yes
{% if ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version_compare('18','==') %}
ReadWritePaths=-/var/run/fail2ban
ReadWritePaths=-/var/lib/fail2ban
ReadWritePaths=-/var/log/fail2ban.log
{% else %}
{# Older systemd versions don't have ReadWritePaths #}
ReadWriteDirectories=-/var/run/fail2ban
ReadWriteDirectories=-/var/lib/fail2ban
ReadWriteDirectories=-/var/log
{% endif %}
CapabilityBoundingSet=CAP_AUDIT_READ CAP_DAC_READ_SEARCH CAP_NET_ADMIN CAP_NET_RAW