Files
wg-admin/FIREWALL.md
2026-01-12 15:23:32 +01:00

5.4 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

Enable/disable firewall

sudo nftables-firewall enable
sudo nftables-firewall disable

Allow additional ports

sudo nftables-firewall allow 80/tcp
sudo nftables-firewall allow 443/tcp

Allow from specific IP

# IPv4
sudo nftables-firewall allow from 192.168.1.100

# IPv6
sudo nftables-firewall allow from 2001:db8::/32

# CIDR range
sudo nftables-firewall allow from 192.168.1.0/24

Delete a rule

# List rules with numbers
sudo nft -a list chain inet wireguard input

# Delete by handle number
sudo nftables-firewall delete <handle_number>

Reload firewall

sudo nftables-firewall reload

Manually 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

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 starts automatically

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 nftables-firewall reload

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

/etc/nftables.d/wireguard.conf

System service

/etc/systemd/system/nftables.service

Management script

/usr/local/sbin/nftables-firewall

Migration from UFW

If migrating from a UFW-based setup:

UFW Command nftables Equivalent
ufw status nft list ruleset
ufw enable nftables-firewall enable
ufw disable nftables-firewall disable
ufw allow 80/tcp nft add rule inet wireguard input tcp dport 80 accept
ufw delete allow 80/tcp nft delete rule inet wireguard input handle <num>
ufw reset nft flush ruleset && nftables-firewall reload