ssh 原理
SSH之所以能够保证安全,原因在于它采用了公钥加密
- 远程主机收到用户的登录请求,把自己的公钥发给用户
- 用户使用这个公钥,将登录密码加密后,发送回来。
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录
SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。
中间人攻击:用户可能收到伪造的公钥,获取用户的登录密码。
- 首次登录用户收到公钥指纹(公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹)
- 让用户决定是否接受这个远程主机的公钥
- 当远程主机的公钥被接受以后,它就会被保存在文件
$HOME/.ssh/known_hosts
之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。
应用修改
所有修改记得
重新启动 sshd。
1 |
|
密码登录
修改配置
1 |
|
修改密码
passwd user-name
修改端口
1 |
|
密钥登录/密钥+密码登录
本地
1 |
|
ssh-keygen
-
-b
参数指定密钥的二进制位数。这个参数值越大,密钥就越不容易破解,但是加密解密的计算开销也会加大。一般来说,
-b
至少应该是1024
,更安全一些可以设为2048
或者更高。 -
-f
参数指定生成的私钥文件。 -
-N
参数用于指定私钥的密码(passphrase)。 -
-p
参数用于重新指定私钥的密码(passphrase)。它与-N
的不同之处在于,新密码不在命令中指定,而是执行后再输入。ssh 先要求输入旧密码,然后要求输入两遍新密码。 -
-t
参数用于指定生成密钥的加密算法,一般为dsa
或`rsa
如果生成密钥对时输入密码,登录时候也要求密码
host
1 |
|
authorized_keys
远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys
(权限644)文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。
等效
1 |
|
使用ssh-copy-id
命令之前,务必保证authorized_keys
文件的末尾是换行符(假设该文件已经存在)。
证书登录
配置非常麻烦,而且只支持域名但是
- 密码登录不安全
- 密钥登录需要服务器保存用户的公钥,也需要用户保存服务器公钥的指纹。这对于多用户、多服务器的大型机构很不方便,如果有员工离职,需要将他的公钥从每台服务器删除。
引入了一个证书颁发机构(Certificate1 authority,简称 CA),对信任的服务器颁发服务器证书,对信任的用户颁发用户证书。
登录时,用户和服务器不需要提前知道彼此的公钥,只需要交换各自的证书,验证是否可信即可。
优点
- 用户和服务器不用交换公钥
- 证书可以设置到期时间,公钥没有到期时间
流程
准备
-
用户和服务器都将自己的公钥,发给 CA;
-
CA 使用服务器公钥,生成服务器证书,发给服务器
-
CA 使用用户的公钥,生成用户证书,发给用户。
登录 (验证对方证书,CA可靠)
- 用户登录服务器时,SSH 自动将用户证书发给服务器
- 服务器检查用户证书是否有效,以及是否由可信的 CA 颁发
- SSH 自动将服务器证书发给用户
- 用户检查服务器证书是否有效,以及是否由信任的 CA 颁发
- 双方建立连接,服务器允许用户登录
CA 服务器生成密钥对
CA 可以用同一对密码签发用户证书和服务器证书,但是出于安全性和灵活性,最好用不同的密钥分别签发。
1 |
|
双方生成自己的密钥对
服务器
1 |
|
用户
1 |
|
CA服务器签发双方公钥
1 |
|
-s
:指定 CA 签发证书的密钥。-I
:身份字符串,可以随便设置,相当于注释,方便区分证书,将来可以使用这个字符串撤销证书。-h
:指定该证书是服务器证书,而不是用户证书。-n host.example.com
:指定服务器的域名,表示证书仅对该域名有效。如果有多个域名,则使用逗号分隔。用户登录该域名服务器时,SSH 通过证书的这个值,分辨应该使用哪张证书发给用户,用来证明服务器的可信性。-n user
:指定用户名,表示证书仅对该用户名有效。如果有多个用户名,使用逗号分隔。用户以该用户名登录服务器时,SSH 通过这个值,分辨应该使用哪张证书,证明自己的身份,发给服务器。-V +52w
:指定证书的有效期,这里为52周(一年)。默认情况下,证书是永远有效的。建议使用该参数指定有效期,并且有效期最好短一点,最长不超过52周。
1 |
|
证书安装
服务器
-
ssh_host_rsa_key-cert.pub 公钥证书
-
user_ca.pub CA签发用户的公钥
放到/etc/ssh/下面
1 |
|
客户端
-
user_key-cert.pub 和 user_key 放在一个目录
-
CA签发服务器证书的公钥host_ca.pub加到客户端的/etc/ssh/ssh_known_hosts文件(全局级别)或者~/.ssh/known_hosts文件(用户级别)。
追加一行,开头为@cert-authority *.example.com
,然后将host_ca.pub
文件的内容(即公钥)粘贴在后面,大概是下面这个样子。
1 |
|
上面代码中,*.example.com
是域名的模式匹配,表示只要服务器符合该模式的域名,且签发服务器证书的 CA 匹配后面给出的公钥,就都可以信任。如果没有域名限制,这里可以写成*
。如果有多个域名模式,可以使用逗号分隔;如果服务器没有域名,可以用主机名(比如host1,host2,host3
)或者 IP 地址(比如11.12.13.14,21.22.23.24
)。
验证
ssh -i ~/.ssh/user_key user@host.example.com
废除证书
废除证书的操作,分成用户证书的废除和服务器证书的废除两种。
服务器证书的废除,用户需要在known_hosts
文件里面,修改或删除对应的@cert-authority
命令的那一行。
用户证书的废除,需要在服务器新建一个/etc/ssh/revoked_keys
文件,然后在配置文件sshd_config
添加一行,内容如下。
1 |
|
revoked_keys
文件保存不再信任的用户公钥,由下面的命令生成。
1 |
|
上面命令中,-z
参数用来指定用户公钥保存在revoked_keys
文件的哪一行,这个例子是保存在第1行。
如果以后需要废除其他的用户公钥,可以用下面的命令保存在第2行。
1 |
|
模拟SSH登录代码
1 |
|