Files
wg-admin/FIREWALL.md
Calmcacil 22688d96b5 Fix firewall rules not loading on reboot
- Enable and start nftables service during installation
- Create /etc/nftables.conf that includes /etc/nftables.d/wireguard.conf
- nftables service now loads firewall rules automatically on boot
- Update documentation to reflect proper configuration file paths
- Remove historical VALIDATION.md document
- Clean up documentation references to non-existent scripts
2026-01-12 16:12:06 +01:00

4.6 KiB

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

sudo nft list ruleset

View specific chain

sudo nft list chain inet wireguard input

Add a rule

# 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

# 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 <handle_number>

Reload firewall

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

sudo nft list ruleset

Check service status

sudo systemctl status nftables

View blocked connections

# Count packets by rule
sudo nft -a list ruleset | grep -i counter

# Monitor connections
sudo conntrack -L

Test connectivity from client

# Test WireGuard port (from another machine)
nc -zuv velkhana.calmcacil.dev 51820

Verify forwarding

# 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

# Check NAT rules
sudo nft list table ip nat
sudo nft list table ip6 nat

Reset to defaults

# Flush all rules
sudo nft flush ruleset

# Reload from config
sudo nft -f /etc/nftables.conf

Debug with counters

# 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

# 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

# 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)

# 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