【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【远程开发】内网穿透:密钥算法介绍(二)
讲了 SSH 密钥算法中一般支持的密钥长度,然后提到了 -t 选项还有另一个功能:指定签名算法,下面继续分析下
内网穿透
之前 blog 【Ubuntu】【远程开发】内网穿透:密钥算法介绍(一) 最开始说密钥算法的时候,提到 -t 选项可以选择用来生成密钥的算法类型 ,除了指定密钥算法类型外,-t 还可以用来指定签名算法

具体来说,是 RSA 密钥算法的基础上 ,选择签名算法类型 ,有 ssh-rsa(不安全),rsa-sha2-256(安全),rsa-sha2-512(更安全,默认值)
使用场景一般是企业内部用 CA 统一签发 SSH 证书,这里的 CA 指的是 Certificate Authority,中文翻译过来就是认证授权,当热,内网穿透不涉及 CA 签名,只是刚好分析到,就详细说下
首先不用 CA 签名,而是用传统的 SSH 登录方式,看是什么情况
- 用户本地生成私钥
id_ed25519和公钥id_ed25519.pub - 用户登录 Web 控制台,把公钥
id_ed25519.pub内容粘贴进去 - 平台后端自动把公钥写入某个用户的 authorized_keys 文件(或等效数据库)
- 然后用户用私钥可以直接 SSH 登录,或者
git clone下载代码

这种做法简单直观,用户自己可以完成,适合身份绑定到账号的场景,比如这个公钥属于账号 XXX,典型使用场景有 GitHub,Gitee,GitLab,小团队服务器等等,但也有缺点,比如
- 无法自动过期(除非平台额外开发)
- 无法限制权限粒度(比如只能读不能写,只能访问某仓库)
- 无法限制来源 IP 或有效期
- 大规模服务器管理困难(每台机器都要同步公钥)
对于开源的代码托管平台 ,比如 GitHub,Gitee,它们不关心用户能做什么,什么时候做,在哪里做,它们只关心用户是谁,是不是属于平台账号的,所以不需要 CA 签名 ,而在大型组织中,对权限,有效期,成本比较敏感,如果也采用上面传统的形式,会带来高维护成本,高管理成本,审计困难,且容易出错
之前 blog 【Ubuntu】【远程开发】内网穿透:密钥算法介绍(一) 提到过,rsa 是第一个既能用于加密又能用于数字签名的公钥算法,下面就来看 RSA CA 签名验证的登录方式
- 首先,在 SSH CA 场景中,CA 授权中心拥有一对 RSA 密钥(包含公私钥),其中 ca_key 私钥用于签名,ca_key.pub 公钥用于验签
- 用户在本地生成密钥对
id_ed25519和id_ed25519.pub,注意,这里另一套密钥对,用户自己生成的, 不是上面的 RSA 密钥,RSA 密钥是在授权中心 - 用户向 CA 授权中心发送公钥
id_ed25519.pub申请证书,CA 授权中心验证身份通过后,用授权中心的 ca_key 私钥签发一个带策略的证书id_ed25519-cert.pub - 这个签名证书是个结构化数据,包含了用户公钥,元数据(有效期、权限、身份),CA 的数字签名 等信息,做这个签名主要是为了限制和授权公钥的使用范围,从而解决传统 SSH 公钥认证中一旦公钥被接受就永久有效,无权限控制的问题
- 证书被签名后,会被授权中心再返还给用户,这样,用户拿到
id_ed25519-cert.pub证书,可以用它登录任意受信服务器 - 登录时要出示签名证书 ,证书里面的数字签名用来证明授权是合法的 ,并且要按照证书中的权限和有限期来执行,签名验证通过后,服务器会提取证书中的公钥信息
- 注意,这里服务器只存放 CA 公钥 ,不存任何用户公钥(用户公钥存放在用户手里,这和传统的 SSH 登录是反过来的),用户在登录时,再把证书(里面包含了公钥)传递给服务器
- 再之后就是传统的 SSH 登录过程

CA 方案不用用户上传公钥,而是用户自己申请临时证书 ,可见优点包括自动过期(用户私钥可长期用,但证书短期有效,安全合规刚需 ),权限精细控制,集中吊销,方便审计,服务器无需同步用户列表等,缺点就是架构复杂,需要额外维护 CA,另外,不适合公开服务(比如 GitHub),这种方案不用用户上传公钥,而是用户申请临时证书
(补充)上图说的后续使用传统的 SSH 登录 ,这里不是说服务器存了用户的公钥,而是用户的公钥已经包含在证书里面,服务器解析证书的时候就已经知道了公钥信息,然后用公钥信息加密数据再给用户回复过去,基本流程相同,不同的就是服务器不存放用户的公钥
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【远程开发】内网穿透:SSH 建立连接