Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

This question already has an answer here:

Quick summary: Forwarded port works from the outside world, but from the internal network using the external IP the connection is refused.

This is a simplified situation to make the explanation easier:

I have a computer that is running a service on port 12345. This computer has an internal IP 192.168.1.100 and is connected directly to a modem/router which has internal IP 192.168.1.1 and external (public, static) IP 1.2.3.4. (The router is TP-LINK TD-w8960N) I have set up port forwarding (virtual server) at port 12345 to go to port 12345 at 192.168.1.100.

If I run telnet 192.168.1.100 12345 from the same computer everything works. But running telnet 1.2.3.4 12345 says connection refused. If I do this on another computer (on the same internal network, connected to the router) the same thing happens. This would seem like the port forwarding is not working. However...

If I run a online port checking service on my external IP and the service port it says the port is open and I can see the remote server connecting and immediately closing connection. And using another computer that is connected to the internet using a mobile connection I can also use telnet 1.2.3.4 12345 and I get a working connection.

So the port forwarding seems to be working, however using external IP from the internal network doesn't. I have no idea what can be causing this, since another setup very much like this (different router) works for me. I can access a service running on a server from inside the network both through the internal and external IP.


Note: I know I could just use the internal IP inside of the network to access this service. But if I have a laptop that must be able to do this both from inside and outside it would be annoying to constantly switch between 1.2.3.4 and 192.168.1.100 in the software configuration.


Router output:

> iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            224.0.0.0/3         
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:25 to:192.168.1.101 
DNAT       udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:25 to:192.168.1.101 
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:110 to:192.168.1.101 
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:12345 to:192.168.1.102 
DNAT       udp  --  0.0.0.0/0            192.168.1.1         udp dpt:53 to:217.118.96.203 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.1.0/24       0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination       
share|improve this question

marked as duplicate by MadHatter, Dave M, Falcon Momot, Rex, Michael Hampton Nov 30 '13 at 17:26

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Would you please show us the FORWARD chain from the filter table? tcp/12345 still has to be allowed there and since you get a connection reused, you might be hitting a REJECT rule there. Edit: Just noticed, this posting is kinda... old. Feel free to answer if you are sill having the problem (I hope you sorted this out by now;) –  Alexander Janssen Oct 12 '12 at 6:43
    
related: superuser.com/questions/470883/… –  David Cary Dec 31 '12 at 18:08

5 Answers 5

Sure it wouldn't work! When you send packets from LAN-connected host to 1.2.3.4:12345, packets go via default route to your router, which changes the destination address to 192.168.1.100. It is OK. But when server tries to respond, it sees that the source address (it remains original, 192.168.1.xx) is on the same LAN, and send packets directly, not via router. So, you host do not understand these responses since their source address (192.168.1.100) is not the same as the orignal packets destintion address (1.2.3.4)!

The best solutions are:

  1. Configure iptables on server to SNAT local address to 1.2.3.4
  2. Configure DNS caching server on router and assign the LAN IP address to DNS name of the server. Thus, external clients would use external IP, while internal clients would use internal IP. And the DNS name would be the same.
share|improve this answer


I found the following to work - taken from http://www.tomshardware.com/forum/12532-42-iptables-access-local-server-external

Example: (external ip 1.1.1.1, internal network 192.168.1.0/24, webserver 192.168.1.10, router 192.168.1.1)

Connect via SSH and then enter:

iptables -t nat -A PREROUTING -d 1.1.1.1 -m tcp -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10

Repeat for each port you have forwarded.

Then enter the following ONE SNAT rule:

iptables -t nat -A POSTROUTING -d 192.168.1.10 -s 192.168.1.0/24 -j SNAT --to-source 192.168.1.1

It seems to work just fine, but I can't figure out how to save it to survive a router restart.

share|improve this answer

The connection refused seems to be of interest here. If it were a routing issue, the telnet would timeout or say no route to host. I would start with a packet trace on the box that is hosting the service and try connecting again through the public IP. This will at least help you to see whether the connection is getting through the router. If it gets through, then you should dig more on the host. If it doesn't get through, there is likely a firewall or some other configuration parameter on the router that is causing issues. You may want to try a different router.

share|improve this answer

There must be some IP control configured somewhere blocking your access. You wrote it works for you in a similar setup, and I can confirm that this also works for me in a very similar setup.

Did you try running tcpdump on the network interface on 192.168.1.100 to see if the packets are arriving there at all at port 12345?

tcpdump -i eth0 port 12345

With which IP address are the packets arriving? Is your application perhaps blocking this IP range?

Have you checked your /etc/hosts.deny and /etc/hosts.allow configurations?

share|improve this answer
    
I tried that, local IP/remote connection on external IP works great, remote IP from inside shows nothing. –  ksvi Feb 16 '11 at 15:44
    
Then the router is somehow not forwarding for IP coming from inside ... but you wrote it works on a similar configuration? What is different here to the configuration that works? –  rems Feb 16 '11 at 16:32

As far as I know you can't do that.

Try to traceroute the connection, any host on internal network choose 192.168.1.1 as next hop for 1.2.3.4 then the router should handle this connection but I think that it cannot forward connection from inside to inside.

You have to see which level of control you have on the router, if it was a linux server you could play with iptables, but a device like that doesn't offer that level of control on network configuration.

share|improve this answer
    
I found that some routers don't have IP loopback, maybe that is the case? There is a static routing option (portforward.com/routergui/TP-Link/TD-W8960N/…) but I'm not sure how to set it up. Also, even if I managed to somehow map the external IP from inside to an internal one, there might be need to have a different port map to a different internal IP and then this won't work. –  ksvi Feb 16 '11 at 15:47
    
Maybe. Just to be sure, can you ping the external address from inside the network? And if yes, can you connect to web interface from inside (using the external address)? Remember that most router deny this by default so you have to enable remote administration from WAN. If you can't even do these tasks I think you have no way to solve your issue. –  Fabio Feb 16 '11 at 15:52
    
I can do both. Ping works OK and also web interface. BTW, there is SSH running on the router and also iptables (v.1.3.8) but I'm not familiar with it. Could you tell me how to make server.example.com(=1.2.3.4) from inside actually connect directly to 192.168.1.100 ? –  ksvi Feb 16 '11 at 15:56
    
If you can ssh into the router you should edit your question and post the output of iptables -t nat -L -n. Also post the output of traceroute 1.2.3.4 from inside the network –  Fabio Feb 16 '11 at 16:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.