OpenSSH中使用用户级cert-authority时如何撤销单个SSH证书?
嘿,我刚好踩过这个一模一样的坑!当初我把整个CA通过cert-authority加到~/.ssh/authorized_keys后,想撤销某台设备的证书,试了和你一样的操作——加restrict,command="false"配要撤销的公钥或证书,结果完全不管用,后来才搞明白问题出在哪。
为什么你的方法无效?
核心原因是OpenSSH处理authorized_keys的逻辑:它是按顺序匹配规则,而且cert-authority的信任优先级极高——只要证书是由信任的CA签发的,后面针对单个公钥/证书的拒绝规则根本不会被触发,因为系统已经匹配到信任规则并直接允许登录了。
两种可行的解决方案
方案一:用证书撤销列表(CRL)——官方推荐的标准做法
这是长期维护最省心的方式,也是OpenSSH官方认可的撤销途径:
- 第一步,用你的CA密钥生成CRL文件,把要撤销的证书添加进去,执行命令:
这里的ssh-keygen -k -f ~/.ssh/revoked_keys $REVOKED_CERTIFICATE$REVOKED_CERTIFICATE可以是你要撤销的证书文件,也可以是证书对应的公钥。执行后,~/.ssh/revoked_keys就是你的CRL文件。 - 第二步,修改
~/.ssh/authorized_keys里的cert-authority条目,加上crl-file选项,改成如下格式:
之后每次有证书尝试登录,OpenSSH都会自动检查这个CRL文件,里面列示的证书会被直接拒绝,其他合法的CA签发证书不受任何影响。后续如果要新增撤销的证书,只需执行cert-authority,crl-file=~/.ssh/revoked_keys $CA_PUBLIC_KEYssh-keygen -u -f ~/.ssh/revoked_keys $NEW_REVOKED_CERT(-u参数用于更新现有CRL),无需改动authorized_keys。
方案二:利用Principal前置拒绝(仅适用于签证书时指定了唯一Principal的场景)
如果你给每台设备的证书都签了唯一的Principal(比如自定义device-laptop、device-phone这类专属标识),可以用这个技巧:
- 在
authorized_keys里,把拒绝规则放在cert-authority条目之前,比如要撤销Principal为device-lost的证书,就添加这一行:restrict,command="false",principals="device-lost" $CA_PUBLIC_KEY - 然后再保留你的
cert-authority信任条目:
因为OpenSSH按顺序匹配规则,先匹配到的拒绝规则会优先生效,直接拦截对应Principal的证书登录,而后续的信任规则只会对未被拒绝的证书生效。但要注意,这个方法的前提是你之前签证书时就指定了唯一Principal,否则无法精准定位到要撤销的设备。cert-authority $CA_PUBLIC_KEY
备注:内容来源于stack exchange,提问作者Ryan Patterson




