[广告: 最高 ¥2000 红包]阿里云服务器, 主机等产品通用, 可叠加官网常规优惠使用 | 限时领取
p://www.ruanyifeng.com/blog/
SSH 是服务器登录工具, 提供密码登录和密钥登录.
但是, SSH 还有第三种登录方法, 那就是证书登录. 很多情况下, 它是更合理, 更安全的登录方法, 本文就介绍这种登录方法.
一, 非证书登录的缺点
密码登录和密钥登录, 都有各自的缺点.
密码登录需要输入服务器密码, 这非常麻烦, 也不安全, 存在被暴力破解的风险.
密钥登录需要服务器保存用户的公钥, 也需要用户保存服务器公钥的指纹. 这对于多用户, 多服务器的大型机构很不方便, 如果有员工离职, 需要将他的公钥从每台服务器删除.
二, 证书登录是什么?
证书登录就是为了解决上面的缺点而设计的. 它引入了一个证书颁发机构(Certificate1 authority, 简称 CA), 对信任的服务器颁发服务器证书, 对信任的用户颁发用户证书.
登录时, 用户和服务器不需要提前知道彼此的公钥, 只需要交换各自的证书, 验证是否可信即可.
证书登录的主要优点有两个:(1)用户和服务器不用交换公钥, 这更容易管理, 也具有更好的可扩展性.(2)证书可以设置到期时间, 而公钥没有到期时间. 针对不同的情况, 可以设置有效期很短的证书, 进一步提高安全性.
三, 证书登录的流程
SSH 证书登录之前, 如果还没有证书, 需要生成证书. 具体方法是:(1)用户和服务器都将自己的公钥, 发给 CA;(2)CA 使用服务器公钥, 生成服务器证书, 发给服务器;(3)CA 使用用户的公钥, 生成用户证书, 发给用户.
有了证书以后, 用户就可以登录服务器了. 整个过程都是 SSH 自动处理, 用户无感知.
第一步, 用户登录服务器时, SSH 自动将用户证书发给服务器.
第二步, 服务器检查用户证书是否有效, 以及是否由可信的 CA 颁发.
第三步, SSH 自动将服务器证书发给用户.
第四步, 用户检查服务器证书是否有效, 以及是否由信任的 CA 颁发.
第五步, 双方建立连接, 服务器允许用户登录.
四, 生成 CA 的密钥
证书登录的前提是, 必须有一个 CA, 而 CA 本质上就是一对密钥, 跟其他密钥没有不同, CA 就用这对密钥去签发证书.
虽然 CA 可以用同一对密码签发用户证书和服务器证书, 但是出于安全性和灵活性, 最好用不同的密钥分别签发. 所以, CA 至少需要两对密钥, 一对是签发用户证书的密钥, 假设叫做 user_ca, 另一对是签发服务器证书的密钥, 假设叫做 host_ca.
使用下面的命令, 生成 user_ca.
- # 生成 CA 签发用户证书的密钥
- $ SSH-keygen -t rsa -b 4096 -f ~/.SSH/user_ca -C user_ca
上面的命令会在~/.SSH 目录生成一对密钥: user_ca(私钥)和 user_ca.pub(公钥).
这个命令的各个参数含义如下.
-t rsa: 指定密钥算法 RSA.
-b 4096: 指定密钥的位数是 4096 位. 安全性要求不高的场合, 这个值可以小一点, 但是不应小于 1024.
-f ~/.SSH/user_ca: 指定生成密钥的位置和文件名.
-C user_ca: 指定密钥的识别字符串, 相当于注释, 可以随意设置.
使用下面的命令, 生成 host_ca.
- # 生成 CA 签发服务器证书的密钥
- $ SSH-keygen -t rsa -b 4096 -f host_ca -C host_ca
上面的命令会在~/.SSH 目录生成一对密钥: host_ca(私钥)和 host_ca.pub(公钥).
现在,~/.SSH 目录应该至少有四把密钥.
- ~/.SSH/user_ca
- ~/.SSH/user_ca.pub
- ~/.SSH/host_ca
- ~/.SSH/host_ca.pub
五, CA 签发服务器证书
有了 CA 以后, 就可以签发服务器证书了.
签发证书, 除了 CA 的密钥以外, 还需要服务器的公钥. 一般来说, SSH 服务器 (通常是 sshd) 安装时, 已经生成密钥 / etc/SSH/ssh_host_rsa_key 了. 如果没有的话, 可以用下面的命令生成.
$ sudo SSH-keygen -f /etc/SSH/ssh_host_rsa_key -b 4096 -t rsa
上面命令会在 / etc/SSH 目录, 生成 ssh_host_rsa_key(私钥)和 ssh_host_rsa_key.pub(公钥). 然后, 需要把服务器公钥 ssh_host_rsa_key.pub, 复制或上传到 CA 所在的服务器.
上传以后, CA 就可以使用密钥 host_ca 为服务器的公钥 ssh_host_rsa_key.pub 签发服务器证书.
$ SSH-keygen -s host_ca -I host.example.com -h -n host.example.com -V +52w ssh_host_rsa_key.pub
上面的命令会生成服务器证书 ssh_host_rsa_key-cert.pub(服务器公钥名字加后缀 - cert). 这个命令各个参数的含义如下.
-s: 指定 CA 签发证书的密钥.
-I: 身份字符串, 可以随便设置, 相当于注释, 方便区分证书, 将来可以使用这个字符串撤销证书.
-h: 指定该证书是服务器证书, 而不是用户证书.
-n host.example.com
: 指定服务器的域名, 表示证书仅对该域名有效. 如果有多个域名, 则使用逗号分隔. 用户登录该域名服务器时, SSH 通过证书的这个值, 分辨应该使用哪张证书发给用户, 用来证明服务器的可信性.
-V +52w: 指定证书的有效期, 这里为 52 周(一年). 默认情况下, 证书是永远有效的. 建议使用该参数指定有效期, 并且有效期最好短一点, 最长不超过 52 周.
ssh_host_rsa_key.pub
: 服务器公钥.
生成证书以后, 可以使用下面的命令, 查看证书的细节.
$ SSH-keygen -L -f ssh_host_rsa_key-cert.pub
最后, 为证书设置权限.
$ chmod 600 ssh_host_rsa_key-cert.pub
六, CA 签发用户证书
下面, 再用 CA 签发用户证书. 这时需要用户的公钥, 如果没有的话, 客户端可以用下面的命令生成一对密钥.
$ SSH-keygen -f ~/.SSH/user_key -b 4096 -t rsa
上面命令会在~/.SSH 目录, 生成 user_key(私钥)和 user_key.pub(公钥).
然后, 将用户公钥 user_key.pub, 上传或复制到 CA 服务器. 接下来, 就可以使用 CA 的密钥 user_ca 为用户公钥 user_key.pub 签发用户证书.
$ SSH-keygen -s user_ca -I user@example.com -n user -V +1d user_key.pub
上面的命令会生成用户证书 user_key-cert.pub(用户公钥名字加后缀 - cert). 这个命令各个参数的含义如下.
-s: 指定 CA 签发证书的密钥
-I: 身份字符串, 可以随便设置, 相当于注释, 方便区分证书, 将来可以使用这个字符串撤销证书.
-n user: 指定用户名, 表示证书仅对该用户名有效. 如果有多个用户名, 使用逗号分隔. 用户以该用户名登录服务器时, SSH 通过这个值, 分辨应该使用哪张证书, 证明自己的身份, 发给服务器.
-V +1d: 指定证书的有效期, 这里为 1 天, 强制用户每天都申请一次证书, 提高安全性. 默认情况下, 证书是永远有效的.
user_key.pub: 用户公钥.
生成证书以后, 可以使用下面的命令, 查看证书的细节.
$ SSH-keygen -L -f user_key-cert.pub
最后, 为证书设置权限.
$ chmod 600 user_key-cert.pub
七, 服务器安装证书
CA 生成服务器证书 ssh_host_rsa_key-cert.pub 以后, 需要将该证书发回服务器, 可以使用下面的 scp 命令, 将证书拷贝过去.
$ scp ~/.SSH/ssh_host_rsa_key-cert.pub root@host.example.com:/etc/SSH/
然后, 将下面一行添加到服务器配置文件 / etc/SSH/sshd_config.
HostCertificate /etc/SSH/ssh_host_rsa_key-cert.pub
上面的代码告诉 sshd, 服务器证书是哪一个文件.
重新启动 sshd.
- $ sudo systemctl restart sshd
- # 或者
- $ sudo service sshd restart
八, 服务器安装 CA 公钥
为了让服务器信任用户证书, 必须将 CA 签发用户证书的公钥 user_ca.pub, 拷贝到服务器.
$ scp ~/.SSH/user_ca.pub root@host.example.com:/etc/SSH/
上面的命令, 将 CA 签发用户证书的公钥 user_ca.pub, 拷贝到 SSH 服务器的 / etc/SSH 目录.
然后, 将下面一行添加到服务器配置文件 / etc/SSH/sshd_config.
TrustedUserCAKeys /etc/SSH/user_ca.pub
上面的做法是将 user_ca.pub 加到 / etc/SSH/sshd_config, 这会产生全局效果, 即服务器的所有账户都会信任 user_ca 签发的所有用户证书.
另一种做法是将 user_ca.pub 加到服务器某个账户的~/.SSH/authorized_keys 文件, 只让该账户信任 user_ca 签发的用户证书. 具体方法是打开~/.SSH/authorized_keys, 追加一行, 开头是 @cert-authority principals="...", 然后后面加上 user_ca.pub 的内容, 大概是下面这个样子.
@cert-authority principals="user" SSH-rsa AAAAB3Nz...XNRM1EX2gQ==
上面代码中, principals="user" 指定用户登录的服务器账户名, 一般就是 authorized_keys 文件所在的账户.
重新启动 sshd.
- $ sudo systemctl restart sshd
- # 或者
- $ sudo service sshd restart
至此, SSH 服务器已配置为信任 user_ca 签发的证书.
九, 客户端安装证书
客户端安装用户证书很简单, 就是从 CA 将用户证书 user_key-cert.pub 复制到客户端, 与用户的密钥 user_key 保存在同一个目录即可.
十, 客户端安装 CA 公钥
为了让客户端信任服务器证书, 必须将 CA 签发服务器证书的公钥 host_ca.pub, 加到客户端的 / etc/SSH/ssh_known_hosts 文件 (全局级别) 或者~/.SSH/known_hosts 文件(用户级别).
具体做法是打开 ssh_known_hosts 或 known_hosts 文件, 追加一行, 开头为 @cert-authority *.example.com, 然后将 host_ca.pub 文件的内容 (即公钥) 粘贴在后面, 大概是下面这个样子.
@cert-authority *.example.com SSH-rsa AAAAB3Nz...XNRM1EX2gQ==
上面代码中,*.example.com 是域名的模式匹配, 表示只要服务器符合该模式的域名, 且签发服务器证书的 CA 匹配后面给出的公钥, 就都可以信任. 如果没有域名限制, 这里可以写成 *. 如果有多个域名模式, 可以使用逗号分隔; 如果服务器没有域名, 可以用主机名 (比如 host1,host2,host3) 或者 IP 地址(比如 11.12.13.14,21.22.23.24).
然后, 就可以使用证书, 登录远程服务器了.
$ SSH -i ~/.SSH/user_key user@host.example.com
上面命令的 - i 参数用来指定用户的密钥. 如果证书与密钥在同一个目录, 则连接服务器时将自动使用该证书.
十一, 废除证书
废除证书的操作, 分成用户证书的废除和服务器证书的废除两种.
服务器证书的废除, 用户需要在 known_hosts 文件里面, 修改或删除对应的 @cert-authority 命令的那一行.
用户证书的废除, 需要在服务器新建一个 / etc/SSH/revoked_keys 文件, 然后在配置文件 sshd_config 添加一行, 内容如下.
RevokedKeys /etc/SSH/revoked_keys
revoked_keys 文件保存不再信任的用户公钥, 由下面的命令生成.
$ SSH-keygen -kf /etc/SSH/revoked_keys -z 1 ~/.SSH/user1_key.pub
上面命令中,-z 参数用来指定用户公钥保存在 revoked_keys 文件的哪一行, 这个例子是保存在第 1 行.
如果以后需要废除其他的用户公钥, 可以用下面的命令保存在第 2 行.
$ SSH-keygen -ukf /etc/SSH/revoked_keys -z 2 ~/.SSH/user2_key.pub
十二, 参考链接
- SSH Emergency Access https://smallstep.com/blog/ssh-emergency-access/ , Carl Tashian
- Using OpenSSH Certificate Authentication, Red Hat Enterprise Linux Deployment Guide
- How to SSH Properly, Gus Luxton
- (完)
来源: http://www.mzh.ren/ssh-certificate.html