diff --git a/roles/common/tasks/firewall_Ubuntu.yml b/roles/common/tasks/firewall_Ubuntu.yml index eb3619f..2d6b920 100644 --- a/roles/common/tasks/firewall_Ubuntu.yml +++ b/roles/common/tasks/firewall_Ubuntu.yml @@ -1,7 +1,14 @@ --- +# Ubuntu 20.04 will use nftables directly, with no firewalld. +# Ubuntu 18.04 will use firewalld with the nftables backend. +# Ubuntu 16.04 will use firewalld with the iptables backend. - block: + - include_tasks: firewall_Ubuntu_cleanup.yml + when: ansible_distribution_version is version('20.04', '==') + - name: Set Ubuntu firewall packages + when: ansible_distribution_version is version('20.04', '<') set_fact: ubuntu_firewall_packages: - firewalld @@ -9,47 +16,57 @@ - fail2ban - python3-systemd # for fail2ban systemd backend - - name: Install firewalld and deps - when: ansible_distribution_version is version('16.04', '>=') + - name: Set Ubuntu firewall packages + when: ansible_distribution_version is version('20.04', '>=') + set_fact: + ubuntu_firewall_packages: + - fail2ban + - libnet-ip-perl # for aggregate-cidr-addresses.pl + - nftables + - python3-systemd + + - name: Install firewall packages apt: pkg={{ ubuntu_firewall_packages }} state=present - name: Remove ufw when: ansible_distribution_version is version('16.04', '>=') apt: pkg=ufw state=absent - # I'm not sure why, but you can use firewalld with the nftables backend even - # if nftables itself is not installed. In that case the only way to see the - # currently active rules is with firewall-cmd. I prefer installing nftables - # so that we can have somewhat of a parallel with iptables: - # - # nft list ruleset - # - # See: https://firewalld.org/2018/07/nftables-backend - - name: Install nftables - when: ansible_distribution_version is version('20.04', '==') - apt: pkg=nftables state=present + - name: Start and enable nftables + when: ansible_distribution_version is version('20.04', '>=') + systemd: name=nftables state=started enabled=yes - - name: Use nftables backend in firewalld - when: ansible_distribution_version is version('20.04', '==') - lineinfile: - dest: /etc/firewalld/firewalld.conf - regexp: '^FirewallBackend=iptables$' - line: 'FirewallBackend=nftables' + - name: Copy nftables.conf + when: ansible_distribution_version is version('20.04', '>=') + template: src=nftables.conf.j2 dest=/etc/nftables.conf owner=root mode=0644 notify: - - restart firewalld + - reload nftables + + - name: Create /etc/nftables extra config directory + when: ansible_distribution_version is version('20.04', '>=') + file: path=/etc/nftables state=directory owner=root mode=0755 + + - name: Copy extra nftables configuration files + when: ansible_distribution_version is version('20.04', '>=') + copy: src={{ item }} dest=/etc/nftables/{{ item }} owner=root group=root mode=0644 force=no + loop: + - spamhaus-ipv4.nft + - spamhaus-ipv6.nft + notify: + - reload nftables - name: Copy firewalld public zone file - when: ansible_distribution_version is version('16.04', '>=') + when: ansible_distribution_version is version('18.04', '<=') template: src=public.xml.j2 dest=/etc/firewalld/zones/public.xml owner=root mode=0600 - name: Format public.xml firewalld zone file - when: ansible_distribution_version is version('16.04', '>=') + when: ansible_distribution_version is version('18.04', '<=') command: tidy -xml -iq -m -w 0 /etc/firewalld/zones/public.xml notify: - restart firewalld - - name: Copy ipsets of abusive IPs - when: ansible_distribution_version is version('16.04', '>=') + - name: Copy firewalld ipsets of abusive IPs + when: ansible_distribution_version is version('18.04', '<=') copy: src={{ item }} dest=/etc/firewalld/ipsets/{{ item }} owner=root group=root mode=0600 loop: - abusers-ipv4.xml @@ -59,30 +76,49 @@ notify: - restart firewalld - - name: Copy Spamhaus update script - when: ansible_distribution_version is version('16.04', '>=') + - name: Copy Spamhaus firewalld update script + when: ansible_distribution_version is version('18.04', '<=') copy: src=update-spamhaus-lists.sh dest=/usr/local/bin/update-spamhaus-lists.sh mode=0755 owner=root group=root - - name: Copy Spamhaus systemd units - when: ansible_distribution_version is version('16.04', '>=') + - name: Copy Spamhaus firewalld systemd units + when: ansible_distribution_version is version('18.04', '<=') copy: src={{ item }} dest=/etc/systemd/system/{{ item }} mode=0644 owner=root group=root loop: - update-spamhaus-lists.service - update-spamhaus-lists.timer - register: spamhaus_systemd_units + register: spamhaus_firewalld_systemd_units + + - name: Copy Spamhaus nftables update scripts + when: ansible_distribution_version is version('20.04', '>=') + copy: src={{ item }} dest=/usr/local/bin/{{ item }} mode=0755 owner=root group=root + loop: + - update-spamhaus-nftables.sh + - aggregate-cidr-addresses.pl + + - name: Copy Spamhaus nftables systemd units + when: ansible_distribution_version is version('20.04', '>=') + copy: src={{ item }} dest=/etc/systemd/system/{{ item }} mode=0644 owner=root group=root + loop: + - update-spamhaus-nftables.service + - update-spamhaus-nftables.timer + register: spamhaus_nftables_systemd_units # need to reload to pick up service/timer/environment changes - name: Reload systemd daemon systemd: daemon_reload=yes - when: spamhaus_systemd_units is changed + when: spamhaus_firewalld_systemd_units is changed or + spamhaus_nftables_systemd_units is changed - - name: Start and enable Spamhaus update timer - when: ansible_distribution_version is version('16.04', '>=') + - name: Start and enable Spamhaus firewalld update timer + when: ansible_distribution_version is version('18.04', '<=') systemd: name=update-spamhaus-lists.timer state=started enabled=yes - notify: - restart firewalld + - name: Start and enable Spamhaus nftables update timer + when: ansible_distribution_version is version('20.04', '>=') + systemd: name=update-spamhaus-nftables.timer state=started enabled=yes + - include_tasks: fail2ban.yml when: ansible_distribution_version is version('16.04', '>=') tags: firewall diff --git a/roles/common/tasks/firewall_Ubuntu_cleanup.yml b/roles/common/tasks/firewall_Ubuntu_cleanup.yml new file mode 100644 index 0000000..8bc6629 --- /dev/null +++ b/roles/common/tasks/firewall_Ubuntu_cleanup.yml @@ -0,0 +1,40 @@ +--- +# Clean up previous firewalld configuration on Ubuntu 20.04, now that we are +# migrating to a pure nftables configuration. + +- name: Stop and disable firewalld + systemd: name=nftables state=stopped enabled=no + +- name: Set Ubuntu firewall packages to remove + set_fact: + ubuntu_firewall_packages: + - firewalld + - tidy + +- name: Remove old firewall packages + apt: pkg={{ ubuntu_firewall_packages }} state=absent + +- name: Remove old firewalld zone and ipsets + file: dest={{ item }} state=absent + loop: + - /etc/firewalld/zones/public.xml + - /etc/firewalld/ipsets/abusers-ipv4.xml + - /etc/firewalld/ipsets/abusers-ipv6.xml + - /etc/firewalld/ipsets/spamhaus-ipv4.xml + - /etc/firewalld/ipsets/spamhaus-ipv6.xml + +- name: Stop and disable old Spamhaus firewalld systemd timer + systemd: name=update-spamhaus-lists.timer state=stopped enabled=no + +- name: Remove old Spamhaus firewalld update script and systemd units + file: dest=/usr/local/bin/update-spamhaus-lists.sh state=absent + loop: + - /usr/local/bin/update-spamhaus-lists.sh + - /etc/systemd/system/update-spamhaus-lists.service + - /etc/systemd/system/update-spamhaus-lists.timer + +# need to reload to pick up service/timer/environment changes +- name: Reload systemd daemon + systemd: daemon_reload=yes + +# vim: set sw=2 ts=2: diff --git a/roles/common/templates/etc/fail2ban/jail.d/sshd.local.j2 b/roles/common/templates/etc/fail2ban/jail.d/sshd.local.j2 index 9df015f..3dafcbd 100644 --- a/roles/common/templates/etc/fail2ban/jail.d/sshd.local.j2 +++ b/roles/common/templates/etc/fail2ban/jail.d/sshd.local.j2 @@ -2,7 +2,7 @@ enabled = true # See: /etc/fail2ban/filter.d/sshd.conf filter = sshd -{% if ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11', '>=') %} +{% if (ansible_distribution == 'Debian' and ansible_distribution_major_version is version('11', '>=')) or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('20.04', '>=')) %} # Integrate with nftables banaction=nftables[type=allports] {% else %}