使用GPG 生成SSH密钥替代密码进行SSH登录认证 & 续期GPG密钥
参考:
Using OpenPGP Keys For SSH Authentication
我已经生成了用于邮件签名和加密的密钥,只需要在此基础上增加一个用于A即可,如果你没用GPG加密过邮件,强烈建议看一看这个:
电子邮件加密指南
gpg --expert --edit-key yourmail@addr.com
gpg>addkey
选择RSA、DSA、ECC均可,但是必须是(自定义用途)。我选择ECC,因为Goodspeed说这个短😀(ECC后面还会选不同的ECC标准实现,我选择了(1) Curve 25519,你也可以在了解大致区别后选择别的标准。)
随后选择(S)签名功能开关、(E)和(A)身份验证开关,直到目前启用的功能 仅包含身份验证(Authenticate),然后选择(Q)完成。
还需要选择有效时间
生成完成记得保存
gpg>save
这时使用gpg --list-keys
可以发现我们已经得到了一个新的密钥对,如果你和我选择完全相同,你会看到多了类似下面的一个密钥对。不管你怎末选,这里都应该是可用于A,如果你新增的内容不被标注可以用于A,那你大概是在上面的功能开关选择错了。
ssb ed25519/9E25EFFF37DDA369
创建于:2024-02-01 有效至:2028-01-31 可用于:A
生成SSH公钥:
gpg --export-ssh-key 9E25EFFF37DDA369
(你可以加上 > ssh_gnu_key.pub把GPG生成的SSH公钥写入文件中存储备用),
公钥内容应该被写入你要控制的服务器的:~/.ssh/authorized_keys
文件中
如果Server上路径或文件不存在就直接 mkdir ~/.ssh && touch ~/.ssh/authorized_keys
再写入。
接下来工作重新回到本地,本地PC默认使用ssh-agent作为ssh代理,但是我们使用了GPG生成的密钥对,需要让gpg-agent成为ssh代理。
为 gpg-agent 启用SSH支持:
echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf
将 SSH_AUTH_SOCK 环境变量指向 gpg-agent 的套接字:
echo "export SSH_AUTH_SOCK=\$(gpgconf --list-dirs agent-ssh-socket)" >> ~/.bashrc
source ~/.bashrc
指定SSH登录使用的身份验证子密钥:
如果你不知道是哪个,可以输入gpg --list-secret-keys --with-keygrip
查看具有[A]即标示的子密钥(ssb)的keygrip
echo "EF21ED9472AA44F7CC0D337F29540E2D97D154C7" >> ~/.gnupg/sshcontrol
启动 gpg-agent:
gpg-agent --daemon
新gpg-agent配置(如果你在完全配置好之前就启动了gpg-agent)
gpg-connect-agent updatestartuptty /bye
接下来,尝试使用ssh yourserver.com 访问你的服务器
你会被提醒输入密码解密私钥。(是私钥的密码!)
正确输入后你将可以直接登录已经添加了公钥的服务器。
细节优化
你会发现解锁私钥后不久重新连接服务器需要重新解锁私钥,这一问题可以通过调整 GPG 代理的超时时间解决。
nano ~/.gnupg/gpg-agent.conf
default-cache-ttl 3600
max-cache-ttl 3600
此处单位是秒,3600即1小时。
End
后记
给自己的GPG密钥续期
过期就换固然安全,但是未必方便。如果你在Android上使用OpenKeychain或类似的软件管理自己密钥,续期就显得很容易了。
当然,PC上也并不复杂,在gpg命令行下输入
gpg>expert
即可对主密钥对进行续期。
续期完成后一定要上传公共密钥服务器以同步密钥状态。
gpg --send-keys YOUR_KEYID
使用--keyserver
参数可以指定公共密钥服务器(通常不需要,除非hkps://keys.openpgp.org这个全世界都在用的公共服务器被墙。)
其他设备如何连接?
比如手机,可以参考:在Termux 里使用GPG密钥登录ssh服务器