5

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       
ksvi
  • 51
  • 1
  • 3

5 Answers5

1

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.
gevial
  • 1,434
0

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.

Fabio
  • 1,299
0

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?

rems
  • 2,258
0

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.

cwebber
  • 491
0

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.