一直使用SSH登录服务器,本以为自己已经很了解了,最近才偶然得知 SSH 也有类似 SSL 一样的 CA 体系。 作为一个非专业运维(DevOps) 选手,顿时感到惭愧。顺便抽空学习了一下。

SSH 登录和验证

SSH 登录是所有用 Linux 系统,尤其是服务器的人必须会用到的功能,一般情况下登录分为两种:

  1. 简单粗暴 - 密码登录
  2. 相对安全且方便 - 密钥登录

除了登录以外还有很多人会忽略的验证环节,这里是指避免中间人攻击的服务器指纹验证 (Host Key)

我不过多的去阐述各个不同登录的优缺点,网上搜索很多内容。至于指纹验证很多人可能会忽略,因为每次都需要 “Yes/No”.

证书登录和验证

相比前面提到的密钥登录,证书登录依然是使用SSH密钥,不同的是,他引入了一个 CA 的机制,避免了多用户多服务器以及公钥增减上面的繁琐。

简单来说,从以前的服务器需要被添加(或删除)某个公钥,变换成了服务器完全不需要变化,只需要信任某个 CA 然后由 CA 去签名信任某些公钥就可以了。

这样做的优点我引用阮一峰老师的教程来说

  1. 用户和服务器不需要交换公钥,更容易管理,且有更好的可扩展性
  2. 证书可以设置到期时间,针对不同情况可以控制访问时间

具体步骤

多余的不说,直接来具体操作吧

一 生成 CA 密钥对 + 用 CA 签名

首先需要生成一个 SSH 密钥对用户充当 CA 角色,这里生成的办法和原先生成 SSH 密钥 没有任何去吧。

一般会有两种方式可选,视情况而选择

  1. 生成一个 CA 用于 用户(User) 和 服务器(Host) 两个不同需求
  2. 分别生成两个 CA

我们以下的示例中,仅考虑一个 CA 的情况

生成CA
ssh-keygen -t ed25519 -f ~/.ssh/ca_ed25519 -C "User and Host CA"

假设你已经有自己的密钥/公钥,你只需要签名就行
ssh-keygen -s ~/.ssh/ca_ed25519 -I "WhatEverName" -n principals,name -V -5m:+52w ~/.ssh/id_ed25519.pub

如果你需要签名服务器的公钥,那么用以下命令
ssh-keygen -s ~/.ssh/ca_ed25519 -h -I "WhatEverName" -n hostname,ip_addr -V -5m:+52w /etc/ssh/ssh_host_ed25519_key.pub

注释:

  • ca_ed25519 是你生成的 CA 的密钥 (后面还会有一个 ca_ed25519.pub 作为公钥)
  • id_ed25519.pubssh_host_ed25519_key.pub 分别是用户的 SSH Key 和服务器的 Host SSH Key
  • -I 填写的叫做 “key_id” 主要是自己能认识的名字,没有什么要求,一般就是 用户名/邮箱 或者 域名
  • -n 这个 Principals 比较重要,后面会用到
  • -V 有效日期,可以写年月日,也可以是几个小时几天或者几周,比如 -5m:52w 就是 5分钟前 至 52周后

配置使用 CA

前面部分完成签名之后,就需要配置服务器使用 CA 了

/etc/ssh/sshd_config
# 用户 SSH 访问配置
TrustedUserCAKeys /root/.ssh/ca_ed25519.pub
AuthorizedPrincipalsFile %h/.ssh/authorized_principals

# 服务器指纹配置
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub

~/.ssh/
# 用户 SSH 访问配置
"your-set-principals" >>~/.ssh/authorized_principals

然后在自己的本地需要配置

# 服务器指纹配置
"@cert-authority * $(cat content-of-your-ca_ed25519.pub)" >>~/.ssh/known_hosts

同时在登录 SSH 的时候需要确定本地拥有你自己的 密钥 和完成签名的 证书 即可