I want to access a Raspberry Pi Zero W on the local network via NAT traversal. I was following this tutorial (in Chinese), but am having the issue described below.

The idea is to forward the SSH port on the local Raspberry Pi to remote machine with a public IP, and then access the Pi from there. For security reasons, I have replaced the real values with nalzok@remote-ip.

On Raspberry Pi (access from the local network)

pi@nalzoks-pi:~ $ autossh -M 30000 -o "StrictHostKeyChecking=false" -o "ServerAliveInterval 10" -o "ServerAliveCountMax 3" -NR 20000:localhost:22 nalzok@remote-ip

On remote server

I have no issue logging to the Pi from the remote server

nalzok@iZuf68c45z6sk19lln4zvsZ:~$ ssh -p20000 pi@localhost
Linux nalzoks-pi 4.19.66+ #1253 Thu Aug 15 11:37:30 BST 2019 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Sep  8 10:12:30 2019 from ::1
pi@nalzoks-pi:~ $

On my computer (outside of the local network)

However, I cannot access it directly from my computer.

$ ssh -p20000 pi@remote-ip
ssh: connect to host remote-ip port 20000: Connection refused

On remote server

I'm pretty sure the firewall is opened for both port 20000 and 30000 on the remote server. When trying to troubleshot myself, I realized that these ports are only available for local access.

nalzok@iZuf68c45z6sk19lln4zvsZ:~$ sudo lsof -i -P -n | grep LISTEN
[sudo] password for nalzok:
sshd        601    root    3u  IPv4  13223      0t0  TCP *:22 (LISTEN)
sshd      12503    root    8u  IPv4 879255      0t0  TCP (LISTEN)
sshd      13026  nalzok    9u  IPv4 885817      0t0  TCP (LISTEN)
sshd      13026  nalzok   10u  IPv4 885818      0t0  TCP (LISTEN)

How do I open the port 20000 for public access?


This remote forwarding behavior is explicitly documented in the the SSH man page:

By default, TCP listening sockets on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)).

If the GatewayPorts option is enabled on the server, you'd specify the remote forward like this to take advantage of it:

-R *:20000:localhost:22
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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