SSH隧道的使用

SSH隧道的使用

1. 什么是SSH隧道?

SH 隧道是 SSH 中的一种机制,它能够将其他 TCP 端口的网络数据通过 SSH 连接来转发,并且自动提供了相应的加密及解密服务。因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输,因此这一过程也被叫做“隧道”(tunneling)。

2. 适用场景

·客户那边不给开放除了ssh外的其他端口,又想本地访问测试

·有些对接内部的接口,外部不给访问,那么你本地就没法调试

·某些DB端口只开放给app server访问,又想在本地进行数据查询等

2.1 本地端口转发

图片如何上图,客户服务器只开放ssh登录,不给开其他端口,此时我们想本地访问测试就可以使用ssh隧道方案(前提是服务器没禁用ssh代理)。

1.192.168.31.31上启动一个node-exporter服务做测试

图片

2.开启防火墙,只允许我PC访问ssh端口

$ systemctl start firewalld

$ firewall-cmd –permanent –add-rich-rule=’
rule family=”ipv4”
source address=”192.168.31.188/32”
port protocol=”tcp” port=”65522” accept’

$ firewall-cmd –reload
$ firewall-cmd –list-rich-rules
rule family=”ipv4” source address=”192.168.31.188/32” port port=”65522” protocol=”tcp” accept

3.PC机访问测试

# 测试ssh端口
$ telnet 192.168.31.31 65522

# 测试9100端口
$ telnet 192.168.31.31 9100

图片

4.启动隧道服务(在本地需要访问的机器上执行,我这里是我的PC)

语法:

ssh -L 本地端口:localhost:服务器目标端口 用户名@服务器IP

如果是非标准端口,添加-p参数:

ssh -p 服务器SSH端口 -L 本地端口:localhost:服务器目标端口 用户名@服务器IP

所以我这里是:

ssh -p 65522 -L 8888:localhost:9100 root@192.168.31.31

图片

5.访问测试

保持 SSH 连接终端不要关闭,在本地浏览器或工具中访问:http://localhost:8888 这个请求会通过 SSH 隧道转发到服务器的 9100 端口。

图片

图片

2.2 通过第三台机绕过火墙限制

图片如上图所示,我们想要在Server A与Server B之间创建隧道,最终通过隧道访问到Server C中的 http 服务。

1.server C启动一个http服务(python2 python3有些不一样)

# python2
$ python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 …

# python3
$ python3 -m http.server 8888
Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) …

2.server C开启火墙仅允许192.168.31.79访问8888端口

$ systemctl start firewalld

$ firewall-cmd –permanent –add-rich-rule=’ \
rule family=”ipv4” \
source address=”192.168.31.79/32” \
port protocol=”tcp” port=”8888” accept’

$ firewall-cmd –reload
$ firewall-cmd –list-rich-rules
rule family=”ipv4” source address=”192.168.31.79/32” port port=”8888” protocol=”tcp” accept

3.测试访问

server B: 192.168.31.79

-

-

-

-

-

-

-

-

1
$ curl http://192.168.31.89:8888<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Directory listing for /</title></head><body><h1>Directory listing for /</h1><hr><ul><li><a href="docker-compose.yaml">docker-compose.yaml</a></li></ul><hr></body></html>    

server A: 192.168.31.188

图片

4.server A 上执行下面的命令开启隧道

ssh -N -L 18888:192.168.31.89:8888 root@192.168.31.79

图片

需要输入server B的ssh root密码,注意不要关闭这个窗口。

5.server A上访问测试,访问本机的18888端口即可访问到server C上的http服务

图片

2.4 通过跳板机建立 SSH 隧道访问db服务

图片如上图我们想要创建一个 SSH 隧道,让只能从App Server访问的Mysql DB Server的端口3306在本地也能访问。通过下面的命令,使用 appusr 用户名连接到 appserver 主机,并通过跳板机 jump server连接到 dbserver 主机,将本地端口 13306映射到远程主机的端口3306,这样就能访问DB server的3306了:

ssh -v -N appuser@appserver -J jumpuser@jumphost -L 13306:dbserver:13306

-v:表示启用详细模式,输出详细的连接信息,这对于调试很有用,并且不返回App server的 shell 提示符

-N:表示禁用远程命令执行,只连接到远程主机,不执行任何命令,只做转发端口。

appuser@appserver:表示要连接的远程主机App server的用户名和主机名或者IP。

-J:表示使用代理命令连接到跳板机Jump Server。

jumpuser@jumphost:jumpuser 是连接跳板机的用户名,jumphost 是跳板机的主机名或者IP。

-L :local,表示使用本地端口转发创建 ssh 隧道。

13306:dbserver:3306:表示将本地端口13306 映射到远程主机DB server的端口 3306。dbserver 是远程主机的主机名或者IP

1.DB server上创建一个测试用户,仅允许App server(192.168.31.79)访问

图片

2.在App server和其他机器(我这里是本机PC)上测试连接状态

192.168.31.79连接成功:

图片

我的PC机连接失败:

图片

3.在PC机上启动SSH隧道:通过192.168.31.96跳板机和仅允许连接的app server(192.168.31.79)连接db,将本地端口 13306映射到远程主机的端口3306

ssh -N root@192.168.31.79 -J root@192.168.31.96 -L 13306:192.168.31.89:3306

这里会让你输入跳板机和app server的ssh用户密码,输入后回车就行:

图片

4.测试连接,用localhost:13306就可以远程连接到DB server的3306了

图片

3. 其他

1.如果希望隧道在后台运行,可以加上 -fN 参数

# 22端口
ssh -fN -L 8888:localhost:9100 user@your_server_ip

# 非标准端口
ssh -fN -p 2222 -L 8888:localhost:9100 user@your_server_ip

-f:后台运行

-N:不执行远程命令,仅作端口转发

2.禁用ssh代理, 在sshd_config中添加下面的配置

# 禁用X11转发(如果不需要图形界面转发)
X11Forwarding no

# 禁用SSH代理转发
AllowAgentForwarding no

# 禁用TCP端口转发(包括本地和远程端口转发)
AllowTcpForwarding no

# 禁用动态端口转发(SOCKS代理)
AllowStreamLocalForwarding no

# 禁用网关端口(禁止远程主机连接转发的端口)
GatewayPorts no

如果要对某些用户开启,可以按照下面的配置:

# 禁用所有用户的端口转发(作为默认设置)
AllowTcpForwarding no
GatewayPorts no

# 对普通用户禁用,对admin用户允许
Match User admin
AllowTcpForwarding yes
GatewayPorts yes

如果要仅允许某些IP使用ssh代理,可以参考下面的配置:

# 禁用所有用户的端口转发(作为默认设置)
AllowTcpForwarding no
GatewayPorts no

# 针对特定IP地址允许端口转发
Match Address 192.168.31.79,192.168.31.80
AllowTcpForwarding yes
GatewayPorts yes

如果需要同时指定用户和IP,可以参考下面的配置:

# 禁用所有用户的端口转发(作为默认设置)
AllowTcpForwarding no
GatewayPorts no

# 针对特定IP地址和用户允许端口转发
Match User username Address 192.168.31.79
AllowTcpForwarding yes
GatewayPorts yes

禁用之后的效果:

图片

图片

3.如果希望监听本地所有IP,可以用如下的命令代替

ssh -g -N -L 8888:192.168.31.31:9100 root@192.168.31.31

使用”-g”选项可以开启”网关功能”

图片

图片

这样localhost能访问,使用本机的IP也能访问:

图片

图片

https://mp.weixin.qq.com/s/YU9gRGWra4-sENaBuKUMtQ?scene=1