From 61d48f117339ea5dff44b3a7e09d0d4b96912a50 Mon Sep 17 00:00:00 2001 From: Phillip Smith <phillip.smith@naturesorganics.com.au> Date: Fri, 25 Oct 2019 16:46:09 +1100 Subject: [PATCH] implement fail2ban role and deploy to orion fail2ban role now protects postfix, dovecot and sshd. other roles can drop configuration files into /etc/fail2ban/jail.d/*.local to enable fail2ban to monitor it's service. --- host_vars/orion.archlinux.org/misc | 5 ++ playbooks/orion.yml | 1 + roles/archwiki/tasks/main.yml | 10 +++ .../templates/fail2ban.filter.j2} | 4 + roles/fail2ban/defaults/main.yml | 14 ++++ roles/fail2ban/handlers/main.yml | 7 ++ roles/fail2ban/tasks/main.yml | 81 ++++++++++++++++--- roles/fail2ban/templates/dovecot.jail.j2 | 8 ++ roles/fail2ban/templates/fail2ban.local.j2 | 12 +++ roles/fail2ban/templates/fail2ban.service.j2 | 6 ++ .../templates/firewallcmd-allports.local.j2 | 8 ++ roles/fail2ban/templates/jail.local.j2 | 39 ++++++--- roles/fail2ban/templates/postfix.jail.j2 | 9 +++ roles/fail2ban/templates/sshd.jail.j2 | 6 ++ 14 files changed, 192 insertions(+), 18 deletions(-) rename roles/{fail2ban/templates/nginx-dos.conf => archwiki/templates/fail2ban.filter.j2} (91%) create mode 100644 roles/fail2ban/defaults/main.yml create mode 100644 roles/fail2ban/handlers/main.yml create mode 100644 roles/fail2ban/templates/dovecot.jail.j2 create mode 100644 roles/fail2ban/templates/fail2ban.local.j2 create mode 100644 roles/fail2ban/templates/fail2ban.service.j2 create mode 100644 roles/fail2ban/templates/firewallcmd-allports.local.j2 create mode 100644 roles/fail2ban/templates/postfix.jail.j2 create mode 100644 roles/fail2ban/templates/sshd.jail.j2 diff --git a/host_vars/orion.archlinux.org/misc b/host_vars/orion.archlinux.org/misc index f262ca79f..a820a9a01 100644 --- a/host_vars/orion.archlinux.org/misc +++ b/host_vars/orion.archlinux.org/misc @@ -22,3 +22,8 @@ zabbix_agent_templates: - Template App Borg Backup - Template App Nginx - Template App Archive + +fail2ban_jails: + sshd: true + postfix: true + dovecot: true diff --git a/playbooks/orion.yml b/playbooks/orion.yml index 54ebd0683..428affafe 100644 --- a/playbooks/orion.yml +++ b/playbooks/orion.yml @@ -29,3 +29,4 @@ - { role: archive, archive_domain: "archive.archlinux.org", archive_dir: "/srv/archive", tags: ['archive'] } - { role: hefur, ftp_iso_dir: '/srv/ftp/iso', tags: ['torrenttracker']} - wkd + - { role: fail2ban, tags: ["fail2ban"] } diff --git a/roles/archwiki/tasks/main.yml b/roles/archwiki/tasks/main.yml index 286a0955d..25918005d 100644 --- a/roles/archwiki/tasks/main.yml +++ b/roles/archwiki/tasks/main.yml @@ -99,6 +99,16 @@ - archwiki-question-updater.service - archwiki-memcached.service +- name: install fail2ban rate-limit filter + template: src=fail2ban.filter.j2 dest=/etc/fail2ban/filter.d/nginx-dos.local owner=root group=root mode=0644 + tags: + - fail2ban + +- name: install fail2ban rate-limit jail + template: src=fail2ban.jail.j2 dest=/etc/fail2ban/jail.d/nginx-dos.local owner=root group=root mode=0644 + tags: + - fail2ban + - name: start and enable archwiki runjobs timer service: name="archwiki-runjobs.timer" enabled=yes state=started diff --git a/roles/fail2ban/templates/nginx-dos.conf b/roles/archwiki/templates/fail2ban.filter.j2 similarity index 91% rename from roles/fail2ban/templates/nginx-dos.conf rename to roles/archwiki/templates/fail2ban.filter.j2 index 56a5ee4b3..7b637034b 100644 --- a/roles/fail2ban/templates/nginx-dos.conf +++ b/roles/archwiki/templates/fail2ban.filter.j2 @@ -1,3 +1,7 @@ +# +# {{ansible_managed}} +# + [Definition] # Option: failregex # Notes.: Regexp to catch a generic call from an IP address. diff --git a/roles/fail2ban/defaults/main.yml b/roles/fail2ban/defaults/main.yml new file mode 100644 index 000000000..003ddc95b --- /dev/null +++ b/roles/fail2ban/defaults/main.yml @@ -0,0 +1,14 @@ +# by default all jails are disabled +# override this variable in a host/group file to define which jails to enable +fail2ban_jails: + sshd: false + postfix: false + dovecot: false + +# use variables for these directives so they can be overridden at a host or +# group level as required. note that there cannot be a space between the +# integer and the unit (eg "15min" == good, "15 min" == bad). +# refer to `man jail.conf` +fail2ban_findtime: 15min +fail2ban_bantime: 1day +fail2ban_maxretry: 5 diff --git a/roles/fail2ban/handlers/main.yml b/roles/fail2ban/handlers/main.yml new file mode 100644 index 000000000..731c718ac --- /dev/null +++ b/roles/fail2ban/handlers/main.yml @@ -0,0 +1,7 @@ +- name: restart fail2ban + systemd: + name: fail2ban + state: restarted + +- name: reload fail2ban jails + shell: type fail2ban-server > /dev/null && (fail2ban-client ping > /dev/null && fail2ban-client reload > /dev/null || true) || true diff --git a/roles/fail2ban/tasks/main.yml b/roles/fail2ban/tasks/main.yml index 4a726b0e3..faca06bf6 100644 --- a/roles/fail2ban/tasks/main.yml +++ b/roles/fail2ban/tasks/main.yml @@ -1,14 +1,77 @@ ---- - - name: install fail2ban - pacman: name=fail2ban state=present + package: + name: "fail2ban" + state: "present" + notify: + - restart fail2ban + +- name: install systemd unit override file + template: + src: "fail2ban.service.j2" + dest: "/etc/systemd/system/fail2ban.service.d/override.conf" + owner: "root" + group: "root" + mode: 0644 + +- name: install local config files + template: + src: "{{item}}.j2" + dest: "/etc/fail2ban/{{item}}" + owner: "root" + group: "root" + mode: 0644 + with_items: + - "fail2ban.local" + - "jail.local" + notify: + - restart fail2ban + +- name: install firewallcmd-allports.local + template: + src: "firewallcmd-allports.local.j2" + dest: "/etc/fail2ban/action.d/firewallcmd-allports.local" + owner: "root" + group: "root" + mode: 0644 + notify: + - restart fail2ban -- name: install jail.local - template: src=jail.local.j2 dest=/etc/fail2ban/jail.local owner=root group=root mode=0644 +- name: install sshd jail + when: fail2ban_jails.sshd + template: + src: "sshd.jail.j2" + dest: "/etc/fail2ban/jail.d/sshd.local" + owner: "root" + group: "root" + mode: 0644 + notify: + - reload fail2ban jails -- name: install nginx-dos filter - template: src=nginx-dos.conf dest=/etc/fail2ban/filter.d/nginx-dos.conf owner=root group=root mode=0644 +- name: install postfix jail + when: fail2ban_jails.postfix + template: + src: "postfix.jail.j2" + dest: "/etc/fail2ban/jail.d/postfix.local" + owner: "root" + group: "root" + mode: 0644 + notify: + - reload fail2ban jails -- name: start and enable fail2ban service - service: name=fail2ban.service enabled=yes state=started +- name: install dovecot jail + when: fail2ban_jails.dovecot + template: + src: "dovecot.jail.j2" + dest: "/etc/fail2ban/jail.d/dovecot.local" + owner: "root" + group: "root" + mode: 0644 + notify: + - reload fail2ban jails +- name: start and enable service + systemd: + name: "fail2ban.service" + enabled: yes + state: started + daemon-reload: yes diff --git a/roles/fail2ban/templates/dovecot.jail.j2 b/roles/fail2ban/templates/dovecot.jail.j2 new file mode 100644 index 000000000..80aae27d5 --- /dev/null +++ b/roles/fail2ban/templates/dovecot.jail.j2 @@ -0,0 +1,8 @@ +# +# {{ansible_managed}} +# + +[dovecot] +enabled = true +findtime = 3600 ; 1 hour +maxretry = 8 diff --git a/roles/fail2ban/templates/fail2ban.local.j2 b/roles/fail2ban/templates/fail2ban.local.j2 new file mode 100644 index 000000000..6bf9be7eb --- /dev/null +++ b/roles/fail2ban/templates/fail2ban.local.j2 @@ -0,0 +1,12 @@ +# +# {{ansible_managed}} +# + +[Definition] + +# reduce logging verbosity by default; if we need to debug we can set it +# temporarily higher by using: fail2ban-client set loglevel INFO +loglevel = WARNING + +# we need to override the default pid path to /run instead of /var/run +pidfile = /run/fail2ban/fail2ban.pid diff --git a/roles/fail2ban/templates/fail2ban.service.j2 b/roles/fail2ban/templates/fail2ban.service.j2 new file mode 100644 index 000000000..eb8761b99 --- /dev/null +++ b/roles/fail2ban/templates/fail2ban.service.j2 @@ -0,0 +1,6 @@ +# the user journal files exceeds MaxNOFiles so increase the +# maximum number of open files +# Refer: https://github.com/fail2ban/fail2ban/issues/2208 + +[Service] +LimitNOFILE=8192 diff --git a/roles/fail2ban/templates/firewallcmd-allports.local.j2 b/roles/fail2ban/templates/firewallcmd-allports.local.j2 new file mode 100644 index 000000000..26352a00a --- /dev/null +++ b/roles/fail2ban/templates/firewallcmd-allports.local.j2 @@ -0,0 +1,8 @@ +# +# {{ansible_managed}} +# + +# creates the requisite chains in firewalld when fail2ban starts instead +# of creating them on first use (ie, when first IP is banned) +[Definition] +actionstart_on_demand = false diff --git a/roles/fail2ban/templates/jail.local.j2 b/roles/fail2ban/templates/jail.local.j2 index dcacf0bc9..1e68c2023 100644 --- a/roles/fail2ban/templates/jail.local.j2 +++ b/roles/fail2ban/templates/jail.local.j2 @@ -1,9 +1,30 @@ -[wiki-nginx-dos] -enabled = true -filter = nginx-dos -action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp] -logpath = /var/log/nginx/wiki.archlinux.org/access.log -# 400 pages in 30 minutes -findtime = 1800 -bantime = 1d -maxretry = 400 +# +# {{ansible_managed}} +# + +[DEFAULT] +findtime = {{fail2ban_findtime}} +bantime = {{fail2ban_bantime}} +maxretry = {{fail2ban_maxretry}} + +# don't trust dns +usedns = no + +# if f2b ever needs to send emails, send them to root and make sure the sender +# address clearly identifies the host the message originated from +destemail = root +sender = fail2ban@{{ansible_fqdn}} + +# use firewalld to manage bans - if we don't specify this, then fail2ban will +# default to use iptables, which we don't want as our systems are running +# firewalld with nftables backend. +# +# check current rules added to firewalld while fail2ban is running: +# firewall-cmd --direct --get-all-rules +# useful runtime commands include: +# fail2ban-client set <JAIL> banip <IP> +# fail2ban-cleint set <JAIL> unbanip <IP> +# fail2ban-client set unban <IP> +# fail2ban-client set unban --all +# see `fail2ban-client help` for full list of runtime commands +banaction = firewallcmd-allports diff --git a/roles/fail2ban/templates/postfix.jail.j2 b/roles/fail2ban/templates/postfix.jail.j2 new file mode 100644 index 000000000..4989375ff --- /dev/null +++ b/roles/fail2ban/templates/postfix.jail.j2 @@ -0,0 +1,9 @@ +# +# {{ansible_managed}} +# + +[postfix] +mode = aggressive +enabled = true +findtime = 3600 ; 1 hour +maxretry = 8 diff --git a/roles/fail2ban/templates/sshd.jail.j2 b/roles/fail2ban/templates/sshd.jail.j2 new file mode 100644 index 000000000..d156d2989 --- /dev/null +++ b/roles/fail2ban/templates/sshd.jail.j2 @@ -0,0 +1,6 @@ +# +# {{ansible_managed}} +# + +[sshd] +enabled = true -- GitLab