SSH端口转发

时间:2022-07-22
本文章向大家介绍SSH端口转发,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

端口转发概述:

让我们先来了解一下端口转发的概念吧。我们知道,SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据。但是,SSH 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling),这是因为 SSH 为其他 TCP 链接提供了一个安全的通道来进行传输而得名。例如,Telnet,SMTP,LDAP 这些 TCP 应用均能够从中得益,避免了用户名,密码以及隐私信息的明文传输。而与此同时,如果您工作环境中的防火墙限制了一些网络端口的使用,但是允许 SSH 的连接,那么也是能够通过将 TCP 端口转发来使用 SSH 进行通讯。总的来说 SSH 端口转发能够提供两大功能:

  1. 加密 SSH Client 端至 SSH Server 端之间的通讯数据。
  2. 突破防火墙的限制完成一些之前无法建立的 TCP 连接。

端口转发方式:

共有三种方式,分别为本地转发,远程转发,动态转发

1:本地端口转发

原理:

将本地机(客户机)的某个端口转发到远端指定机器的指定端口. 工作原理是这样的, 本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转发出去, 同时远程主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有 root 才能转发特权端口。

命令:-L localport:remotehost:remotehostport sshserver

说明:localport       本机开启的端口号

      remotehost      最终连接机器的IP地址

      remotehostport        转发机器的端口号

      sshserver       转发机器的IP地址

选项:-f 后台启用

      -N 不打开远程shell,处于等待状态(不加-N则直接登录进去)

    接下来,我们通过实验来详细的说明一下如何实现本地转发:

实验:

三台机器:c5服务器,c6跳板机,c7客户机

c5服务器只允许telnet连接(23端口)访问,不允许外部直接访问,c6服务器是一个ssh服务器;有一个用户c7需要从外部连接到内部的c5服务器。

c5防火墙允许22端口进来(或者企业内部有一个堡垒机,ssh -t通过堡垒机进去)。

c7用户通过ssh协议连接到c6机器上,再通过c6机器做跳板,连接至c5服务器。

实验步骤:

1)模拟c5不允许c7连接,并且开启c6机器的telnet服务端口23。

c5安装 telnet-server并开启:

[root@centos5 Server]# rpm -ivh telnet-server-0.17-39.el5.i386.rpm 
warning: telnet-server-0.17-39.el5.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
error: failed to stat /media/RHEL_5.4 i386 DVD: 没有那个文件或目录
Preparing...                ########################################### [100%]
   1:telnet-server          ########################################### [100%]
[root@centos5 Server]# chkconfig xinetd on
[root@centos5 Server]# chkconfig telnet on
[root@centos5 Server]# service xinetd start
启动 xinetd:
[root@centos5 Server]# ss -ntl | grep 23
0      0                              *:23                            *:*     

在c5上输入以下口令:

[root@centos5 Server]# iptables -F
[root@centos5 Server]# iptables -A INPUT -s 172.18.251.152 -p tcp --dport 23 -j ACCEPT
[root@centos5 Server]# iptables -A INPUT -p tcp --dport 23 -j REJECT

在c5上的23端口只允许c6进行访问,其他任何机器都拒绝

iptables -L可以看到详细信息

[root@centos5 ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  172.18.251.152       anywhere            tcp dpt:telnet 
REJECT     tcp  --  anywhere             anywhere            tcp dpt:telnet reject-with icmp-port-unreachable 

c6,c7安装telnet客户端并开启23端口

c6

[root@centos6 ~]# ss -ntl | grep 23
LISTEN     0      64                       :::23                      :::*     
[root@centos6 ~]# 

c7

[root@centos7 ~]# ps -ef | grep xinetd  
root      6641     1  0 23:22 ?        00:00:00 /usr/sbin/xinetd -stayalive -pidfile /var/run/xinetd.pid  
root      6644  5817  0 23:24 pts/3    00:00:00 grep --color=auto xinetd  

验证:

c6可以通过telnet进行连接c5的23端口

[root@centos6 ~]# telnet c5
Trying 172.18.253.91...
Connected to c5.
Escape character is '^]'.
login: liubei
Password: 
Last login: Thu Aug 23 06:34:51 from 172.18.251.152
[liubei@centos5 ~]$ exit

c7不能通过telnet进行连接c5的23端口

[root@centos7 ~]# telnet c5
Trying 172.18.253.91...
telnet: connect to address 172.18.253.91: Connection refused
[root@centos7 ~]# 

2)开启端口转发(telnet隧道)

首先,我们在c7机器上确认已经开启的端口有哪些:

[root@centos7 ~]# ss -ntl 
State      Recv-Q Send-Q             Local Address:Port                            Peer Address:Port              
LISTEN     0      128                            *:111                                        *:*                  
LISTEN     0      5                  192.168.122.1:53                                         *:*                  
LISTEN     0      128                            *:22                                         *:*                  
LISTEN     0      128                    127.0.0.1:631                                        *:*                  
LISTEN     0      100                    127.0.0.1:25                                         *:*                  
LISTEN     0      128                    127.0.0.1:6010                                       *:*                  
LISTEN     0      128                           :::111                                       :::*        

我们使用的端口是9527端口,从上图中我么已经看出,9527端口没有被占用,所以我们可以使用~

接着我们建立本地转发的隧道(c7上输入以下命令):

ssh -L 9527:c6:23 -Nf c6
The authenticity of host 'c6 (172.18.251.152)' can't be established.
RSA key fingerprint is SHA256:TkCkQl0OlK0u0ojODTZnoDB9sADxNF2sQnQxb2fzQII.
RSA key fingerprint is MD5:d3:62:38:db:bc:99:45:7a:59:7a:87:8d:78:b0:f5:e6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'c6' (RSA) to the list of known hosts.
root@c6's password: 
[root@centos7 ~]#                     #(成功建立隧道,在后台运行)

    -L 启动本地端口转发     -N 不启用shell     -f 后台,不用登陆到本机

在这里,我们可以通过ss -nt查看接口连接情况:

[root@centos7 ~]# ss -nt
State      Recv-Q Send-Q             Local Address:Port                            Peer Address:Port              
ESTAB      0      52                172.18.254.130:22                            172.18.253.114:64271              
ESTAB      0      0                 172.18.254.130:40346  (c7 通过ssh 连接上了c6的22端口)          72.18.251.152:22                 
[root@centos6 ~]# ss -nt
State       Recv-Q Send-Q                  Local Address:Port                    Peer Address:Port 
ESTAB       0      0                      172.18.251.152:22                    172.18.254.130:40346 
ESTAB       0      0                      172.18.251.152:22   c6 c7 已建立连接                 172.18.253.114:50715 
[root@centos6 ~]# 

3)在c7上输入以下命令,用9527端口连接c5:

[root@centos7 ~]# telnet 127.0.0.1 9527
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
Kernel 2.6.18-164.el5 on an i686
login: liubei
Password: 
[liubei@centos5 ~]$ hostname
centos5
[liubei@centos5 ~]$ exit

至此,我们已经实现了c7外部远程连接c5的需求,接下来我们就来讲一讲实现过程:

当c7连接自己的9527端口时,该请求自然会通过ssh协议封装发送给c6,然后在c6上解封装,形成telnet流量,发送给c5

杀死9527端口占用,便于下个实验使用

2:远程端口转发

在之前的 本地端口转发中,首先要满足的是c5防火墙上必须打开22端口,但是在现实生活中,企业处于安全考虑,一般是不会打开防火墙,只允许出不允许进。所以,当防火墙的端口没有打开的时候,我们要怎么办呢?这就要用到我们接下来要说的远程转发了:

命令:-R sshserverport:remotehost:remotehostport sshserver

说明:sshserverport         被转发机器开启的端口号

           remotehost          最终连接机器的IP地址

           remotehostport        被转发机器的端口号

           sshserver             被转发机器的IP地址

  同样的,我们以实验来具体说明我们的远程转发:

原理:

将远程主机(服务器)的某个端口转发到本地端指定机器的指定端口. 工作原理是这样的, 远程主机上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接, 该连接就经过安全通道转向出去, 同时本地主机和 host 的 hostport 端口建立连接. 可以在配置文件中指定端口的转发. 只有用 root 登录远程主机才能转发特权端口。

实验:

三台机器:c5服务器,c6跳板机,c7客户机

c5服务器只允许telnet连接(23端口)访问,不允许外部直接访问,c6服务器是一个ssh服务器;有一个用户需要从外部连接到企业内部的c5服务器。

c6机器访问c7用户,给c7用户转发

实验步骤:

1)模拟c5不允许c7连接,并且开启c6的telnet服务端口23。

步骤和实现本地转发的步骤1一样

2)开启隧道转发(telnet隧道)

    这一次,由于防火墙完全关闭,外部的设备连接不进来,所以我们要通过c6机器去连接c7的机器,因此,我们的开启隧道命令要在c6上运行:

首先,我们要确定一下c6上开启了哪些端口:

[root@centos6 ~]# ss -ntl
State       Recv-Q Send-Q                  Local Address:Port                    Peer Address:Port 
LISTEN      0      128                                :::22                                :::*     
LISTEN      0      128                                 *:22                                 *:*     
LISTEN      0      64                                 :::23                                :::*     
LISTEN      0      128                         127.0.0.1:631                                *:*     
LISTEN      0      128                               ::1:631                               :::*     
LISTEN      0      100                               ::1:25                                :::*     
LISTEN      0      100                         127.0.0.1:25                                 *:*     
LISTEN      0      128                         127.0.0.1:6010                               *:*     
LISTEN      0      128                               ::1:6010                              :::*  

然后,我们选择一个没有被开启的端口开启隧道,进行实验:

[root@centos6 ~]# ssh -R 9527:172.18.254.130:23 -fN 172.18.253.91
root@172.18.253.91's password: 
[root@centos6 ~]# 

同样的,在这里,我们可以通过ss -nt查看接口连接情况:

[root@centos6 ~]# ss -nt
State       Recv-Q Send-Q                  Local Address:Port                    Peer Address:Port 
ESTAB       0      52                     172.18.251.152:22                    172.18.253.114:56177 
ESTAB       0      0                      172.18.251.152:51854   (c7收到一个远程连接)               172.18.253.91:22    
[root@centos6 ~]# 
[root@centos7 ~]# ss -nt
State      Recv-Q Send-Q             Local Address:Port                            Peer Address:Port              
ESTAB      0      52                172.18.254.130:22  (c6 c7 已建立连接)                          172.18.253.114:64271              
[root@centos7 ~]# 

3)在c7上输入以下命令,用9527端口连接c5:

[root@centos7 ~]# telnet 127.0.0.1 9527
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
Kernel 2.6.18-164.el5 on an i686
login: liubei
Password: 
Last login: Thu Aug 23 11:11:20 from centos6
[liubei@centos5 ~]$

至此,我们已经实现了c7外部远程连接c5的需求,接下来我们就来讲一讲实现过程:

当c7连接自己的9527端口时,该请求自然会通过ssh协议封装发送给c6,然后在c6上解封装,形成telnet流量,发送给c5

三:动态端口转发实现科学上网

三台机器: c7(国内) c6(国外可以访问的网站)c5(谷歌)

模拟Google的服务器c5不允许国内网站c7直接访问,c6服务器是国外的一个小型的学习用的服务器;国内网站c7可以访问国外学习服务器c6;实现国内网站c7访问模拟Google服务器c5。

国内网站c7通过ssh协议连接到国外学习服务器c6上,再通过国外学习服务器c6做跳板,连接至Google服务器c5。

实验步骤:

1)在模拟google服务器c5上搭建一个网页,从互联网上访问c5时,页面显示"Welcome to www.google.com"

  命令如下:

[root@centos5 ~]# cd /var/www/html/
[root@centos5 html]# vim index.html
<h1> Welcome to www.google.com </h1> 

编写完文件以后,记得重启一下httpd服务:

[root@centos5 html]# systemctl restart httpd 

2)模拟Google服务器c5不允许国内网站c7连接

  在c5上输入以下口令:

 [root@centos5 ~]# iptables -A INPUT -s 172.18.254.130 -j REJECT

  此时,我们来测试一下c6和c7能否访问c5,命令为:

  curl c5 

[root@rhel6 ~]# curl 172.18.253.91
<h1> Welcome to www.google.com </h1>

 
[root@centos7 ~]# curl 172.18.253.91
curl: (7) couldn't connect to host 

3)动态端口转发

首先,我们在c6机器上确认已经开启的端口有哪些:

[root@centos6 ~]# ss -ntl
State       Recv-Q Send-Q                  Local Address:Port                    Peer Address:Port 
LISTEN      0      128                                :::22                                :::*     
LISTEN      0      128                                 *:22                                 *:*     
LISTEN      0      64                                 :::23                                :::*     
LISTEN      0      128                         127.0.0.1:631                                *:*     
LISTEN      0      128                               ::1:631                               :::*     
LISTEN      0      100                               ::1:25                                :::*     
LISTEN      0      100                         127.0.0.1:25                                 *:*     
LISTEN      0      128                         127.0.0.1:6010                               *:*     
LISTEN      0      128                               ::1:6010                              :::*     
[root@centos6 ~]# 

我们使用1080端口,从上图中我么已经看出,1080端口没有被占用,所以我们可以使用~

接着我们建立动态转发的隧道(c6上输入以下命令):

[root@centos6 ~]# ssh -D 1080 -fN 172.18.253.91
root@172.18.253.91's password: 
[root@centos6 ~]#

4)设置代理c7访问c5,命令如下(在c6上输入):

[root@centos6 ~]# curl --socks5 127.0.0.1:1080 http://172.18.253.91
<h1> Welcome to www.google.com </h1>
[root@centos6 ~]# 

现在c6可以访问c5了

5)在图形化界面,在7上的firefox浏览器设置代理:

点击OK

回到终端查看,也可在浏览器中查看

[root@centos7 ~]# curl 172.18.253.91
<h1> Welcome to www.google.com </h1>

访问成功。