一、SSH的概念
- 全名SecureShell,是一项建立在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境。
- 传统的网络服务程序,如rsh、FTP、POP和Telnet其本质上都是不安全的;因为它们在网络上用明文传送数据、用户帐号和用户口令,很容易受到中间人(man-in-the-middle)攻击方式的攻击。
- SSH之另一项优点为其传输的数据可以是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、POP、甚至为PPP提供一个安全的「通道」。
- OpenSSH是SSH的替代软件包,而且是开放源码且自由的。
二、SSH的安全验证
- 第一种级别(基于密码的安全验证),知道帐号和密码,就可以登录到远程主机,并且所有传输的数据都会被加密。但是,可能会有别的服务器在冒充真正的服务器,将伪造的公钥发给用户,所以仍然无法避免被「中间人」攻击。步骤如下:
- 远程主机收到用户的登录请求,把自己的公钥发给用户。
- 用户使用这个公钥,将登录密码加密后,发送回来。
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。
注意:https与ssh不同,https的公钥是经过证书中心公证的,必须从CA (Certificate Authority)申请一个用于证明服务器用途类型的证书。
第二种级别(基于密钥的安全验证),需要依靠密钥,也就是你必须为自己创建一对密钥,并把公有密钥放在需要访问的服务器上。登录的时候,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后,再发回来。远程主机用事先储存的公钥进行解密,如果成功,就证明用户是可信的,直接允许登录shell,不再要求密码。从而避免被「中间人」攻击。步骤如下:
- ssh-keygen -t rsa -c ‘abc@abc’生成公钥私要
- ssh-copy-id user@host将公钥传送到远程主机host上面,效果等同ssh user@host ‘mkdir -p .ssh && cat >> .ssh/authorized_keys’ < ~/.ssh/id_rsa.pub
- 确认主机/etc/ssh/sshd_config文件
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
- service ssh restart重启主机ssh服务
三、SSH隧道
ssh隧道3中类型
- 动态端口转发
- 本地端口转发
- 远端端口转发
动态端口转发
- 概念:动态端口允许通过配置一个本地端口,把通过隧道到数据转发到远端的所有地址。本地的应用程序需要使用Socks协议与本地端口通讯。此时SSH充当Socks代理服务器的角色。
- 命令格式:
ssh -D [bind_address:]port
- 描述:谁要是请求[bind_address:]port被我收到了,我就把请求通过ssh服务器发给host:hostport
- 参数说明:
- bind_address 指定绑定的IP地址,省略情况会绑定在本地的回环地址(即127.0.0.1),只能自己使用。如果为*会绑定本地所有的IP地址,同一局域网下的其他主机也可以使用。
- port 指定本地绑定的端口
使用场景:
假设X网络(192.168.18.0/24)有主机A(192.168.18.100),Y网络(192.168.2.0/24)有主机B(192.168.2.100)和主机C(192.168.2.101),已知主机A可以连接主机B,但无法连接主机C。在主机A执行
$ ssh -D localhost:8080 root@192.168.2.100
然后主机A上的应用程序就可以通过
SOCKS5 localhost:8080
- 访问主机C上的服务
- 优点
- 配置一个代理服务就可以访问远端机器和与其所在子网络的所有服务
- 缺点
- 应用程序需要额外配置SOCKS代理,若应用程序不支持代理配置则无法使用
- 相关知识
- HTTP代理:能够代理客户机的HTTP访问,主要是代理浏览器访问网页,它的端口一般为80、8080、3128等;
- SOCKS代理:SOCKS代理与其他类型的代理不同,它只是简单地传递数据包,而并不关心是何种应用协议,既可以是HTTP请求,所以SOCKS代理服务器比其他类型的代理服务器速度要快得多。SOCKS代理又分为SOCKS4和SOCKS5,二者不同的是SOCKS4代理只支持TCP协议(即传输控制协议),而SOCKS5代理则既支持TCP协议又支持UDP协议(即用户数据包协议),还支持各种身份验证机制、服务器端域名解析等。SOCK4能做到的SOCKS5都可得到,但SOCKS5能够做到的SOCK4则不一定能做到,比如我们常用的聊天工具QQ在使用代理时就要求用SOCKS5代理,因为它需要使用UDP协议来传输数据
本地端口转发
- 概念:通过SSH隧道,将一个远端机器能够访问到的地址和端口,映射为一个本地的端口。
- 命令格式:
ssh -L [bind_address:]port:host:hostport
- 描述:对方的ssh服务器是公网主机,我连到上面,并承诺谁要是请求[bind_address:]port被我收到了,我就把请求通过ssh服务器发给host:hostport
- 参数说明:
- bind_address 指定绑定的IP地址,省略情况会绑定在本地的回环地址(即127.0.0.1),只能自己使用。如果为*会绑定本地所有的IP地址,同一局域网下的其他主机也可以使用。
- port 指定本地绑定的端口
- host 指定数据包转发目标地址的IP,如果目标主机和ssh server是同一台主机时该参数指定为localhost
- host_port 指定数据包转发目标端口
使用场景:
假设X网络(192.168.18.0/24)有主机A(192.168.18.100),Y网络(192.168.2.0/24)有主机B(192.168.2.100)和主机C(192.168.2.101),已知主机A可以连接主机B,但无法连接主机C。A主机需要访问C主机的VNC服务(5900端口)。在A主机上建立本地转发端口5901
$ ssh -L 5901:192.168.2.101:5900 root@192.168.2.100
然后本地vnc客户端通过5901端口打开c主机的vnc服务
open vnc://localhost:5901
- 访问主机C上的服务
- 优点
- 无需设置代理
- 缺点
- 每个服务都需要配置不同的端口转发
远端端口转发(反向端口转发)
- 概念:远程端口转发用于某些单向阻隔的内网环境,比如说NAT,网络防火墙。在NAT设备之后的内网主机可以直接访问公网主机,但外网主机却无法访问内网主机的服务。如果内网主机向外网主机建立一个远程转发端口,就可以让外网主机通过该端口访问该内网主机的服务。可以把这个内网主机理解为“内应”和“开门者”。
- 命令格式:
ssh -R [bind_address:]port:host:hostport
- 描述:对方是两个内网主机,我是公网主机,其中一个连到我,并告诉我,谁要是请求[bind_address:]port被我收到了,我就把请求通过ssh服务器发给host:hostport
- 参数说明:
- bind_address 指定绑定的IP地址,省略情况会绑定在本地的回环地址(即127.0.0.1),只能自己使用。如果为*会绑定本地所有的IP地址,同一局域网下的其他主机也可以使用。
- port 指定本地绑定的端口
- host 指定数据包转发源地址的IP,如果源主机和ssh server是同一台主机时该参数指定为localhost
- host_port 指定数据包转发源端口
使用场景:
假设X网络(192.168.18.0/24)有主机A(192.168.18.100),Y网络(192.168.2.0/24)有主机B(192.168.2.100)和主机C(192.168.2.101),已知主机B可以通过SSH访问登录A主机,但反向直接连接被禁止,主机B和主机C可以相互访问。若主机A想访问主机C的VNC服务(5900端口)。在主机B执行如下命令。
$ ssh -L 5901:192.168.2.101:5900 root@192.168.2.100
然后本地vnc客户端通过5901端口打开C主机的vnc服务
open vnc://localhost:5901
- 访问主机C上的服务
- 优点
- 可以穿越防火墙和NAT设备
- 缺点
- 每个服务都需要配置不同的端口转发
四、SSH免密码登录
- 原理:所谓的免密码登录,就是使用了ssh基于密钥的安全认证。
- 主机A:1.1.1.1
- 主机B:2.2.2.2
目标:A主机的test用户,以B主机的test用户登录时不需要输入密码
步骤一
ssh-keygen -t rsa -C 'test@1.1.1.1' 默认路径,无密码就好 scp ~/.ssh/id_rsa.pub test@2.2.2.2:~/
步骤二
在2.2.2.2的主机上 mkdir ~/.ssh 如果已有就不用自己新建了 cat ~/id_rsa.pub >> ~/.ssh/authorized_keys chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
仍然需要输入密码
- 请确认所有文件夹属于自己
chown -R test:test ~/.ssh
请确认权限正确
chmon 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub
SELinux引发的血案
ls -laZ ~/.ssh 查看安全上下文信息,如果 drwx------. jenkins jenkins system_u:object_r:ssh_home_t:s0 .ssh 不是ssh_home_t而是别的,就用 restorecon -r -vv .ssh/修复一下吧 修复完如果还不是ssh_home_t,就用 chcon -R -t ssh_home_t .ssh/改一下吧
还没解决?
你可以看看2.2.2.2的日志 tail /var/log/secure -n 20 或者看看1.1.1.1的日志 ssh -vvv test@2.2.2.2
- 请确认所有文件夹属于自己
五、参考文章
- 维基百科
- SSH原理与运用(一):远程登录
- SSH原理与运用(二):远程操作与端口转发
- 三种不同类型的ssh隧道
- 目前本篇博客内容,大体来自上面三个文档的总结与更正,感谢文章的作者们。