5

I have an SSH server behind a NAT router. Machines on the same (NAT'd) network as the SSH server can only connect to the SSH server using the LAN IP, not the WAN IP. Why?

My network looks like this:

(the Internet, via Comcast)
      |
      | (cable line)
  comcast modem. ← External IP of a.b.c.d,
      |            internal IP of 10.1.10.1 on 10.1.10.0/24
      |
      |
   box running sshd  (10.1.10.201)

I run an SSH service behind a Comcast router performing NAT. Using the IP address obtained above, I can run ssh me@«that IP» from anywhere on the Internet, and I receive my SSH service. If I run that same command from within the 10.1.10.0/24 network just inside the router, the connection will time out.

The Comcast router is set up to do port forwarding to the SSH machine on the standard port.

  • The comcast router answers pings, both on the internal and external IPs.
  • The box running sshd answers pings

The device is a piece of junk SMC Networks SMCD3G.

Performing a wireshark on the sshd machine, while attempting to ssh 10.1.10.201 gives normal looking traffic. Attempting an ssh a.b.c.d gives the following:

Source       Destination  Info
10.1.10.11   10.1.10.201  39946 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201  10.1.10.11   ssh > 39946 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0
10.1.10.11   10.1.10.201  39946 > ssh [RST] Seq=1 Win=0 Len=0

10.1.10.11     10.1.10.201  39946 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201  10.1.10.11   [TCP Previous segment lost] ssh > 39946 [SYN, ACK] Seq=46941561
10.1.10.11   10.1.10.201  39946 > ssh [RST] Seq=1 Win=0 Len=0

(the last three lines repeat)

The packets seem to be getting there, but the connecting machine is sending a RST. Why?

From the client's side (the machine running SSH) a later attempt looked like:

Source       Destination  Info
10.1.10.11   a.b.c.d      40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201  10.1.10.11   ssh > 40212 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460
10.1.10.11   10.1.10.201  40212 > ssh [RST] Seq=1 Win=0 Len=0

10.1.10.11   a.b.c.d      [TCP Retransmission] 40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201  10.1.10.11   [TCP Previous segment not captured] ssh > 40212 [SYN, ACK] Seq=15635206
10.1.10.11   10.1.10.201  40212 > ssh [RST] Seq=1 Win=0 Len = 0

(the last three lines repeat)

The only thing that stands out is that I'm continually getting "Previous segment not captured" (it wasn't? Seems to be right there), and that the sequence numbers from the client are really deterministic. (Aren't they supposed to start at a random point, and increment from there?)

2
  • You need to enable something called "NAT loopback/reflection" to be able to use the public ip on the LAN-side. I don't know if your modem supports it (and if it's visible in the webinterface of the modem)
    – Rik
    Oct 9, 2013 at 20:35
  • 1
    Is there any time when not having "NAT loopback" would be the desired behavior? To me, it seems like "NAT loopback enabled" means "it works", and "not NAT loopback capable" means "it's a piece of junk". (And, judging by the posts that term turns up, it looks like my device really is a piece of junk.)
    – Thanatos
    Oct 9, 2013 at 20:52

3 Answers 3

3

Like i said in my comment. To be able to use your public ip within you LAN you'll need something called NAT Loopback also known as NAT hairpinning or NAT reflection.

You can read about it here

As far as i can find on the internet your piece of ... uuuh... "SMC Networks SMCD3G" does not support "NAT Loopback".

You have two options:

  1. You can add a line 10.1.10.201 fake_or_real_hostname in your hosts file.
    You can connect like ssh me@fake_or_real_hostname.

  2. You can run your own local DNS server. Here is some explanation.

I solved the same problem you are having by running my own local DNS server that recurses to OpenDNS for non-local domains, and creating zones with local DNS A and PTR records that resolve my external hostname to the LAN IP of that host.


In both cases it is best to use a hostname instead of an ip. You could use a dynamic hostname service to get a hostname (like myname.dyndns.org) if your public ip changes a lot. It is also easier to remember. And in case you go for option 1 you can add this name in your hosts-file.

Some of these are:
DynDNS
FreeDNS
ZoneEdit
No-Ip

My modem has the option to automatically register ip changes with these services. There are also desktop-utilities who can update it when you public ip changes.

2
  • I have a hostname, which is part of the whole problem. ssh my_hostname will cause ssh to (rightfully) resolve the hostname, which of course resolves to my external IP. (That is what the OpenDNS suggestion appears to suggest — manually overriding hostnames known to point into the network to the in-network IPs.)
    – Thanatos
    Oct 9, 2013 at 21:15
  • Yep. and you can do it simple by adding that line in all the hosts-files on all computers or setting up a local DNS-server.
    – Rik
    Oct 9, 2013 at 21:18
0

What you want is sometimes called router hairpinning

Whether your router supports this, what it is called, and how configured, depends on router make and model (which information isn't currently in your question)


Another solution to the same problem is to use split-horizon DNS and refer to the server by name. However this isn't easy to set up if you are currently relying on a typical SOHO router to do all your DHCP+DNS.

0

To add to Rik's answer: my particular is at fault here: it is only partially doing the correct thing, and in the end, is messing up NAT.

10.1.10.11   a.b.c.d      40212 > ssh [SYN] Seq=0 Win=14600 Len=0 MSS=1460
10.1.10.201  10.1.10.11   ssh > 40212 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460
10.1.10.11   10.1.10.201  40212 > ssh [RST] Seq=1 Win=0 Len=0

Note carefully the connections here. First, we see a SYN (expected) from 10.1.10.11 (the ssh client, this is normal) to a.b.c.d (also normal). The server, however, receives this as 10.1.10.11 → 10.1.10.201. The destination IP has been replaced by the router, NAT fashion, correct. The source IP, however, did not get replaced. Here, we should have the connection (10.1.10.201 & a.b.c.d) but instead, we have (10.1.10.201 & 10.1.10.11). The router has only done half the required job.

The connection, to the server, is (10.1.10.201 & 10.1.10.11). To the client, it's (10.1.10.201 & a.b.c.d)¹. When the client gets the SYN/ACK for the (10.1.10.201 & 10.1.10.11), the OS (rightfully) sends a RST — it has no knowledge of that connection.

¹Note that the port numbers do matter in determining connections, but for simplicity I've left them out.

Not the answer you're looking for? Browse other questions tagged .