78.ssh隧道

1.ssh常用命令

详情请看朱双印的博客http://www.zsythink.net/

01:交互式生成密钥对
ssh-keygen
上述命令表示在完全交互的模式下生成密钥对

02:指定密钥对生成位置与名称
ssh-keygen -f /testdir/test/id_rsa
上述命令表示在/testdir/test目录下生成私钥id_rsa以及对应的公钥,-f选项表示直接指定密钥生成位置以及密钥的名称,
但是还是会交互式的提示用户为私钥设置密码,自定义密钥生成位置与名称后,在使用ssh命令连接到对应主机时,可以使用
-i选项指定对应的密钥,比如:
ssh -i /testdir/id_rsa_zsy_testkey zsy@192.168.50.50
 
03:直接生成密钥对并设置密码
ssh-keygen -P '123456' -f /testdir/test/id_rsa
上述命令表示在/testdir/test目录下生成私钥id_rsa以及对应的公钥,并且为将私钥的密码设置为123456,-P (大写P)
表示指定私钥的密码,上述命令不会进入交互模式,所以用户不用输入任何信息即可生成密钥对,如果想要生成没有密码的
私钥,只需要将 -P '123456' 改为 -P '' 即可。

04:为私钥添加密码,取消密码,修改密码
ssh-keygen -f /testdir/test/id_rsa -p
上述命令表示为私钥设置新密码,-p(小写p)表示为私钥设置新密码,无论私钥原来是否有密码,都可以使用此命令对私
钥设置新密码,输入上述命令后,会进入交互模式,如果原来私钥没有密码,则会直接提示输入新密码,即为私钥添加密码,
如果私钥原来就有密码,则会提示先输入老密码,再提示输入新密码,即为修改私钥密码,如果私钥原来就有密码,现在想要
取消原来的密码,只需要在提示输入新密码时直接回车即可。

05:生成指定类型的密钥
ssh-keygen -t dsa -P '' -f /testdir/test/id_dsa
上述命令表示生成dsa类型的密钥对,-t选项表示指定密钥的类型,即指定算法,版本2的ssh协议可以指定的密钥类型有 
"dsa", "ecdsa", "ed25519", "rsa"

06:生成指定位数的密钥
ssh-keygen -t rsa -b 1024 -P '' -f /testdir/test/id_rsa
上述命令表示生成1024位长的密钥,-b用于指定密钥的位数。

07:根据私钥生成公钥
ssh-keygen -f /testdir/test/id_rsa -y
上述命令表示根据私钥生成对应的公钥,-y选项表示根据私钥生成对应的公钥,生成的公钥会打印在屏幕中,我们可以
使用重定向生成公钥文件。

ssh-keygen -f /testdir/test/id_rsa -y > id_rsa.pub
如果私钥有密码,则需要在生成公钥是提供密码,用户需要在交互式模式中输入密码,如果不想使用交互式输入密码,
可以使用-P选项(大写P)提供密码。

08:将公钥加入到指定账户的认证文件中
当ssh服务器使用默认端口号时,使用如下命令

ssh-copy-id -i ~/.ssh/id_rsa.pub zsy@10.1.0.3
当ssh服务器未使用默认端口号时,使用如下命令
centos6中:ssh-copy-id -i ~/.ssh/id_rsa.pub "zsy@10.1.0.3 -p 22222"
centos7中:ssh-copy-id -i ~/.ssh/id_rsa.pub zsy@10.1.0.3 -p 22222
-i 选项用于指定公钥文件
- p 选项用于指定ssh服务器的端口号
也可以使用如下命令,效果与上述命令相同
cat ~/.ssh/id_rsa.pub | ssh -p 22 zsy@10.1.0.3 "umask 077;mkdir -p ~/.ssh;cat - >> ~/.ssh/authorized_keys"

2.ssh-agent常用命令

01:启动ssh-agent
如下两种方式均可启动ssh-gent
方式一:创建子shell,在子shell中运行ssh-agent进程,退出子shell自动结束代理。
ssh-agent $SHELL   """这种是启动一个临时窗口"""
方式二:单独启动一个代理进程,退出当前shell时最好使用ssh-agent -k关闭对应代理
eval `ssh-agent`   """这种事后台启动一个守护进程形式"""
  
02:关闭ssh-agent
ssh-agent -k

03:将私钥添加到ssh代理
ssh-add ~/.ssh/key_name
  
04:查看代理中的私钥
ssh-add -l
  
05:查看代理中的私钥对应的公钥
ssh-add -L
  
06:移除指定的私钥
ssh-add -d /path/of/key/key_name
  
07:移除代理中的所有私钥
ssh-add -D
  
08:锁定ssh代理
锁定时需要指定锁定密码,锁定后的ssh代理暂时不能帮助我们管理私钥
ssh-add -x
  
08:解锁ssh代理
解锁时需要输入创建锁时设定的密码,解锁后ssh代理可正常工作
ssh-add -X

grant all privileges on *.* to 'root'@'%' identified by '1' with grant option;

3.ssh远程管理

scp root@10.20.70.222:/root/cpu.txt root@10.20.70.224:/root/cpu.txt  """当你执行这个命令的时候需
要输入222的密码和224的密码,如何避免呢"""

解决思路:(其实可以理解为FQ这种概念)
    """其实当我把223服务器的秘钥发送给222和224之后,我同样执行这条命令还是会让我输入224的密码,这是因为
223->222->224,其中224需要的是222的公钥(但是我的222服务器是堡垒机啊,我不能让其他服务器保存堡垒机的公钥,
如果堡垒机沦陷所有秘钥将丢失),所以想到了如下的方式"""
    我们通过223服务器远程操作222服务器,拷贝文件到224服务器,但是都需要输入密码很麻烦,所以我们设想一种代
理模式,通过222将224的输入密码的操作请求转发到223服务器上,这个时候我们通过秘钥验证的时候,只需要将223的秘
钥分别发送到222和224服务上就可以实现(ssh-keygen和ssh-copy_id).但是如何设置转发呢?
    1.开启223服务的转发功能
    223服务器/etc/ssh/ssh_config配置文件(注意:ssh_config与sshd_config不要搞混了)
    将ForwardAgent的值设置为yes,默认情况下ForwardAgent配置项是被注释的,默认值为no
    ForwardAgent yes表示允许ssh客户端进行代理转发
    2.开启222服务器的转发功能
    222服务器的/etc/ssh/sshd_config配置文件(注意:ssh_config与sshd_config不要搞混了)
将AllowAgentForwarding的值设置为yes,表示允许进行代理转发, openssh中AllowAgentForwarding默认值即为yes,
所以,如果配置没有修改过,保持默认即可。

	"""经过这些操作之后就可以直接在223服务器上管理222和224了(同时这是很bug的,就算224禁止了223的访问,
我们通过222中间商代理了请求通过可以访问它,所以请确保两边的安全性)"""  
    参考:
        http://www.zsythink.net/archives/2422

4.ssh隧道(本地转发)

01:问题:
    """当我们使用mysql -uroot -p -h10.20.70.223,连接其它主机的mysql服务的时候,通过抓包可以知道数据在传
输过程中是明文的,我们如何通过ssh服务来转发请求是的通信变成加密过程呢?也就是有222mysql---->223mysql变成 
222mysql--->222ssh -----223>ssh ---->223mysql的过程,从直接连变成通过ssh加密之后的联机方式"""
    server1:222 (mysql客户端)
    server2:223 (msyql服务端)
    server3:224 (mysql客户端)
        
server1上执行:
    ssh -L 9966:10.20.70.223 root@10.20.70.223  (其实就是在222客户端上面起一个9966端口,转发请求到223
服务器的3306端口,也就是表示当访问222服务端的9966端口就是访问223的3306端口)
        
# 参数讲解:       
第1部分为-L选项,-L 选项表示使用"本地转发"建立ssh隧道,本地转发是什么意思呢?
"本地转发"表示本地的某个端口上的通讯数据会被转发到目标主机的对应端口,你可以把它抽象的理解成一种"映射",注意,
我们把执行上述命令的主机称为"本地主机"。比如,访问本地(当前主机)的端口A,就相当于访问目标主机的端口B,因为当
你访问本地的端口A时,通讯数据会被转发到目标主机的端口B,这就是本地转发,其实,"本地转发"是与"远程转发"相对应
的,但是我们还没有介绍到远程转发,所以并不用在意那么多,我们只要先了解本地转发的作用就行了。刚才说过,"本地转
发"表示本地的某个端口上的通讯数据会被转发到目标主机的对应端口,那么你一定能够理解上述命令中第2部分的含义了

第2部分表示:通讯数据会从本地的9906端口上被转发,最终被转发到10.1.0.2的3306端口。

第3部分表示:我们创建的ssh隧道是连接到10.1.0.2上的root用户的,其实,第3部分可以与之前的ssh连在一起去理解,比
如,ssh root@10.1.0.2,其实就是使用ssh命令从ServerA中连接到ServerB的root用户,这就是为什么执行上述命令以后,
会提示我们输入10.1.0.2中root用户的密码,当然,如果你已经在ServerB中配置好了ServerA对应用户的公钥,那么则可以
省去输入密码的步骤直接连接,此时,ServerA的角色是ssh的客户端,ServerB的角色是ssh的服务端,而这条ssh隧道就是建
立在ServerA与ServerB之间的。

server1:
"""查看端口情况,发现9966监听者本地回环地址"""
[root@lala ~]# netstat -tnulp|grep 9966
tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh           
tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
 
server1:
"""通过制定ip和端口连接223的mysql服务"""
[root@lala ~]# mysql -uroot -P9966 -h127.0.0.1 -p1
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| muke               |
| mysql              |
| performance_schema |
| test2              |  # 这个库是我在223上特别创建出来的,可以看出来连接上了
+--------------------+

但是当我们把执行这个ssh -L 9966:10.20.70.223 root@10.20.70.223命令的窗口关闭之后,就不能连接是不是很坑.
    
02:问题
    """其实在问题1中我们的解决思路没问题,但是能不能让ssh -L 9966:10.20.70.223 root@10.20.70.223这条命令在后
台启动一个守护进程,方便我们每次连接呢?因为每次退出之后这个9966端口就没了."""
    ssh -f -N -L 9966:10.20.70.223:3306 root@10.20.70.223 
    -N选项:当配合此选项创建ssh隧道时,并不会打开远程shell连接到目标主机
    -f选项:表示后台运行
    
   server1: 
   """查看端口情况,发现9966监听者本地回环地址"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh           
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
    
    server1:
    """通过制定ip和端口连接223的mysql服务"""
    [root@lala ~]# mysql -uroot -P9966 -h127.0.0.1 -p1
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | muke               |
    | mysql              |
    | performance_schema |
    | test2              |  # 这个库是我在223上特别创建出来的,可以看出来连接上了
    +--------------------+
    
    这个时候又出现问题了,我需要通过server3访问server1的9966端口请求server2的3306端口(也就是mysql服务好像不行啊)

问题3:
    """问题2结束抛出的问题,如何让server3通过server1访问到server2的服务呢?将监听的ip换成server3的,我试了一下不行.
然后我又换了一种思路直接监听所有ip"""
    
    server1:
    ssh -f -N -L 0.0.0.0:9966:10.20.70.223:3306 root@10.20.70.223 
    -N选项:当配合此选项创建ssh隧道时,并不会打开远程shell连接到目标主机
    -f选项:表示后台运行
    
    server1:
   """查看端口情况,发现9966监听者本地回环地址"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh           
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
	
    server3
    """通过制定ip和端口连接223的mysql服务"""
    [root@lala ~]# mysql -uroot -P9966 -h10.20.70.222 -p1
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | muke               |
    | mysql              |
    | performance_schema |
    | test2              |  # 这个库是我在223上特别创建出来的,可以看出来连接上了
    +--------------------+
    
    这个好了,换成监听所有的之后就可以访问了.

5.ssh隧道(远程转发)

server1:222 (mysql客户端)外网[你自己的]
server2:223 (msyql服务端)
server3:224 (mysql客户端)
问题1:
    """通过上面我们解决了本地转发的问题,接下来场景时server1外网ip, server2内网ip(提供mysql服务,或者可以连接内
部mysql服务,这个时候你是使用本地转发肯定不行了,你回到家里连内网连都连不到玩个锤子.这个时候我们能不能让server2主
动连接server1在server1上执行命令呢?)"""
    server2:
    ssh -f -N -R 9966:10.20.70.223:3306 root@10.20.70.222
    -R选项: 可以创建一个"远程转发"模式的ssh隧道  (也就是通过server2操控server1,在server1上启动9966端口)         server1:
   """查看端口情况,发现9966监听者本地回环地址"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh       
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
	
    server1
    """通过制定ip和端口连接223的mysql服务"""
    [root@lala ~]# mysql -uroot -P9966 -h127.0.0.1 -p1
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | muke               |
    | mysql              |
    | performance_schema |
    | test2              |  # 这个库是我在223上特别创建出来的,可以看出来连接上了
    +--------------------+
    
    这个问题好像解决了,但是就像本地转发中的问题3一样,我需要通过server3连接server1之后再连接server2呢?

问题2:
    """
    问题1结束抛出的问题,如何让server3通过server1访问到server2的服务呢?将监听的ip换成server3的,我试了一下不行,
然后我又换了一种思路直接监听所有ip
    """
    server2:
    ssh -f -N -R 0.0.0.0:9966:10.20.70.223:3306 root@10.20.70.222
    -R选项: 可以创建一个"远程转发"模式的ssh隧道  (也就是通过server2操控server1,在server1上启动9966端口) 
     
    server1
     
    """查看端口情况,发现9966监听者本地回环地址,但是我发现他死活不让我改,还是监听本机地址"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh       
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
                            
    man ssh 我查了一下-R参数的介绍,发现默认就是监听这个地址,需要更改server1上的/etc/ssh/sshd_config文件中的
GatewayPorts参数才可以,ok改了之后重启sshd服务再试一次上面的命令
    
    server1
    """查看端口情况,发现9966监听者本地回环地址,这次OK了"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 0.0.0.0:9966            0.0.0.0:*               LISTEN      2825/ssh       
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
                            
    server1
    """通过制定ip和端口连接223的mysql服务"""
    [root@lala ~]# mysql -uroot -P9966 -h10.20.70.222 -p1
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | muke               |
    | mysql              |
    | performance_schema |
    | test2              |  # 这个库是我在223上特别创建出来的,可以看出来连接上了
    +--------------------+
    这下都解决了OK了哈哈哈
    
问题3:
    server1:222 (mysql 客户端)
    server2:223 (msyql 客户端)
    server3:224 (mysql msyql服务端)
    """睡不好,又出现问题了,上面各种情况都是mysql服务和server2挂钩的,但是现在mysql服务跑到server3上面了肿么办?"""
    server2:
    ssh -f -N -L 9966:10.20.70.224:3306 root@10.20.70.223
    -R选项: 可以创建一个"远程转发"模式的ssh隧道  (也就是通过server2操控server1,在server1上启动9966端口)         server1:
   """查看端口情况,发现9966监听者本地回环地址"""
    [root@lala ~]# netstat -tnulp|grep 9966
    tcp        0      0 127.0.0.1:9966            0.0.0.0:*               LISTEN      2825/ssh       
    tcp6       0      0 :::9966                 :::*                    LISTEN      2825/ssh
	
    server1
    """通过制定ip和端口连接223的mysql服务"""
    [root@lala ~]# mysql -uroot -P9966 -h127.0.0.1 -p1
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | muke               |
    | mysql              |
    | performance_schema |
    | test              |  # 这个库是我在224上特别创建出来的,可以看出来连接上了
    +--------------------+
    
    上述场景中存在一个问题,就是数据安全性的问题,我们之所以使用ssh隧道,就是为了用它来保护明文传输的数据,从而
提升安全性,不过,在上例的场景中,只有ServerA与ServerB之间的传输是受ssh隧道保护的,ServerB与ServerC之间的传输,
仍然是明文的,所以,如果想要在上述场景中使用ssh隧道进行数据转发,首先要考虑ServerB与ServerC之间的网络是否可靠。
    
问题4:
    """问题3虽然解决了连接问题,但是安全问题如何解决呢,其实就是在server2再做一次转发,但是在某些实际的使用场景中
,我们使用ssh隧道的目的并不是提升数据的安全性,而是为了绕过防火墙"""
    
# 一些配置
其实,如果想要能够正常的使用ssh端口转发,我们还需要做出正确的配置才行,之前一直没有说明,是因为openssh默认的配置就
是支持端口转发的。
如果想要ssh端口转发能够正常工作,需要在ssh服务端的配置文件中将AllowTcpForwarding的值设置为yes。
此处所指的ssh服务端即ssh隧道中的一头,扮演ssh服务端角色的那台主机。
当隧道建立以后,经过一段时间后,ssh隧道链接可能会被断开,这有可能是因为ssh客户端和ssh服务端长时间没有通讯,于是ssh
服务端主动断开了链接,如果想要解决这个问题,可以在ssh服务端进行配置,调整ssh服务端的ClientAliveInterval配置
和ClientAliveCountMax配置即可。

# 小结
经过上述描述,我想你应该已经了解的ssh隧道的作用。
通常,ssh隧道可以帮助我们达到如下目的:
1、保护tcp会话,保护会话中明文传输的内容。
2、绕过防火墙或者穿透到内网,访问对应的服务。

  

# 为了以后方便回顾,我们将上文中使用到的命令及选项进行总结
创建隧道时的常用选项有:
"-L选项":表示使用本地端口转发创建ssh隧道
"-R选项":表示使用远程端口转发创建ssh隧道
"-N选项": 表示创建隧道以后不连接到sshServer端,通常与"-f"选项连用
"-f选项":表示在后台运行ssh隧道,通常与"-N"选项连用
"-g选项":表示ssh隧道对应的转发端口将监听在主机的所有IP中,不使用"-g选项"时,转发端口默认只监听在主机的本地回环地址中,
"-g"表示开启网关模式,远程端口转发中,无法开启网关功能。

创建本地转发模式的ssh隧道,命令如下
ssh -g -f -N -L forwardingPort:targetIP:targetPort user@sshServerIP
本机上的forwardingPort将会被监听,访问本机的forwardingPort,就相当于访问targetIP的targetPort,ssh隧道建立在
本机与sshServer之间。

创建远程转发模式的ssh隧道,命令如下
ssh -f -N -R forwardingPort:targetIP:targetPort user@sshServerIP
sshServer上的forwardingPort将会被监听,访问sshServer上的forwardingPort,就相当于访问targetIP的targetPort,
ssh隧道建立在本机与sshServer之间。

posted @ 2020-07-23 16:21  楠海  阅读(217)  评论(0编辑  收藏  举报