Igor Bubelov About Blog Photos

IP Forwarding With Nftables

August 23, 2020

I have a Digital Ocean droplet which I use as a proxy for my self-hosted home server. I’ve been using some hacky solution based on iptables but it was a pain in the ass, so I’ve decided to get rid of this piece of technical debt and the first thing that I noticed was the deprecation of iptables utility itself.

It certainly looks like nftables is the future, so I played with it for a while, and I settled with the following config for my proxy:

#!/usr/sbin/nft -f

define wan = eth0
define wg = wg0
define wg_net = 10.0.0.0/24

# TODO Since Linux kernel 5.2, there is support for performing stateful NAT in inet family chains.
table ip wg {
  chain prerouting {
    # Priority = NF_IP_PRI_NAT_DST (-100, destination NAT)
    type nat hook prerouting priority -100;
    iif $wan tcp dport { http, https } dnat 10.0.0.2
  }

  chain postrouting {
    # Priority = NF_IP_PRI_NAT_SRC (100, source NAT)
    type nat hook postrouting priority 100;
    # Mask WireGuard packets as if they come from this server
    oif $wan ip saddr $wg_net masquerade
  }

  chain input {
    type nat hook input priority 100;
  }

  chain output {
    type nat hook output priority -100;
  }
}

It looks way cleaner than the iptables equivalent, and it can certainly be refactored to look even more readable. I really like its declarative way of describing the traffic rules.

The prerouting chain just redirects all the TCP traffic coming to the ports 80 or 443 to my home-based Raspberry Pi 4. Both DO droplet and RPi share the same WireGuard network between them. The RPi IP address is 10.0.0.2, that’s why dnat points there in the config above. I should probably convert this magic number into a variable, thankfully nftables supports that.

The postrouting chain is pretty interesting. It allows me to use that DO droplet as a VPN server. It masks all the outgoing traffic with this server’s IP address but that traffic can originate from any node in my WireGuard network. Such a VPN won’t give you a lot of privacy since most of the mainstream hosting providers know your name, email and even your credit card info, but it can certainly be used to circumvent certain kinds of Internet censorship in your real location.