在这之前要检查下端口转发功能是否已开启,必须要配置/etc/ssh/sshd_config,文件中允许端口转发,重启ssh
AllowTcpForwarding yes
1、本地端口转发
场景如下:
ssh client与ssh server的概念,本文章以此种概念为准
- ssh client 执行命令的一方,无论是本地端口转发还是远程端口转发,执行命令的机器为ssh client
- ssh server 执行命令需要登录的另一方
注:有些文章会是另外一种理解,如下:
- ssh client(启动一个端口等待连接的一方)
- ssh server(使用ssh client通过隧道发送过来的数据就进行转发的一方)
对于本地端口转发来说,ssh client与ssh server分别如下:
需求是想从客户端直接传送东西至内部服务器,在采集机上配置端口转发,采集机为ssh client,堡垒机为ssh server
命令格式为:ssh –g -L <local port>:<remote host>:<remote port> <SSH Server>
ssh client上执行命令,即在采集上(172.16.13.16)执行如下命令
ssh -g –L 1234:192.168.3.16:22 root@172.16.12.150
这时候采集机上就启动了1234端口,作为ssh client接收数据,然后把数据通过ssh协议传输到ssh server,sshserver再转发数据到内部服务器的22端口
这时候连接采集机(172.16.13.16)的1234端口,就相当于连接了192.168.3.16的22端口,如下为以上两个参数的解释
-L 本地端口 -g 允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接
2、远程端口转发
本地端口转发和远程端口转发的区别为
- 本地端口转发是在执行命令的机器,即ssh client启动端口监听,数据的走向是ssh clinet->ssh server->转发到对应设备
- 远程端口转发是在执行命令机器的对端机器,即ssh server上启动端口监听,数据的走向是ssh server->ssh client->转发到对应设备
命令格式为:ssh -R <local port>:<remote host>:<remote port> <SSH Server>
local port为ssh server上启动的端口
remote host和 remote port 为需要ssh client转发的设备和端口
使用的场景如下:
- A机器属于我方网络内设备,所属的网络的防火墙做了NAT后,提供公网地址(111.12.12.12)让外部ssh访问
- B机器属于对方网络,能够ssh登录,能够ssh访问到A机器,反过来A机器是不能够通B机器的
B机器上部署了数据库,现在想在本人电脑的客户端直接能够使用客户端访问到B机器上的数据库服务,因为对方的网络是不能操作的,所以无法说做一个nat映射提供公网地址进行访问
这时候,我们就要使用远程端口转发功能了,如下操作
B机器作为ssh client,在上面执行如下命令
ssh -g -R 1234:127.0.0.1:3306 root@111.12.12.12
这时候A机器上就启动了1234端口,作为ssh server接收数据,然后把数据通过ssh协议传输到ssh client,ssh client再转发数据到B机器本身的数据库服务3306端口
这时候我们发现,其实A机器的1234端口,除了A机器本身能访问,其他设备是无法访问的,就是-g参数是不生效的。
所以这里需要再做一个本地转发,如下
ssh -g -L 1235:127.0.0.1:1234 root@127.0.0.1
本地转发启动1235端口,数据流为:1235端口接收到数据->把数据转发到1234端口上->转发到远程服务器(ssh server)上->ssh server再转
此时,就可以通过连接A设备的1235端口达到访问数据库的目的。
注:使用远程端口转发,有时候会出现远程端口会消失的情况,并不像本地端口那样稳定。
3、动态端口转发
上面的本地端口转发和远程端口转发都要求有一个固定的远程主机和端口,那如果没有这个主机和端口号呢?这就需要用到我们的动态端口转发来实现
ssh -D <local port> <SSH Server>
-D port
指定一个本地机器 “动态的’’ 应用程序端口转发. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去。 目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发.
模拟一个场景:
A机器可以访问B机器的ssh端口
B机器可以访问C机器
A机器完全不通C机器
如下图:
需求:从A机器使用浏览器直接访问C机器的任意应用
3.1、模拟A机器完全访问不到C机器
在C机器的iptables做策略,完全禁止A机器的访问,加入如下策略
-A INPUT -s 192.168.2.150 -j REJECT |
重启C机器的iptables使其生效
在A机器执行如下命令测试:
curl http://192.168.2.241:8080 |
如下图:策略生效
3.2、设置动态端口转发
在A机器执行如下命令
ssh -D 1234 root@192.168.2.151
查看A机器上,已经启动了1234端口进行监听
3.3、在A机器访问C机器上的应用
A机器命令终端可以如下命令测试:
curl --socks5 127.0.0.1:1234 http://192.168.2.241:8080
能够返回数据,代表从A机器直接访问C机器成功
原理:当用A机器访问C机器上的应用时,本机的1234端口做为代理服务器(ssh client),访问请求被转发到B机器(sshserver)上,由sshserver替之访问C机器上的应用
可在C机器使用tcpdump抓包来判断源IP是否为B机器
tcpdump port 8080
在A机器使用curl命令后,抓取包如下,源IP地址为B机器
[root@TAPP01 sysconfig]# tcpdump port 8080 22:45:36.720471 IP 192.168.2.151.47741 > TAPP01.webcache: Flags [S], seq 2062243485, win 14600, options [mss 1460,sackOK,TS val 434850441 ecr 0,nop,wscale 7], length 0 省略…………………. |
A机器与B机器的通讯通过ssh协议,可在B机器抓包分析A机器过来的包的情况
tcpdump src 192.168.2.150
在A机器使用curl命令后,抓取包如下,可知A机器与B机器是通过ssh协议通讯
[root@report-server-backup ~]# tcpdump src 192.168.2.150 22:53:43.622494 IP 192.168.2.150.59514 > 192.168.2.151.ssh: Flags [P.], seq 2688161549:2688161649, ack 2351494896, win 290, options [nop,nop,TS val 5330431 ecr 435312270], length 100 |
以上,同时也可分析出A机器通过socket端口1234接收到数据后,启动另外一个端口与B机器进行ssh连接,B机器收到A机器的访问请求,再启动一个端口访问C机器的web服务
4、其他
上面的本地端口转发,执行命令的时候要求登录ssh server,登录成功后,本地会启动一个端口进行监听,此时,如果登录ssh server的终端断开,监听的端口也会关闭
现在场景要开放一个端口,保持长时间的连接,同时作为ssh client和 ssh server,把数据转发到远端机器,如下命令
ssh -C -f -N -g patrol@127.0.0.1 -L 8080:163.163.163.163:143
参数释义:
-f 后台认证用户/密码,通常和-N连用,不用登录到远程主机
-N 不执行脚本或命令,通常与-f连用
-C Enable compression,压缩数据传输。