How do I forward localhost traffic to a remote host with iptables?

9,338

Solution 1

I do not know how to configure iptables on this machine to do as you want. I usually use in such case SSH tunneling. I find it easy to set-up (personal opinion here!) ;-) but ... you need to have an SSH connection on your localhost (it does not need to be accessible from remote!).

The command syntax in this case is:

ssh -f -C -N -L [<bind address>:]<local port>:<remote host name>:<remote service port> [-p <ssh port>] [<username>@]<remote host outside name>

So for you that would mean:

ssh -f -C -N -L 127.0.0.1:8888:10.0.3.10:8888 localhost

Solution 2

The trick involves enabling localhost/localnet route processing for your outbound interface with:

sysctl -w net.ipv4.conf.all.route_localnet=1

Then this works:

iptables -t nat -A OUTPUT -m addrtype --src-type LOCAL --dst-type LOCAL -p tcp --dport 8888 -j DNAT --to-destination 10.0.3.10
iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE
Share:
9,338

Related videos on Youtube

Jonathan
Author by

Jonathan

I'm a programmer living and working in Glasgow, Scotland. Day-to-day, I work with Java, SQL, some JEE technologies, like JPA, and Javascript. I'm passionate about performance, and really interested in highly-scalable web applications. I enjoy working with legacy code (Crazy, I know!) because of its trove of interesting challenges.

Updated on September 18, 2022

Comments

  • Jonathan
    Jonathan almost 2 years

    I would like to set up my CentOS 6.5 box to forward connections to localhost (127.0.0.1) to the same port on a remote machine (e.g. 10.0.3.10).

    I've tried the iptables rule below, but when I attempt to connect, it just hangs:

    iptables -t nat -I OUTPUT --src 0/0 --dst 127.0.0.1 -p tcp --dport 8888 \
        -j DNAT --to-destination=10.0.3.10:8888
    

    Running tcpdump on the remote machine, I can see that there was no incoming traffic. I've done some google searches, but haven't turned up anything particularly useful. I've also confirmed that my sysctl.conf file contains net.ipv4.ip_forward = 1.

    Edit I've added logging in response to one of the comments below. It produces no output when I go to 127.0.0.1:8888 but does produce output when going to 10.0.3.10:

    # Generated by iptables-save v1.4.7 on Tue Jul 29 12:52:17 2014
    *nat
    :PREROUTING ACCEPT [0:0]
    :POSTROUTING ACCEPT [11:1008]
    :OUTPUT ACCEPT [11:1008]
    :LOGGING - [0:0]
    -A OUTPUT -p tcp -m tcp -d 10.0.3.10 --dport 8888 -j LOGGING
    -A LOGGING -j LOG --log-prefix "IPTABLES: "
    -A LOGGING -j ACCEPT
    -A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 8888 -j DNAT --to-destination 10.0.3.10:8
    888
    COMMIT
    # Completed on Tue Jul 29 12:52:17 2014
    # Generated by iptables-save v1.4.7 on Tue Jul 29 12:52:17 2014
    *filter
    :INPUT ACCEPT [50:2776]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [49:4336]
    COMMIT
    # Completed on Tue Jul 29 12:52:17 2014
    
    • Dennis Nolte
      Dennis Nolte almost 10 years
      is this on the same network, or do you have some additional router in between? if so: did you check there if the traffic is reaching it. check tcpdump locally to see if it exits to your interface. Additionally you could add logging in iptables to check if you enter the chain.
    • Jonathan
      Jonathan almost 10 years
      I've added logging and there are no messages being recorded. Both machines are on the same network (10.0.3.13 is my local machine, 10.0.3.10 is the remote). Tcpdump locally shows no traffic.
  • Jonathan
    Jonathan almost 10 years
    Thank-you. I ended up doing just this. iptables is so flexible but sometimes something that seems very simple on the surface is just impossible.