NFTables – Route IPv6 to Localhost and NAT to Loopback

ipv6nftables

I'm trying to route incoming http internet traffic to [::1]:8080 which is where my http server binds to. I'm using nftables on an IPv6-only device. If I add following rules:

  sudo nft flush ruleset
  sudo nft add table ip6 nat
  sudo nft add chain ip6 nat prerouting { type nat hook prerouting priority 0 \; }
  sudo nft add chain ip6 nat postrouting { type nat hook postrouting priority 100 \; }

  sudo nft add rule ip6 nat prerouting ip6 daddr [global-ip6] tcp dport 80 dnat to ::1 :8080

  sudo nft list ruleset

with resulting ruleset:

table ip6 nat {
  chain prerouting {
    type nat hook prerouting priority 0; policy accept;
    ip6 daddr [global-ip6] tcp dport http dnat to [::1]:http-alt
  }

  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
  }
}

then requests to [global-ip6]:80 get swallowed (there is no connection refused error) but no connection is established.

If I use one of the rules

sudo nft add rule ip6 nat prerouting tcp dport 80 redirect to 8080

or

sudo nft add rule ip6 nat prerouting ip6 daddr [global-ip6] tcp dport 80 dnat to [global-ip6] :8080

and bind my program to [global-ip6]:8080, then communication works as expected.

Do you have an idea what I am missing? I tried out some rules in the postrouting and input chains but couldn't get it to work. Back with IPv4 and iptables I had to do sudo sysctl -w net.ipv4.conf.all.route_localnet=1, maybe there is a similar IPv6 flag?

Best Answer

Unfortunately you cannot achieve what you want with the nftables.

After the dnat target the destination address is rewritten to the loopback address (::1), and then the incoming packet is processed by the routing code. But any incoming packet with the loopback destination address has been received from outside MUST be dropped by RFC 4291 2.5.3. There aren't any sysctl variables to change this behavior.

You can run some proxy app, that will be accept connection on the external address and connects to the application that listens the loopback address.