有一台设备,开启了ssh server,但是它位于NAT之后,从外面是没办法直接ssh登录的。但是使用ssh的
反向代理功能、以及一台公网服务器,可以实现ssh登入。
拓扑如下:
device A <------> NAT <------> Public server < ----------- > Client
设备A,它在NAT之后,是要登录的设备。
Public server,公网服务器,有公网ip。
Client 是要登录到device A的设备,可以是PC,手机等,client也可能在NAT之后。
第一步:在device A上执行ssh -R 连接到 Public server
$ sudo ssh -fN -R :7010:localhost:22 root@insidelinuxdev.net
设备A在NAT之后,但它是可以主动发起连接到公网服务器的。上述命令就是建立了设备A和公网服务器的
连接。然后在公网服务器的一个端口监听请求,对于新接入的连接,将其forward到device A的一个端口。
-R [bind_address:]port:host:hostport
bind_address,是公网服务器上监听的ip。默认为127.0.0.1,如果为空或者*,则绑定到所有接口。
port,是公网服务器上要监听的端口。
host,是device A上的接口,外面的请求将转发到这个接口
通常localhost即可。因为ssh服务器也监听localhost。
hostport,是device A上的端口,外面的请求将转发到这个端口,ssh服务器的端口是22,所以这里指定22。
在服务器上查看监听端口信息:
# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 577/apache2
tcp 0 0 0.0.0.0:7010 0.0.0.0:* LISTEN 26310/sshd: root
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 577/apache2
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 388/systemd-resolve
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 26309/sshd
可以看到服务器已经监听了7010端口。
注意服务器上的sshd配置/etc/ssh/sshd_config需要打开GatewayPorts yes
否则,服务器sshd不允许指定bind_address。而我们这种场景需要指定bind_address,
否则bind_address为127.0.0.1,那client是没办法接入的。
第二步:在Client上发起ssh连接即可
$ ssh -p 7020 yuan@insidelinuxdev.net
注意,这里的用户,显然是device A上的用户,因为公网服务器只是负责打通tcp通道而已。
-R 说明:
-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port
Specifies that connections to the given TCP port or Unix socket on the re‐
mote (server) host are to be forwarded to the local side.
This works by allocating a socket to listen to either a TCP port or to a
Unix socket on the remote side. Whenever a connection is made to this port
or Unix socket, the connection is forwarded over the secure channel, and a
connection is made from the local machine to either an explicit destination
specified by host port hostport, or local_socket, or, if no explicit desti‐
nation was specified, ssh will act as a SOCKS 4/5 proxy and forward connec‐
tions to the destinations requested by the remote SOCKS client.
Port forwardings can also be specified in the configuration file. Privi‐
leged ports can be forwarded only when logging in as root on the remote ma‐
chine. IPv6 addresses can be specified by enclosing the address in square
brackets.
By default, TCP listening sockets on the server will be bound to the loop‐
back 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 port argument is ‘0’, the listen port will be dynamically allocated
on the server and reported to the client at run time. When used together
with -O forward the allocated port will be printed to the standard output.
参考
man ssh
https://jfrog.com/connect/post/reverse-ssh-tunneling-from-start-to-end