--- nftables_configuration: | flush ruleset table inet firewall { set tcp_accepted { type inet_service elements = { # OpenSSH ssh, # NGINX http, https } } {% if "mail" in group_names %} set mail_accepted { type inet_service elements = { # Mail configuration sieve, # Mail submission smtp, smtps, submission, # Mail receiving imap, imaps } } {% endif %} {% if "databases" in group_names %} # Access control for database server set possible_lke_ipv4_addrs { type ipv4_addr flags interval elements = { {{ lke_frankfurt_ipv4_addresses | join(", ") }} } } set possible_lke_ipv6_addrs { type ipv6_addr flags interval elements = { {{ lke_frankfurt_ipv6_addresses | join(", ") }} } } {% endif %} chain input { type filter hook input priority 0 # Drop anything not explicitly dropped or accepted by default policy drop # Drop invalid packets ct state invalid drop # Allow already established connections ct state established,related accept # Allow loopback iif lo accept # Allow certain inbound ICMP types (ping, traceroute). # With these allowed you are a good network citizen. meta l4proto { icmp, ipv6-icmp } counter accept # Standard allowed ports iifname {{ ansible_default_ipv4.interface }} tcp dport @tcp_accepted ct state new accept {% if ansible_default_ipv4.interface != ansible_default_ipv6.interface %} iifname {{ ansible_default_ipv6.interface }} tcp dport @tcp_accepted ct state new accept {% endif %} # WireGuard client connections iifname {{ ansible_default_ipv4.interface }} udp dport {{ wireguard_port }} ct state new accept {% if ansible_default_ipv4.interface != ansible_default_ipv6.interface %} iifname {{ ansible_default_ipv6.interface }} udp dport {{ wireguard_port }} ct state new accept {% endif %} # Node Exporter port for Prometheus scraping over WireGuard iifname wg0 tcp dport 9100 ct state new accept # Munin scraping over WireGuard iifname wg0 tcp dport 4949 ct state new accept {% if "databases" in group_names %} # PostgreSQL connections iifname {{ ansible_default_ipv4.interface }} ip saddr @possible_lke_ipv4_addrs tcp dport postgresql ct state new accept {% if ansible_default_ipv6 is defined %} iifname {{ ansible_default_ipv6.interface }} ip6 saddr @possible_lke_ipv6_addrs tcp dport postgresql ct state new accept {% endif %} {% endif %} {% if "mail" in group_names %} # Inbound mail iifname {{ ansible_default_ipv4.interface }} tcp dport @mail_accepted ct state new accept {% if ansible_default_ipv6 is defined %} iifname {{ ansible_default_ipv6.interface }} tcp dport @mail_accepted ct state new accept {% endif %} {% endif %} {% if "jitsi" in group_names %} # Ports needed by Jitsi define jitsi_tcp_ports = {5349} define jitsi_udp_ports = {3478, 10000} iifname {{ ansible_default_ipv4.interface }} tcp dport $jitsi_tcp_ports ct state new accept iifname {{ ansible_default_ipv4.interface }} udp dport $jitsi_udp_ports ct state new accept {% if ansible_default_ipv6 is defined %} iifname {{ ansible_default_ipv6.interface }} tcp dport $jitsi_tcp_ports ct state new accept iifname {{ ansible_default_ipv6.interface }} udp dport $jitsi_udp_ports ct state new accept {% endif %} {% endif %} } chain forward { type filter hook forward priority 0 policy drop ct state invalid drop ct state established,related accept iifname wg0 ip daddr 10.0.0.0/8 accept } chain output { type filter hook output priority 0 policy accept ip6 nexthdr ipv6-icmp accept } chain postrouting { type nat hook postrouting priority 100; } }