需求
之前在《macOS 上用触控 ID 安全登录 SSH》,最近比较常用 Linux 桌面,所以还得在 Linux 上也搞一套安全的登陆方式。
分析
目前,MBA13 M1 的 Touch ID 在 Asahi Linux 下无法使用,其它机器也都没有指纹识别器,显然只有 TPM 2.0 模块是唯一适合的安全手段。
参考
实现
1. 检查 TPM
1 | sudo dmesg | grep -i tpm |
如果没有输出,那可能是内核不支持或者没有 TPM 芯片;但也可能只是内核比较老,没有输出而已,比如华为擎云 W515 就没有输出,但它能用。
类似以下输出,是没有芯片:
1 | [ 0.800622] ima: No TPM chip found, activating TPM-bypass! |
内核识别出 TPM 芯片的输出:
1 | [ 0.000000] efi: ACPI=0x75620000 ACPI 2.0=0x75620014 TPMFinalLog=0x755ef000 SMBIOS=0x75cac000 SMBIOS 3.0=0x75cab000 MEMATTR=0x6bf5d018 ESRT=0x6e822718 MOKvar=0x75ce8000 |
2. 安装必要软件
1 | sudo apt install tpm2-tools tpm2-abrmd libtpm2-pkcs11-tools libtpm2-pkcs11-1 |
其中:
-
tpm2-tools
是一套工具。获得tpm2
和tss2
两个命令,可以用sudo tpm2 getrandom --hex 8
测试 TPM2 是否正常工作。 -
tpm2-abrmd
是一个服务,使得非 root 用户能访问 TPM2 映射文件,只需把用户加到 tss 组即可。 -
libtpm2-pkcs11-tools
是 PKCS#11 backend,用于访问加密服务。它提供的tpm2_ptool
是一个 Python 脚本,可用于管理令牌、密钥。 -
libtpm2-pkcs11-1
是 SSH 用的模块,即提供一个符合 PKCS#11 规范的 so 动态库。对于 x64 机器,固定链接位于/lib/x86_64-linux-gnu/pkcs11/libtpm2_pkcs11.so
。如果您安装了gcc
,则可用TPM2_PKCS11_SO=/usr/lib/$(gcc -dumpmachine)/pkcs11/libtpm2_pkcs11.so
来保存它到变量TPM2_PKCS11_SO
,以方便使用。
3. 配置用户
1 | sudo usermod -a -G tss $USER |
如果在桌面或 SSH 会话,可以注销,再登录,使以上配置生效。也可以用 su - $USER
登录一个新会话,这时新会话是生效的,但 exit
后,回到的旧会话依然不生效。
4. 检验
1 | tpm2 getrandom --hex 8 |
注意,上面这条没有 sudo,必须保证没有 sudo 也能获得随机数,才说明 tpm2-abrmd
正常工作,并且用户加入 tss 组,并且重新登录会话!
5. 新建私钥
1 | # 在默认位置 ~/.tpm2_pkcs11 初始化一个数据库 |
稣一般使用 ecc384,即 NIST P-384,但有些机器会报错,这时可以尝试 ecc256,即 NIST P-256。注意:据说 NIST 系列安全性存疑?
6. 导入私钥
这第 6 步与第 5 步只需二选一。
第 5 步中新建私钥是无法导出的,万一自己不小心删了,或者升级 BIOS,也可能无法解开,导致私钥丢失。所以,如果这私钥是不能丢的,那最好的方式是从离线保存的私钥文件里导入。
这步可能有风险,因为需要把离线保存的私钥文件复制到目标机器,而且要将私钥的密码清零。为了提高安全性,建议离线操作,并尽可能快速完成全部流程。
1 | # 在内存文件系统操作,防止私钥落盘 |
7. 查看公钥
1 | TPM2_PKCS11_SO=/usr/lib/$(gcc -dumpmachine)/pkcs11/libtpm2_pkcs11.so |
可以导到文件里:
1 | ssh-keygen -D $TPM2_PKCS11_SO > ~/.ssh/tpm.pub |
8. 设置 SSH 服务端
这里在本地测试:
1 | cat ~/.ssh/tpm.pub >> ~/.ssh/authorized_keys2 |
测试连接:
1 | ssh -I $TPM2_PKCS11_SO $USER@localhost |
9. 【可选】使用 ssh-agent
1 | pgrep -u $UID ssh-agent || eval `ssh-agent` |
10. 【可选】对指定主机自动使用 TPM 密钥
添加以下文本:
1 | Host umu618.com |
或者对全部主机使用:
1 | cat <(echo "PKCS11Provider $TPM2_PKCS11_SO") ~/.ssh/config \ |