## ssh原理之读书笔记
SSH是一种协议标准,其使用了非对称加密了实现安全远程登录以及其它安全网络服务。
### 普通密码认证
- Server收到Client的登录请求,将自己的公钥发给Client
- Client使用这个公钥,将登录密码加密后,发送给Server
- Server用自己的私钥,解密登录密码,如果密码正确,就同意Client登录
#### 中间人攻击
SSH登录本身是安全的,问题在于,如果有人截获了登录请求,然后冒充Server,将伪造的公钥发给Client,
那么Client很难辨别真伪。因为不像https,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
攻击者插在Client和Server之间,用伪造公钥,获取到Client的登录面后,再用这个密码登录Server,那么SSH的安全机制就荡然无存了,
这就是著名的“中间人攻击”
#### 优点:
- 易于设置
#### 缺点:
- 允许暴力破解密码
- 每次都要求输入密码
### 公钥访问(免密)
- Client将自己的公钥存放在Server上,追加在文件authorized_keys中。
- Server端接收到Client的连接请求后,会在authorized_keys中匹配到
Client的公钥pubKey,并生成随机数R,用Client的公钥对该随机数进行加
密得到pubKey(R),然后将加密后信息发送给Client。
- Client端通过私钥进行解密得到随机数R,然后对随机数R和本次会话的
SessionKey利用MD5生成摘要Digest1,发送给Server端。
- Server端会也会对R和SessionKey利用同样摘要算法生成Digest2。
- Server端会最后比较Digest1和Digest2是否相同,完成认证过程。
#### 优点:
- 公钥不能轻易强行使用
- 相同的私钥(带有密码)可用于访问多个系统:无需记住许多密码
#### 缺点:
- 需要在目标系统上一次性设置公钥
- 要求在每次连接时使用秘密密码解锁私钥
#### ssh连接: node1连接node2
- 生成公钥以及密钥:
在node1上:
[hadoop@node1 ~]$ ssh-keygen -t rsa
- 将node1的公钥拷贝到node2
方法一:
[hadoop@node1 .ssh]$ scp -p id_rsa.pub hadoop@node2:~/.ssh/id_rsa.pub1
[hadoop@node1.ssh]$ cat id_rsa.pub1 > authorized_key
方法二:
ssh-copy-id -i ~/.ssh/id_rsa.pub 用户名@ip
- 连接
[hadoop@node1 .ssh]$ ssh hadoop@node2
### 具有代理支持的公钥访问
- ssh-agent是用来保存公钥身份验证所使用的私钥的程序(私钥管理器),运行ssh-agent以
后,使用ssh-add将私钥交给ssh-agent保管,其他程序需要身份验证的时候可以将验证申请交给
ssh-agent来完成整个认证过程。
#### 有server:host1、host2、host3且每台server上到保存了本机(local.biz)的公钥,因此我可以通过公钥认证登录到每台主机:
- [root@local.biz ~]#ssh host1
- [root@local.biz ~]#ssh host2
- [root@local.biz ~]#ssh host3
- 启用ssh-agent: [root@local.biz ~]#eval `ssh-agent `
- 添加私钥:[root@local.biz ~]#ssh-add
- Client进行初始连接,并发送用户名+公钥的请求。
- Server上的ssh守护程序在authorized_keys文件中查找是否有该公钥,根据该公钥构造一个challenge(公钥对一个随机数R进行加密),然后将challenge发送回Client的ssh客户端。
- ssh客户端收到challenge,并将其转发给ssh-agent。 ssh-agent(并不是ssh本身)会打开用户的私钥,并发现它受密码保护(提示用户输入密码以解锁私钥)。
- ssh-agent用私钥对challenge解密得到随机数R,然后对随机数R+SessionId进行MD5加密,并将到ssh进程,然后将其发送Server的sshd 。
- sshd将随机数R+SessionId进行MD5加密,验证其是否与Client传过来的密文相同,若相同,则授予对系统的访问权限。 注意:代理仍未将私钥保留在内存中,尽管它没有参与正在进行的话。
- 注:许多用户在早上启动ssh客户端和ssh-agent时只解锁一次私钥,而且一天中的剩余时间不必再次输入密码,这非常方便而且安全
参考资料:
https://blog.csdn.net/DiamondXiao/article/details/52488628?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
https://translate.google.com/translate?depth=1&hl=zh-CN&rurl=translate.google.com&sl=en&tl=zh-CN&u=http://www.unixwiz.net/techtips/ssh-agent-forwarding.html
#### 优点:
- 公钥不能轻易强行使用
- 相同的私钥(带有密码)可用于访问多个系统:无需记住许多密码
#### 缺点:
- 需要在目标系统上一次性设置公钥
- 要求在每次连接时使用秘密密码解锁私钥
### 具有代理转发的公钥访问
#### 有server:host1、host2、host3,目前你在host1,但是你需要将host2中的/dir/test文件拷贝到host3
- 在host1中执行:[root@host1 ~]#scp root@host2_ip/dir/test root@host2_ip/dir/
但是你需要输入host2和host3的密码,才能执行上诉命令
- 若我们将host1的公钥复制到host2和host3,在host1中执行
[root@host1 ~]#ssh-copy-id -i ~/.ssh/id_rsa.pub host1@host1_ip
[root@host1 ~]#ssh-copy-id -i ~/.ssh/id_rsa.pub host2@host2_ip
- 在执行上述命令 [root@host1 ~]#scp root@host2_ip/dir/test root@host2_ip/dir/ 后, 即使host1可以免密登录host2和host3,但是执行拷贝操作时仍然需要输入host3的密码
#### 原因如下:
- host1可以免密登录host2
- host1也可以免密登录host3
- 但是host2和host3之间没有任何基于免密登录的认证,因此在执行#scp root@host2_ip/dir/test root@host2_ip/dir/ 指令后host3不会与host1认证,而是和host2认证
#### 解决办法:
- 问题的根源在于host3虽然有host1的公钥,但是无法直接和host1认证
- 用host2充当host1和host3之间的代理转发(key-agent), 使得host3能够通过host2和host1认证
- 假设host1和host2已经建立连接,host1中的ssh-agent已经拥有了host1的私钥。
- host2启动ssh客户端,并将username+公钥的request传递给host3的ssh守护程序(这同样可以通过scp secure copy命令完成)
- host3的ssh守护程序查询authorized_keys文件中是否有host2的公钥,然后根据该公钥构造一个challenge3(公钥对一个随机数R进行加密),然后将challenge3发送回host2的ssh客户端。
- host2的ssh客户端接收到challenge3后,host2充当密钥代理将challenge3转发到host1的sshd服务器。
- host1收到challenge3之后 ,ssh客户端通过将ssh-agent中的私钥解密得到随机数R3,将随机数R3+SessionId进行MD5加密,并将得到的密文传送到本地ssh客户端,后者再将其沿着通道传到在host2上运行的sshd。
- 由于host2上的sshd充当key-agent,因此它将密文响应转发给发出请求的host3的ssh客户端, host3上的ssh守护程序验证密钥响应,如果有效,则授予对系统的访问权限。
#### 配置代理转发
- 编缉host1中的/etc/ssh/ssh_config文件:将ForwardAgent的值设置为yes
参考资料:http://www.zsythink.net/archives/2422/
http://www.unixwiz.net/techtips/ssh-agent-forwarding.html