Unable to get NAT working via iptables PREROUTING chain

8,886

Solution 1

I actually got this working by ensuring the kernel module "br_netfilter" was loaded on the host machine. It was as simple as that, annoyingly simple after being stumped for so long.

Documentation/articles that lead me to the solution:

1)

https://github.com/omribahumi/libvirt_metadata_api and https://thewiringcloset.wordpress.com/2013/03/27/linux-iptable-snat-dnat/

See "Setting up iptables" section – I'm using 'DNAT' instead of 'REDIRECT' bc 'REDIRECT' simply redirects traffic to an interface on the local system, rather than forwarding to a removed address as in the case of destination NAT.

2)

https://serverfault.com/questions/179200/difference-beetween-dnat-and-redirect-in-iptables and https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO-6.html

Helped me understand the diff between REDIRECT & DNAT, as stated above.

3)

https://github.com/omribahumi/libvirt_metadata_api/pull/4/files

This commit led me to the actual solution (the above things I'd already been doing before, but to no avail).

Solution 2

You should put dnat in the OUTUPT chain because packets generated locally would not pass the PREROUTING chain.

Share:
8,886

Related videos on Youtube

Andre Goree
Author by

Andre Goree

Updated on September 18, 2022

Comments

  • Andre Goree
    Andre Goree over 1 year

    So, not concerning ourselves with the WHY, and more so with the HOW, I'd like to see if anyone knows where I'm going wrong here.

    Basically, I'd like to forward all packets headed for port 80 on an IP that I've aliased to the loopback device (169.254.169.254) to be forwarded to port 8080 on another IP, which happens to be the public IP of the same box (we'll use 1.1.1.1 for the purpose of this question). In doing so, I should [ostensbily] be able to run

    telnet 169.254.169.254 80
    

    and reach 1.1.1.1:8080, however, this is not happening.

    Here is my nat table in iptables:

    ~# iptables -nvL -t nat
    Chain PREROUTING (policy ACCEPT 66 packets, 3857 bytes)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            169.254.169.254      tcp dpt:80 to:1.1.1.1:8080
    
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    

    Am I missing something? I've followed most the information in the iptables man pages and also in the links below, however, am still getting a "connection refused" during my telnet attempts. I have tried adding ~#iptables -t nat -A POSTROUTING -j MASQUERADE to my iptables, but to no avail :/

    If anyone could point me in the right direction that would be phenomenal!

    http://linux-ip.net/html/nat-dnat.html

    https://www.frozentux.net/iptables-tutorial/chunkyhtml/x4033.html

    EDIT I wanted to add that I do indeed have the following sysctl parameter enabled ~# sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1

    EDIT No. 2 I was able to solve this by adding the rule to the OUTPUT chain in the nat table, v.s. the PREROUTING chain as I originally tried.

    • Admin
      Admin about 8 years
      You don't need port 8080, I watch 8080 in your output.
    • Admin
      Admin about 8 years
      had you enabled the net.ipv4.ip_forward=1 parameter?
    • Admin
      Admin about 8 years
      Ah yes, I forgot to mention in my question that I HAVE indeed enabled that sysctl parameter: ~# sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1
    • Admin
      Admin about 8 years
      @PersianGulf I'm not sure what you're saying...can you elaborate?