# Firewall Configuration with nftables ## Overview This setup uses nftables (the modern successor to iptables) to secure the WireGuard VPN server. ## Configuration Details ### nftables Settings - **Dual-stack Support**: Single ruleset handles both IPv4 and IPv6 - **Default Incoming Policy**: Drop - **Default Outgoing Policy**: Accept - **Table Type**: `inet` (handles both IPv4 and IPv6) ### Allowed Services | Service | Port | Protocol | Description | |---------|------|----------|-------------| | SSH | 22 | TCP | Remote server access | | WireGuard | 51820 | UDP | VPN traffic | ### How It Works The firewall setup uses nftables with a unified architecture: 1. **inet Table**: Single table for both IPv4 and IPv6 filter rules - `input` chain: Filters incoming traffic - `forward` chain: Controls packet forwarding - `output` chain: Manages outgoing traffic 2. **NAT Tables**: Separate tables for IPv4 and IPv6 masquerading - `ip nat` table: IPv4 NAT masquerade for VPN traffic - `ip6 nat` table: IPv6 NAT masquerade for VPN traffic 3. **Rules**: - Loopback traffic allowed - Established/related connections allowed - Invalid packets dropped - SSH and WireGuard ports allowed - ICMP/ICMPv6 for basic connectivity - Forwarding from wg0 interface allowed - NAT masquerade for internet access ### Advantages over iptables/UFW - Single configuration file for IPv4/IPv6 - More efficient packet processing - Better performance on high-traffic systems - Modern, actively maintained ## Management Commands ### View firewall rules ```bash sudo nft list ruleset ``` ### View specific chain ```bash sudo nft list chain inet wireguard input ``` ### Add a rule ```bash # Allow TCP port 8080 sudo nft add rule inet wireguard input tcp dport 8080 accept # Allow UDP port 53 sudo nft add rule inet wireguard input udp dport 53 accept ``` ### Delete a rule ```bash # List rules with handle numbers sudo nft -a list chain inet wireguard input # Delete by handle number sudo nft delete rule inet wireguard input handle ``` ### Reload firewall ```bash sudo nft -f /etc/nftables.d/wireguard.conf ``` ## Important Notes 1. **SSH is always allowed**: The setup explicitly allows SSH to prevent lockout 2. **IPv4/IPv6 unified**: Single configuration handles both protocols 3. **Persistent rules**: nftables rules are saved in `/etc/nftables.d/wireguard.conf` 4. **No UFW dependency**: Direct nftables implementation 5. **Automatic on boot**: nftables service is enabled and starts automatically, loading rules from `/etc/nftables.conf` (which includes `/etc/nftables.d/wireguard.conf`) on system reboot ## Troubleshooting ### Check if nftables is active ```bash sudo nft list ruleset ``` ### Check service status ```bash sudo systemctl status nftables ``` ### View blocked connections ```bash # Count packets by rule sudo nft -a list ruleset | grep -i counter # Monitor connections sudo conntrack -L ``` ### Test connectivity from client ```bash # Test WireGuard port (from another machine) nc -zuv velkhana.calmcacil.dev 51820 ``` ### Verify forwarding ```bash # Check WireGuard interface ip addr show wg0 # Check forwarding is enabled sysctl net.ipv4.ip_forward sysctl net.ipv6.conf.all.forwarding ``` ### Verify NAT is working ```bash # Check NAT rules sudo nft list table ip nat sudo nft list table ip6 nat ``` ### Reset to defaults ```bash # Flush all rules sudo nft flush ruleset # Reload from config sudo nft -f /etc/nftables.conf ``` ### Debug with counters ```bash # Add counters to see rule hits sudo nft add rule inet wireguard input counter accept # View rule statistics sudo nft list ruleset ``` ## Advanced Usage ### Logging dropped packets ```bash # Add logging to input chain sudo nft add rule inet wireguard input log prefix "nft drop: " drop # View logs sudo journalctl -k | grep "nft drop" ``` ### Rate limiting ```bash # Rate limit SSH connections sudo nft add rule inet wireguard input tcp dport 22 ct state new limit rate 5/minute accept ``` ### Port knocking (simplified) ```bash # Three-step port knock on ports 1000, 2000, 3000 opens SSH sudo nft add rule inet wireguard input tcp dport 1000 ct state new update @knock { ip saddr timeout 60s } accept sudo nft add rule inet wireguard input tcp dport 2000 ip saddr @knock update @knock { ip saddr timeout 60s } accept sudo nft add rule inet wireguard input tcp dport 3000 ip saddr @knock update @knock { ip saddr timeout 60s } tcp dport 22 accept ``` ## Configuration Files ### Main configuration (loaded by nftables service) ``` /etc/nftables.conf ``` ### WireGuard rules ``` /etc/nftables.d/wireguard.conf ``` ### System service ``` /etc/systemd/system/nftables.service ```