Securing VPN traffic with nftables ensures that all traffic routes through the VPN interface, preventing leaks. This setup enhances privacy by blocking traffic if the VPN connection drops.
A working VPN connection (e.g., WireGuard, OpenVPN).
Root access to the system.
nftables installed and running.
Identify Interfaces:
Determine your VPN interface name (e.g., wg0, tun0). Use ip link or ifconfig.
Identify your physical network interface (e.g., eth0, wlan0).
Flush Existing Rules:
nft flush ruleset
Define Variables:
VPN_IF=wg0 # Replace with your VPN interface
PHYS_IF=eth0 # Replace with your physical interface
VPN_IP=10.66.66.2 # Replace with your VPN server IP
Create nftables Configuration:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state {established, related} accept
iif $PHYS_IF tcp dport ssh accept #Optional: allow SSH
reject with icmpx type port-unreachable
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state {established, related} accept
iif $PHYS_IF oif $VPN_IF accept
iif $VPN_IF oif $PHYS_IF tcp dport 80 accept #Optional: Allow HTTP
iif $VPN_IF oif $PHYS_IF tcp dport 443 accept #Optional: Allow HTTPS
reject with icmpx type port-unreachable
}
chain output {
type filter hook output priority 0; policy drop;
oif lo accept
ct state {established, related} accept
oif $VPN_IF accept
# Allow DNS resolution through VPN
udp dport 53 oif $VPN_IF accept
tcp dport 53 oif $VPN_IF accept
#Allow VPN connection
oif $PHYS_IF ip daddr $VPN_IP udp dport 51820 accept #WireGuard example
reject with icmpx type port-unreachable
}
}
Load Rules:
Save the above configuration to a file (e.g., /etc/nftables.conf).
Load the ruleset:
nft -f /etc/nftables.conf
Enable on Boot:
Enable the nftables service to load rules on boot:
systemctl enable nftables
systemctl start nftables
Verify Rules: Use nft list ruleset to confirm that the rules are loaded correctly.
Test Connectivity: Ensure you can access the internet through the VPN.
Incorrect Interface Names: Double-check that $VPN_IF and $PHYS_IF are correct.
Missing VPN IP: Ensure $VPN_IP is the correct IP address of your VPN server.
Conflicting Rules: Existing firewall rules may conflict with the nftables configuration. Flush existing rules before applying the new configuration.
DNS Leaks: Ensure DNS requests are routed through the VPN interface.
Verified VPN interface name.
Verified physical interface name.
Verified VPN server IP address.
Loaded nftables ruleset.
Enabled nftables on boot.
Tested internet connectivity through VPN.
Verified no DNS leaks.