配合sudo使用 Google Authenticator

• 本文约 629 字,阅读大致需要 2 分钟 | Security | #Google Authenticator | #sudo | #2FA | #TOTP | #security | #PAM

📜 历史文件已不具备现实意义

基于TOTP的做法不易备份,此外无法防止钓鱼。新部署时应考虑 FIDO 2 等更为现代化的解决方案。

Google Authenticator 是一个TOTP(基于时间的一次性口令)实现,它采用了 RFC 4226 算法。

Google Authenticator与 RSA SecurID 非常类似。具体来说,它使用一个随机串和以整数表达的时间作为输入去计算HOTP(算法是HMAC-SHA-1),然后取输出的最后几位作为一次性口令。

虽然目前已经发现了一些SHA-1的弱点,但目前为止还没有公开的已知算法可以从hash值直接高效地反推出明文信息。另一方面,HOTP只截取hash的最后几位,因此,攻击者在知道可能的明文信息之后,还必须获得足够多的TOTP时间和hash值才能够进行离线验证。

在现代Unix系统上,通常使用PAM来完成系统的验证工作。在 FreeBSD 上,可以通过 security/pam_google_authenticator 来安装Google Authenticator的PAM模块。这样就可以配置sudo来使用它做验证了。

在 /usr/local/etc/pam.d/sudo中,auth部分预设是这样的:

auth include system

这表示采用系统内建的 ‘system’ 规则配置。我们在这后面加入强制使用Google Authenticator的配置:

auth required /usr/local/lib/pam_google_authenticator.so noskewadj

这里的required表示如果验证失败则认为整个验证链失败。

如果不需要用户重新输入口令,则可以用上面这行换掉include那行。

在sudoers中还需要配置使用口令。如果是NOPASSWD,则系统会绕过auth这一部分。

需要注意的是,由于sudo是一个特权提升点,因此假如用可以被用户自行改动的文件作为访问控制机制,便会构成一个显然的安全漏洞。因此,对应的Google Authenticator配置应以sudo的目标用户的身份进行(此外还应在sudoers中配置Defaults rootpw):

sudo google-authenticator

也许应该抽时间改进一下,例如把authenticator的修改做成setuid的,并实现先验证之后再改?