Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions configuration-files/roles/base/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@
name: ssh
state: restarted

- name: persist rules
community.general.iptables_state:
ip_version: "ip{{ item.ip_version }}"
state: saved
path: "/etc/iptables/rules.{{ item.ip_version }}"
loop:
- { ip_version: "v4" }
- { ip_version: "v6" }
- name: firewall | apply ruleset
systemd_service:
name: nftables
state: reloaded

- name: apply netplan
command: sudo netplan apply
Expand Down
338 changes: 18 additions & 320 deletions configuration-files/roles/base/tasks/firewall.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
state: latest
name:
- iptables
- iptables-persistent
- nftables

- name: firewall | uninstall software
package:
state: absent
name:
- iptables-persistent
- netfilter-persistent
- ufw

# Load firewall connection tracking kernel modules and reconnect.
Expand All @@ -21,322 +23,18 @@
- name: firewall | reset connection
meta: reset_connection

# Accessing the DNS resolver for administration purpose

- name: firewall | SSH | allow new incoming SYN packets on TCP port "{{ network_port_ssh }}" on v4 and v6
tags: init
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: tcp
destination: "{{ item.ip }}"
destination_port: "{{ network_port_ssh }}"
ctstate:
- ESTABLISHED
- NEW
- RELATED
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4 }}" }
- { version: "ipv6", ip: "{{ ip6 }}" }
notify:
- persist rules

- name: firewall | ICMP | allow ping
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: "{{ item.protocol }}"
jump: ACCEPT
loop:
- { version: "ipv4", protocol: "icmp" }
- { version: "ipv6", protocol: "icmpv6" }
notify:
- persist rules

# Communication between the DNS resolver and remote (DNS) servers

- name: firewall | DNS | allow remote server response from port 53/udp/tcp
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: "{{ item.protocol }}"
destination: "{{ item.ip }}"
source_port: "53"
ctstate:
- ESTABLISHED
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4 }}", protocol: "tcp" }
- { version: "ipv4", ip: "{{ ip4 }}", protocol: "udp" }
- { version: "ipv6", ip: "{{ ip6 }}", protocol: "tcp" }
- { version: "ipv6", ip: "{{ ip6 }}", protocol: "udp" }
notify:
- persist rules

- name: firewall | HTTP | allow remote server response from port 80/tcp and 443/tcp
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: tcp
destination: "{{ item.ip }}"
source_port: "{{ item.port }}"
ctstate: ESTABLISHED
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4 }}", port: "80" }
- { version: "ipv6", ip: "{{ ip6 }}", port: "80" }
- { version: "ipv4", ip: "{{ ip4 }}", port: "443" }
- { version: "ipv6", ip: "{{ ip6 }}", port: "443" }
notify:
- persist rules

- name: firewall | NTP | allow remote server response from port 123/udp
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: udp
source_port: "123"
destination: "{{ item.ip }}"
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4 }}" }
- { version: "ipv6", ip: "{{ ip6 }}" }
notify:
- persist rules

- name: firewall | loopback | allow loopback communication
iptables:
chain: INPUT
in_interface: "{{ if_loopback }}"
jump: ACCEPT
notify:
- persist rules

# Let's Encrypt ACME setup

- name: webserver | firewall | ensure port 31080/tcp is open on v6 (loopback)
iptables:
ip_version: "ipv6"
chain: "INPUT"
protocol: tcp
source: "{{ ip6 }}"
destination: "{{ ip6 }}"
jump: ACCEPT
notify:
- persist rules

- name: webserver | firewall | ensure port 31080/tcp is open on v6 (accept SYN)
iptables:
ip_version: "ipv6"
chain: "INPUT"
protocol: tcp
source: "{{ ip6_other }}"
destination_port: "31080"
jump: ACCEPT
notify:
- persist rules

- name: webserver | firewall | ensure port 31080/tcp is open on v6 (accept SYN/ACK)
iptables:
ip_version: "ipv6"
chain: "INPUT"
protocol: tcp
source: "{{ ip6_other }}"
source_port: "31080"
jump: ACCEPT
notify:
- persist rules

# VRRP communication between the DNS resolvers

- name: firewall | VRRP | allow v4 anv v6 vrrp traffic
iptables:
ip_version: "{{ item.version }}"
chain: "{{ item.chain }}"
destination: "{{ item.ip }}"
jump: ACCEPT
loop:
- { version: "ipv4", chain: "INPUT", ip: "224.0.0.18" }
- { version: "ipv4", chain: "OUTPUT", ip: "224.0.0.18" }
- { version: "ipv6", chain: "INPUT", ip: "ff02::12/128" }
- { version: "ipv6", chain: "OUTPUT", ip: "ff02::12/128" }
notify:
- persist rules

# DoT / DoH - communication between clients and the DNS resolver

- name: firewall | DoH/DoT | explicitly allow DNS server to receive queries from clients on port 80/tcp, 443/tcp and 853/tcp
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: tcp
destination: "{{ item.ip }}"
destination_ports:
- "80"
- "443"
- "853"
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}" }
notify:
- persist rules

- name: firewall | DoH/DoT NOTRACK | disable connection tracking on queries from clients
iptables:
ip_version: "{{ item.version }}"
table: raw
chain: PREROUTING
protocol: tcp
destination: "{{ item.ip }}"
jump: NOTRACK
loop:
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}" }
notify:
- persist rules

- name: firewall | DoH/DoT | explicitly allow DNS server to answer clients on port 80/tcp, 443/tcp and 853/tcp
iptables:
ip_version: "{{ item.version }}"
chain: OUTPUT
protocol: tcp
source: "{{ item.ip }}"
source_port: "{{ item.port }}"
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}", port: "80" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}", port: "80" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}", port: "80" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}", port: "80" }
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}", port: "443" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}", port: "443" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}", port: "443" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}", port: "443" }
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}", port: "853" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}", port: "853" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}", port: "853" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}", port: "853" }
notify:
- persist rules

- name: firewall | DoH/DoT NOTRACK | disable connection tracking on responses to clients
iptables:
ip_version: "{{ item.version }}"
table: raw
chain: OUTPUT
protocol: tcp
source: "{{ item.ip }}"
jump: NOTRACK
loop:
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_vip_dns2 }}" }
notify:
- persist rules

- name: firewall | DNS | reject unencrypted DNS
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: "{{ item.protocol }}"
destination: "{{ item.ip }}"
destination_port: "53"
jump: REJECT
loop:
- { version: "ipv4", protocol: "tcp", ip: "{{ ip4_vip_dns1 }}" }
- { version: "ipv4", protocol: "udp", ip: "{{ ip4_vip_dns2 }}" }
- { version: "ipv6", protocol: "tcp", ip: "{{ ip6_vip_dns1 }}" }
- { version: "ipv6", protocol: "udp", ip: "{{ ip6_vip_dns2 }}" }
notify:
- persist rules

# Statistics

- name: firewall | HTTP | allow server to answer requests on port 80/tcp and 443/tcp
iptables:
ip_version: "{{ item.version }}"
chain: INPUT
protocol: tcp
destination: "{{ item.ip }}"
destination_ports:
- "80"
- "443"
ctstate:
- NEW
- ESTABLISHED
jump: ACCEPT
loop:
- { version: "ipv4", ip: "{{ ip4 }}" }
- { version: "ipv6", ip: "{{ ip6 }}" }
notify:
- persist rules

- name: firewall | statistics | allow munin to measure incomming traffic
iptables:
ip_version: "{{ item.version }}"
action: insert
chain: INPUT
destination: "{{ item.ip }}"
loop:
- { version: "ipv4", ip: "{{ ip4 }}" }
- { version: "ipv6", ip: "{{ ip6 }}" }
- { version: "ipv4", ip: "{{ ip4_vrrp1 }}" }
- { version: "ipv6", ip: "{{ ip6_vrrp1 }}" }
- { version: "ipv4", ip: "{{ ip4_vrrp2 }}" }
- { version: "ipv6", ip: "{{ ip6_vrrp2 }}" }
- { version: "ipv4", ip: "{{ ip4_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_dns2 }}" }
notify:
- persist rules

- name: firewall | statistics | allow munin to measure outgoing traffic
iptables:
ip_version: "{{ item.version }}"
action: insert
chain: OUTPUT
source: "{{ item.ip }}"
loop:
- { version: "ipv4", ip: "{{ ip4 }}" }
- { version: "ipv6", ip: "{{ ip6 }}" }
- { version: "ipv4", ip: "{{ ip4_vrrp1 }}" }
- { version: "ipv6", ip: "{{ ip6_vrrp1 }}" }
- { version: "ipv4", ip: "{{ ip4_vrrp2 }}" }
- { version: "ipv6", ip: "{{ ip6_vrrp2 }}" }
- { version: "ipv4", ip: "{{ ip4_dns1 }}" }
- { version: "ipv6", ip: "{{ ip6_dns1 }}" }
- { version: "ipv4", ip: "{{ ip4_dns2 }}" }
- { version: "ipv6", ip: "{{ ip6_dns2 }}" }
notify:
- persist rules

# Drop policy

- name: firewall | drop on chain INPUT and FORWARD
iptables:
ip_version: "{{ item.version }}"
chain: "{{ item.chain }}"
policy: DROP
loop:
- { version: "ipv4", chain: "INPUT" }
- { version: "ipv4", chain: "FORWARD" }
- { version: "ipv6", chain: "INPUT" }
- { version: "ipv6", chain: "FORWARD" }
notify:
- persist rules
- name: firewall | cleanup
file:
state: absent
path: /etc/iptables

- name: firewall | rules
notify:
- firewall | apply ruleset
template:
src: nftables.conf.j2
dest: /etc/nftables.conf
validate: /usr/sbin/nft --check --file %s
owner: root
group: root
mode: 0644
Loading
Loading