#!/usr/sbin/nft -f define WAN_IF = enp1s0 define WAN_IP = 192.168.122.254 define LAN_IF = enp7s0 define LAN_IP = 10.0.0.254 define LAN_NET = 10.0.0.0/24 define DMZ_IF = enp8s0 define DMZ_IP = 10.0.200.254 define DMZ_NET = 10.0.200.0/24 define WAN_DNS = { 172.20.254.81, 8.8.8.8, 8.8.4.4, 208.67.222.123, 208.67.220.123 } # Google and OpenDNS servers define SSH_SERVER = 10.0.200.2 define VPN_SERVER = 10.0.200.2 define WEB_SERVER = 10.0.200.1 define IT_HOSTS = 10.0.0.50 flush ruleset table ip6 filter { chain INPUT { type filter hook input priority filter; policy drop; } chain OUTPUT { type filter hook output priority filter; policy drop; } chain FORWARD { type filter hook forward priority filter; policy drop; } } table ip filter { chain LAN_to_FW { ip saddr $IT_HOSTS tcp dport 22 counter accept comment "Accept SSH" } chain FW_to_WAN { ip daddr $WAN_DNS tcp dport 53 counter accept comment "DNS from FW (TCP)" ip daddr $WAN_DNS udp dport 53 counter accept comment "DNS from FW (UDP)" tcp dport { http, https } counter accept comment "Web traffic from FW" } chain LAN_to_WAN { ip daddr $WAN_DNS tcp dport 53 counter accept comment "DNS from LAN (TCP)" ip daddr $WAN_DNS udp dport 53 counter accept comment "DNS from LAN (UDP)" tcp dport { http, https } counter accept comment "Web traffic from LAN" } chain LAN_to_DMZ { ip daddr $WEB_SERVER tcp dport { http, https } counter accept comment "Access web servers from LAN" ip saddr $IT_HOSTS tcp dport 22 counter accept comment "Access to DMZ Servers (SSH) from IT admins" } chain DMZ_to_WAN { tcp dport 53 counter accept comment "DNS from DMZ (TCP)" udp dport 53 counter accept comment "DNS from DMZ (UDP)" tcp dport { http, https } counter accept comment "Web traffic from DMZ" } chain WAN_to_DMZ { ip daddr $WEB_SERVER tcp dport { 80, 443 } counter accept comment "Accept WEB" ip daddr $SSH_SERVER tcp dport 22 counter accept comment "Accept SSH (port 22)" ip daddr $VPN_SERVER udp dport 3394 counter accept comment "Accept OpenVPN (port 3394)" } chain input { type filter hook input priority filter; policy drop; iif lo accept comment "Accept any localhost traffic" ct state invalid drop comment "Drop invalid connections" ct state established,related accept comment "Accept traffic originated from us" meta l4proto icmp counter accept comment "Accept ICMP" ip protocol igmp counter accept comment "Accept IGMP" iif $LAN_IF ip daddr $LAN_IP ct state new jump LAN_to_FW comment "Connections from LAN to FW" iif $WAN_IF ip daddr $WAN_IP tcp dport 22 ct state new counter accept comment "Direct connection from WAM (debug in virtual)" } chain forward { type filter hook forward priority filter; policy drop; ct state invalid drop comment "Drop invalid connections" ct state established,related accept comment "Accept traffic originated from us" meta l4proto icmp counter accept comment "Accept ICMP" iif $LAN_IF oif $WAN_IF ip saddr $LAN_NET ct state new jump LAN_to_WAN iif $LAN_IF oif $DMZ_IF ip saddr $LAN_NET ip daddr $DMZ_NET ct state new jump LAN_to_DMZ iif $DMZ_IF oif $WAN_IF ip saddr $DMZ_NET ct state new jump DMZ_to_WAN iif $WAN_IF oif $DMZ_IF ip daddr $DMZ_NET ct state new jump WAN_to_DMZ } chain output { # Accept every outbound connection type filter hook output priority filter; policy drop; oif lo accept comment "Accept any localhost traffic" ct state invalid drop comment "Drop invalid connections" ct state established,related accept comment "Accept traffic originated from us" meta l4proto icmp counter accept comment "Accept ICMP" ip protocol igmp counter accept comment "Accept IGMP" oif $WAN_IF ct state new jump FW_to_WAN } } table nat { chain masquerading { type nat hook postrouting priority srcnat; oif $WAN_IF masquerade; } chain port_forwarding { type nat hook prerouting priority dstnat; iif $WAN_IF tcp dport { 80, 443 } dnat to $WEB_SERVER iif $WAN_IF tcp dport 1313 dnat to $SSH_SERVER:22 iif $WAN_IF udp dport 3394 dnat to $VPN_SERVER } }