ssh远程端口转发

目录

说明

格式

参数说明

实例

实例1

实例2

ssh个人配置

config配置含义


说明

远程转发指的是在远程 SSH 服务器建立的转发规则。

它跟本地转发正好反过来。建立本地计算机到远程计算机的 SSH 隧道以后,本地转发是通过本地计算机访问远程计算机,而远程转发则是通过远程计算机访问本地计算机。比较常见的例子就是内网穿透。

格式

它的命令格式如下:

$ ssh -R 远程主机端口:目标主机地址:目标主机端口 -N [远程主机用户名@]远程主机地址 [-p 远程主机SSH端口]

参数说明

参数 含义
-C 允许压缩数据
-f 后台执行ssh指令
-N 不执行远程指令,用于转发端口
-g 允许远端主机连接本地转发的端口
-p 指定远程主机的端口,如果为默认端口,则可以省略

注意上面的参数除了-p需要跟参数外其他的可以组合使用,使用一个-,但是主要组合时要放到转发类型参数的签名,并且不能和转发类型组合使用

ssh -g -L lport:remoteAddr:remotePort 等价于 ssh -L 0.0.0.0:lport:remoteAddr:remotePort

转发类型:

参数 含义
-L 正向代理,将本地机(客户机)的某个端口转发到远端指定机器的指定端口
-R 反向代理,远程端口转发,将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口
-D socks5代理(-D):相当于 ss/ssr

其中 [远程主机用户名@] 中如果远程主机用户名跟当前操作的用户名一致可以省略,如都是ubuntu,则只需要写后面的远程主机地址就可以

实例

远程转发主要针对内网的情况。下面举两个例子。

实例1

ssh远程端口转发_第1张图片

服务器 服务 说明
服务器A(192.168.1.245)【隧道建立者】 localhost:8800 内网,外网不可直接访问
服务器B(124.42.8.133)【提供对外访问地址】 124.42.8.133:8899 外网,外网可直接访问
主机C【访问者】 - 外网,想访问服务器A的服务

现在有一台内网服务器A(不可用访问互联网),在 8800 端口启动了一个web服务,现在想把这个服务通过公网映射出去,映射到具有公网 IP 地址的服务器B(124.42.8.133)的 8899端口,使得访问124.42.8.133:8899这个地址,就可以访问到内网服务器A的8800端口。

服务器A上执行以下命令,回车后会要求输入服务器B(124.42.8.133)的ubuntu账号的密码:

# 以下命令在服务器A上执行
$ ssh -R 远程服务器B访问端口:目标服务器A地址:目标服务器A端口 -N 用户名@远程服务器C地址 -p 远程服务器Cssh端口
ssh -fN -R 8899:localhost:8800 [email protected] -p 22022

说明:

1、如果远程服务器跟本地服务器用户名相同都是ubuntu,则ubuntu@可以不写,即:

ssh -fN -R 8899:localhost:8800 124.42.8.133 -p 22022

2、-p参数后面跟的是124.42.8.133的ssh端口,如果是默认的22则-p和后面的参数可以不写,即:

ssh -fN -R 8899:localhost:8800 124.42.8.133

输入密码后就可以在124.42.8.133上访问了

curl 127.0.0.1:8899

可以看到返回了我们服务器A上8800服务的内容。

上面命令是在内网服务器A上执行,建立从服务器A到124.42.8.133的 SSH 隧道。运行以后,用户访问124.42.8.133:8899,就会自动映射到localhost:8800

问题

到这还没有结束,假设有一台能访问服务器B的机器C,在机器C上测试一下这个服务,很可能会发现服务124.42.8.133:8899并不能正常访问。

这又是为什么呢?服务器B上我们明确是可以访问到的。这是因为在SSH服务的配置文件/etc/ssh/sshd_config中有这样一个配置,当然也可能没有,因为它的默认值是no

GatewayPorts no

GatewayPorts 是否允许远程主机连接本地的转发端口,默认值为 no。注意:这个设置需要在端口转发的机器上修改,这里是远程服务器B,改服务器A是没有作用的。

GatewayPorts yes

将此项配置为yes并重启SSH服务后,再次执行命令

~$ sudo service ssh restart

这样再启动,服务器C就可以访问124.42.8.133:8899了,其他能访问服务器B,并且没有被防火墙拦截的机器也都可以访问该服务。

实例2

ssh远程端口转发_第2张图片

服务器 服务 说明
服务器A(124.42.8.133)【提供对外访问地址】 124.42.8.133:8899 外网,外网可直接访问
SSH 跳板机B(192.168.1.251)【隧道建立者】 ssh隧道 内网,外网不可直接访问,可连通A、C服务器
目标服务器C(192.168.1.245)【提供对外访问地址】 192.168.1.245:8800 内网,外网不可直接访问,最终服务提供者
机器D【访问者】 - 外网,访问服务器A

服务器A(124.42.8.133)在外网,SSH 跳板机B(192.168.1.251)目标服务器C(192.168.1.245)都在内网,必须通过 SSH 跳板机B才能访问目标服务器C(192.168.1.245)。但是,服务器A无法访问内网之中的 SSH 跳板机B,但是 SSH 跳板机可以访问服务器A。

由于服务器A无法访问内网 SSH 跳板机B,就无法从外网发起 SSH 隧道,建立端口转发。必须反过来,从 SSH 跳板机B发起隧道,建立端口转发,这时就形成了远程端口转发。跳板机执行下面的命令,绑定服务器A8899端口,去访问192.168.1.245:8800

跳板机B上执行以下命令,回车后会要求输入服务器A(124.42.8.133)的ubuntu账号的密码:

# 以下命令在跳板机B上执行
$ ssh -R 远程服务器A访问端口:目标服务器C地址:目标服务器C端口 -N 用户名@远程服务器A地址 -p 远程服务器Assh端口
$ ssh -R 8899:192.168.1.245:8800 -N [email protected] -p 22022

上面命令是在 SSH 跳板机B(192.168.1.251)上执行的,建立跳板机B(192.168.1.251)服务器A(192.168.1.245)的隧道,并且这条隧道的出口映射到目标服务器C``192.168.1.245:8800

显然,远程转发要求服务器A(124.42.8.133)也安装了 SSH 服务器,这样才能接受 SSH 跳板机B(192.168.1.251)的远程登录。

执行上面的命令以后,SSH 跳板机B(192.168.1.251)服务器A(124.42.8.133)的隧道已经建立了。然后,就可以从服务器A(124.42.8.133)访问目标服务器C(192.168.1.245)了,在服务器A(124.42.8.133)上执行下面的命令。

$ curl 124.42.8.133:8899

本机执行上面的命令以后,就会输出服务器目标服务器C(192.168.1.245)8800 端口返回的内容。

ssh个人配置

如果经常执行远程端口转发,可以将设置写入 SSH 客户端的用户个人配置文件(~/.ssh/config)。

Host 主机别名
    HostName 远程服务器地址
    Port 远程服务器ssh端口
    User 远程服务器用户名
    RemoteForward 远程服务器转发端口 目标主机地址:目标主机端口
Host 133
    HostName 124.42.8.133
    Port 22022
    User ubuntu
    RemoteForward 8899 localhost:8800

config配置含义

  • Host 服务器别名,只要是合法的变量名称且不重复即可,可任意指定,ssh命令通过该名称来连接到指定服务器,比如上面的 ssh hostA / ssh hostB

  • Hostname 服务器地址,可以是域名,也可以是ip地址。

  • Port 端口号,默认为22,只有修改了ssh连接的默认端口才需要配置此参数

  • User ssh的登陆用户名

  • IdentityFile ssh 私钥文件的地址(不带.pub后缀的文件)

  • RemoteForward

    远程转发配置

  • LocalForward

    本地转发配置

  • DynamicForward

    动态转发SOCKS配置

参考文件 How To Configure Custom Connection Options for your SSH Client | DigitalOcean

完成上面的设置后,执行下面的命令就会建立远程转发。

$ ssh -N 133(主机别名) #后台执行可以加上-f   ssh -N remote-forward

# 等同于
$ ssh -R 远程服务器转发端口:目标服务器地址:目标服务器端口 -N [email protected] -p 远程服务器ssh端口  

这样就不用重复输入配置参数,减少出错。

当然除了ssh端口转发这种方法,我们还可以使用其他技术手段来实现转发端口,比如Nginx

你可能感兴趣的:(ssh,服务器,ssh,ubuntu)