如何在 Linux 上使用一次性密码保护 SSH 登录
正如有人所说,安全不是一个产品,而是一个过程。虽然 SSH 协议本身在设计上是加密安全的,但如果管理不当,有人可能会对您的 SSH 服务造成严重破坏,无论是弱密码、泄露的密钥还是过时的 SSH 客户端。
就 SSH 身份验证而言,公钥身份验证通常被认为比密码身份验证更安全。然而,如果您从公共或共享计算机登录,密钥身份验证实际上是不可取的,甚至不太安全,在这些计算机上,诸如隐形键盘记录器或内存抓取之类的东西总是有可能发生。如果您不能信任本地计算机,最好使用其他计算机。这就是一次性密码派上用场的时候。顾名思义,每个一次性密码仅供一次性使用。这种一次性密码可以在不受信任的环境中安全使用,因为即使被盗也无法重复使用。
生成一次性密码的一种方法是通过 Google Authenticator。在本教程中,我将演示另一种为 SSH 登录创建一次性密码的方法:OTPW,一次性密码登录包。与 Google Authenticator 不同,您不依赖任何第三方进行一次性密码生成和验证。
什么是 OTPW?
OTPW 由一次性密码生成器和 PAM 集成验证例程组成。在 OTPW 中,一次性密码是由生成器先验生成的,并由用户安全地携带(例如,打印在一张纸上)。然后,生成的密码的加密哈希值将存储在 SSH 服务器主机中。当用户使用一次性密码登录时,OTPW 的 PAM 模块会验证该密码,并使该密码失效以防止重复使用。
第一步:在 Linux 上安装和配置 OTPW
对于 Debian、Ubuntu 或 Linux Mint:
使用 apt-get 安装 OTPW 软件包。
$ sudo apt-get install libpam-otpw otpw-bin
使用文本编辑器打开 SSH 的 PAM 配置文件 (/etc/pam.d/sshd
),并注释掉以下行(以禁用密码身份验证)。
#@include common-auth
并添加以下两行(以启用一次性密码身份验证):
auth required pam_otpw.so
session optional pam_otpw.so

对于 Fedora 或 CentOS/RHEL:
OTPW 不能作为基于 Red Hat 的系统上的预构建软件包提供。因此,让我们通过从源代码构建来安装 OTPW。
首先,安装先决条件:
$ sudo yum git gcc pam-devel
$ git clone https://www.cl.cam.ac.uk/~mgk25/git/otpw
$ cd otpw
使用文本编辑器打开 Makefile,并编辑以 PAMLIB=
开头的行,如下所示。
在 64 位系统上:
PAMLIB=/usr/lib64/security
在 32 位系统上:
PAMLIB=/usr/lib/security
编译并安装它。请注意,安装将自动重新启动 SSH 服务器。因此,如果您使用 SSH 连接,请准备好断开连接。
$ make
$ sudo make install
现在您需要更新 SELinux 策略,因为 /usr/sbin/sshd 尝试写入用户的主目录,默认 SELinux 策略不允许这样做。以下命令即可。如果您不使用 SELinux,请跳过此步骤。
$ sudo grep sshd /var/log/audit/audit.log | audit2allow -M mypol
$ sudo semodule -i mypol.pp
接下来,使用文本编辑器打开 SSH 的 PAM 配置文件 (/etc/pam.d/sshd
),并注释掉以下行(以禁用密码身份验证)。
#auth substack password-auth
并添加以下两行(以启用一次性密码身份验证):
auth required pam_otpw.so
session optional pam_otpw.so
第二步:为 SSH 服务器配置一次性密码
下一步是将 SSH 服务器配置为接受一次性密码。
用文本编辑器打开/etc/ssh/sshd_config
,设置以下三个参数。确保不要多次添加这些行,因为这会导致 SSH 服务器失败。
UsePrivilegeSeparation yes
ChallengeResponseAuthentication yes
UsePAM yes
您还需要禁用默认密码身份验证。 (可选)启用公钥身份验证,以便在没有一次性密码的情况下可以回退到基于密钥的身份验证。
PubkeyAuthentication yes
PasswordAuthentication no
现在重新启动 SSH 服务器。
$ sudo service ssh restart
或者:
$ sudo systemctl restart sshd
第三步:使用 OTPW 生成一次性密码
如前所述,您需要事先创建一次性密码,并将其存储在远程 SSH 服务器主机上。为此,请以您要登录的用户身份运行 otpw-gen 工具。
$ cd ~
$ otpw-gen > temporary_password.txt

它会要求您设置前缀密码。当您稍后登录时,您需要输入此前缀密码和一次性密码。本质上,前缀密码是另一层保护。即使密码表落入坏人之手,前缀密码也会迫使他们进行暴力破解。
设置前缀密码后,该命令将生成 280 个一次性密码,并将它们存储在输出文本文件中(例如 temporary_password.txt
)。每个密码(默认长度为 8 个字符)前面都有一个三位数索引号。您应该将该文件打印在一张纸上并随身携带。

您还将看到创建的 ~/.otpw
文件,其中存储了这些密码的加密哈希值。每行的前三位数字表示将用于 SSH 登录的密码的索引号。
$ more ~/.otpw
OTPW1
280 3 12 8
191ai+:ENwmMqwn
218tYRZc%PIY27a
241ve8ns%NsHFmf
055W4/YCauQJkr:
102ZnJ4VWLFrk5N
2273Xww55hteJ8Y
1509d4b5=A64jBT
168FWBXY%ztm9j%
000rWUSdBYr%8UE
037NvyryzcI+YRX
122rEwA3GXvOk=z
测试 SSH 登录的一次性密码
现在让我们以通常的方式登录 SSH 服务器:
$ ssh [email _host
如果 OTPW 设置成功,您将看到略有不同的密码提示:
Password 191:
现在打开您的密码表,并在表中查找索引号 191
。
023 kBvp tq/G 079 jKEw /HRM 135 oW/c /UeB 191 fOO+ PeiD 247 vAnZ EgUt
根据上表,号码191
的一次性密码是fOO+PeiD
。您需要在其前面添加您的前缀密码。例如,如果您的前缀密码是 000
,则您需要输入的实际一次性密码是 000fOO+PeiD
。
一旦您成功登录,所使用的密码将自动失效。如果您检查~/.otpw
,您会注意到第一行被替换为---------------
,这意味着密码191
已作废。
OTPW1
280 3 12 8
---------------
218tYRZc%PIY27a
241ve8ns%NsHFmf
055W4/YCauQJkr:
102ZnJ4VWLFrk5N
2273Xww55hteJ8Y
1509d4b5=A64jBT
168FWBXY%ztm9j%
000rWUSdBYr%8UE
037NvyryzcI+YRX
122rEwA3GXvOk=z
结论
在本教程中,我演示了如何使用 OTPW 包设置 SSH 的一次性密码登录。您可能会意识到,打印表可以被视为双因素身份验证中安全令牌的不太花哨的版本。然而,它更简单,并且您不依赖任何第三方来实现它。无论您使用什么机制来创建一次性密码,当您需要从不受信任的公共计算机登录 SSH 服务器时,它们都会很有帮助。请随意分享您对此主题的经验或意见。