作者选择了 COVID-19 救济基金 来接收捐赠,作为 [Write for DOnations] 的一部分](https://do.co/w4do-cta)程序。

介绍

SSH 默认使用密码进行身份验证,[大多数 SSH 加固说明建议使用 SSH 密钥](https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20- 04)。但是,SSH 密钥仍然只是一个因素,尽管是一个更安全的因素。通道是您计算机上的终端,通过加密隧道将数据发送到远程计算机。但是就像黑客可以猜出密码一样,他们可以窃取 SSH 密钥,然后在任何一种情况下,攻击者都可以使用该单条数据访问您的远程系统。

在本教程中,我们将设置多因素身份验证来解决这个问题。 多因素身份验证 (MFA) 或 双因素身份验证 (2FA) 需要多个因素来进行身份验证或登录。这意味着不良行为者将不得不破坏多个事物,例如您的计算机和您的手机,以便进入。身份验证中使用了几种类型的因素:

  1. 知道的东西,例如密码或安全问题

  2. 拥有的东西,例如身份验证器应用程序或安全令牌

  3. 的东西,比如你的指纹或声音

一个常见因素是 OATH-TOTP 应用程序,例如 Google Authenticator。 OATH-TOTP(Open Authentication Time-Based One-Time Password)是一种开放式协议,可生成一次性使用密码,通常是每 30 秒循环一次的六位数字。

本文将介绍如何使用 OATH-TOTP 应用程序和 SSH 密钥启用 SSH 身份验证。通过 SSH 登录到您的服务器需要两个通道上的两个因素,从而使其比单独使用密码或 SSH 密钥更安全。此外,我们还将介绍 MFA 的一些其他用例以及一些有用的提示和技巧。

如果您正在寻求有关保护 SSH 连接的进一步指导,请查看这些 [关于强化 OpenSSH 的教程](https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu-20- 04) 和 强化 OpenSSH 客户端。

先决条件

要遵循本教程,您将需要:

  • 一台 Ubuntu 20.04 服务器 使用 sudo 非 root 用户、SSH 密钥和启用防火墙,您可以按照 [Initial Server Setup] 进行设置教程](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-20-04)。

  • 安装了 OATH-TOTP 应用程序的智能手机或平板电脑,例如 Google Authenticator (iOS、Android)。

  • 或者,您也可以使用名为“oathtool”的 Linux 命令行应用程序来生成 OATH-TOTP 代码。它在各种发行版中可用 repos

  • 如果你想保护你的 SSH 连接,在这个 SSH Essentials 中有几个很好的步骤-and-keys) 文章,例如将用户列入白名单、禁用 root 登录以及更改 SSH 使用的端口。

第 1 步 — 安装 Google 的 PAM

在这一步中,我们将安装和配置 Google 的 PAM。

PAM 代表 Pluggable Authentication Module,是 Linux 系统上用于对用户进行身份验证的身份验证基础结构。因为 Google 制作了 OATH-TOTP 应用程序,所以他们还制作了一个 PAM,它可以生成 TOTP,并且与任何 OATH-TOTP 应用程序完全兼容,例如 Google Authenticator 或 Authy。

首先,更新 Ubuntu 存储库缓存:

sudo apt-get 更新

接下来,安装 PAM:

sudo apt-get install libpam-google-authenticator

安装 PAM 后,我们将使用 PAM 附带的帮助应用程序为需要第二个因素的用户生成 TOTP 密钥。此密钥是在逐个用户的基础上生成的,而不是在系统范围内生成的。这意味着每个想要使用 TOTP auth 应用程序的用户都需要登录并运行帮助应用程序来获取他们的密钥;您不能只运行一次即可为所有人启用它(但本教程末尾有一些提示可以为许多用户设置或要求 MFA)。

运行初始化应用程序:

谷歌身份验证器

运行命令后,应用程序会询问几个问题。第一个询问身份验证令牌是否应该基于时间:

输出您是否希望身份验证令牌是基于时间的 (y/n) y

此 PAM 允许基于时间或基于顺序的令牌。使用 sequential-based tokens 意味着代码从某个点开始,然后在每次使用后递增代码。使用 time-based tokens 意味着代码在某个时间范围后发生变化。我们会坚持使用基于时间的,因为这是像 Google Authenticator 这样的应用程序所期望的,所以回答“y”表示是。

回答完这个问题后,很多输出会滚动过去,包括一个大二维码。使用手机上的身份验证器应用程序扫描 QR 码或手动输入密钥。如果二维码太大而无法扫描,您可以使用二维码上方的 URL 获取较小的版本。添加后,您会在应用中看到每 30 秒更改一次的六位数代码。

注意:确保将密钥、验证码和恢复码记录在安全的地方,例如密码管理器。例如,如果您无法访问 TOTP 应用程序,恢复代码是重新获得访问权限的唯一方法。

剩下的问题告知 PAM 如何运作。我们将一一介绍:

输出你想让我更新你的“~/.google_authenticator”文件吗(y/n)y

这会将密钥和选项写入 .google_authenticator 文件。如果你说不,程序退出并且什么都不写,这意味着验证器将不起作用:

输出是否要禁止多次使用同一个身份验证
令牌?这限制您大约每 30 秒登录一次,但它会增加
您发现甚至阻止中间人攻击的机会 (y/n) y

通过在此处回答“是”,您可以通过使每个代码在使用后立即过期来防止重放攻击。这可以防止攻击者捕获您刚刚使用的代码并使用它登录:

输出默认情况下,移动应用每 30 秒生成一个新令牌。
为了补偿客户端和服务器之间可能的时间偏差,
我们允许在当前时间之前和之后有一个额外的令牌。这允许一个
身份验证服务器和客户端之间最多 30 秒的时间偏差。假设你
遇到时间同步不佳的问题。在这种情况下,您可以增加窗口
从其默认大小的 3 个允许的代码(一个以前的代码,当前
代码,下一个代码)到 17 个允许的代码(前 8 个代码,当前
代码,以及接下来的八个代码)。这将允许最多 4 分钟的时间偏差
客户端和服务器之间。
你想这样做吗? (是/否) n

在此处回答“是”允许在移动的四分钟窗口中最多输入 17 个有效代码。通过回答否,您将其限制为 1:30 分钟滚动窗口中的 3 个有效代码。除非您发现 1:30 分钟窗口存在问题,否则回答“否”是更安全的选择。您可以稍后在存储在主目录根目录的 .google_authenticator 文件中更改此设置:

输出如果您正在登录的计算机没有针对暴力破解进行强化
登录尝试,您可以为身份验证模块启用速率限制。
默认情况下,这将攻击者限制为每 30 秒不超过 3 次登录尝试。
是否要启用速率限制 (y/n) y

速率限制意味着远程攻击者只能尝试一定数量的猜测,然后被迫等待一段时间才能再次尝试。如果您之前没有直接在 SSH 中配置速率限制,那么现在这样做是一种很好的强化技术。

注意:完成此设置后,如果要备份密钥,可以将 ~/.google-authenticator 文件复制到受信任的位置。从那里,您可以在其他系统上部署它或在备份后重新部署它。

现在已经安装并配置了 Google 的 PAM,下一步是配置 SSH 以使用您的 TOTP 密钥。我们需要将 PAM 告诉 SSH,然后配置 SSH 以使用它。

第 2 步 — 配置 OpenSSH 以使用 MFA/2FA

因为我们将通过 SSH 进行 SSH 更改,所以永远不要关闭您的初始 SSH 连接,这一点很重要。相反,打开第二个 SSH 会话进行测试。这是为了避免在 SSH 配置中出现错误时将自己锁定在服务器之外。一旦一切正常,您就可以安全地关闭任何会话。另一个安全预防措施是创建您将要编辑的系统文件的备份,因此如果出现问题,您可以恢复到原始文件并使用干净的配置重新开始。

首先,备份 sshd 配置文件:

sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak

现在使用 nano 或您喜欢的文本编辑器打开文件:

Sudonano /等/ Pam。 d/shd

将以下行添加到文件的底部:

/etc/pam.d/sshd

. . .
# 标准 Un*x 密码更新。
@include 通用密码
需要验证 pam_google_authenticator.so nullok
需要验证 pam_permit.so

最后一行末尾的 nullok 字告诉 PAM 此身份验证方法是可选的。这允许没有 OATH-TOTP 令牌的用户仍然只使用他们的 SSH 密钥登录。一旦所有用户都拥有 OATH-TOTP 令牌,您可以从此行中删除“nullok”以强制执行 MFA。如果用户不使用 MFA 令牌登录,则需要带有 pam_permit.so 的第二行以允许身份验证。登录时,每个方法都需要 SUCCESS 以允许身份验证。如果用户不使用 MFA 身份验证工具,则使用 nullok 选项会返回 IGNORE 以进行交互式键盘身份验证。 pam_permit.so 然后返回 SUCCESS 并允许继续进行身份验证。

保存并关闭文件。

接下来,我们将配置 SSH 以支持这种身份验证。

首先对文件进行备份:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak


现在打开 SSH 配置文件进行编辑:

须藤纳米 /etc/ssh/sshd_config

查找 ChallengeResponseAuthentication 并将其值设置为 yes:

/etc/ssh/sshd_config

. . .
# 更改为 yes 以启用质询-响应密码(注意问题
# 一些 PAM 模块和线程)
ChallengeResponseAuthentication 是
. . .

保存并关闭文件,然后重新启动 SSH 以重新加载配置文件。重新启动 sshd 服务不会关闭我们当前打开的连接,这意味着您不会冒险使用以下命令将自己锁定:

sudo systemctl 重启 sshd.service

要测试到目前为止一切正常,请打开另一个终端并尝试通过 SSH 登录。保持当前 SSH 会话打开并使用附加会话进行测试非常重要,否则您将在某些时候将自己锁定,需要使用 Web 控制台才能重新进入。

注意: 如果您之前创建了 SSH 密钥并正在使用它,您会注意到您无需输入用户密码或 MFA 验证码。这是因为默认情况下 SSH 密钥会覆盖所有其他身份验证选项。否则,您应该得到密码和验证码提示。

接下来,要将 SSH 密钥作为一个因素,将验证码作为第二个因素,我们需要告诉 SSH 使用哪些因素,并防止 SSH 密钥覆盖所有其他类型。

第 3 步 — 让 SSH 了解 MFA

如果您使用 SSH 密钥,MFA 仍然无法正常工作。要让 SSH 了解 MFA,请重新打开 sshd 配置文件:

须藤纳米 /etc/ssh/sshd_config

在文件底部添加以下行。这告诉 SSH 需要哪些身份验证方法。我们告诉 SSH 用户需要一个 SSH 密钥和一个密码或一个验证码(或全部三个):

/etc/ssh/sshd_config

. . .
AuthenticationMethods publickey,password publickey,keyboard-interactive

保存并关闭文件。

接下来,再次打开 PAM sshd 配置文件:

Sudonano /等/ Pam。 d/shd

找到 @include common-auth 行并通过添加 # 字符作为该行的第一个字符将其注释掉。这告诉 PAM 不要提示输入密码:

/etc/pam.d/sshd

. . .
# 标准的 Un*x 认证。
#@include 通用认证
. . .

保存并关闭文件,然后重新启动 SSH:

sudo systemctl 重启 sshd.service

现在尝试使用不同的终端会话/窗口再次登录服务器。与上次不同,SSH 应该要求您提供验证码。输入它,您将完成登录。尽管没有迹象表明您的 SSH 密钥已被使用,但您的登录尝试使用了两个因素。如果要验证这一点,可以在 SSH 命令后添加 -v(表示详细)。

-v 开关将产生如下输出:

示例 SSH 输出\。 . .
debug1:可以继续的身份验证:publickey
debug1:下一个认证方式:publickey
debug1:提供 RSA 公钥:/Users/sammy/.ssh/id_rsa
debug1:服务器接受密钥:pkalg rsa-sha2-512 blen 279
已通过部分成功的身份验证。
debug1:可以继续的身份验证:密码,键盘交互
debug1:下一个认证方法:keyboard-interactive
验证码:

在输出的最后,您将看到 SSH 在哪里使用您的 SSH 密钥,然后询问验证码。您现在可以使用 SSH 密钥和一次性密码通过 SSH 登录。如果要强制执行所有三种身份验证类型,可以执行下一步。

恭喜,您在通过 SSH 远程登录服务器时成功添加了第二个因素。如果这是您想要的——使用 SSH 密钥和 TOTP 令牌为 SSH 启用 MFA(对于大多数人来说,这是最佳配置)——那么你就完成了。

以下是有关恢复、自动使用等的一些提示和技巧。

步骤 4 — 添加第三个因素(可选)

在第 3 步中,我们在 sshd_config 文件中列出了批准的身份验证类型:

  1. publickey(SSH 密钥)

2.password publickey(密码)

3.keyboard-interactive(验证码)

尽管我们列出了三个不同的因素,但到目前为止我们选择的选项,它们只允许 SSH 密钥和验证码。如果您想拥有所有三个因素(SSH 密钥、密码和验证码),只需一次快速更改即可启用所有三个因素。

打开 PAM sshd 配置文件:

Sudonano /等/ Pam。 d/shd

找到您之前注释掉的行,#@include common-auth,并通过删除 # 字符取消注释该行。保存并关闭文件。现在再次重新启动 SSH:

sudo systemctl 重启 sshd.service

通过启用选项 @include common-auth,PAM 现在除了检查 SSH 密钥并要求输入验证码外,还会提示输入密码,这是我们之前使用的。现在我们可以通过两个不同的渠道(您的计算机获取 SSH 密钥和您的手机获取 TOTP 令牌)使用我们知道的东西(密码)和我们拥有的两种不同类型的东西(SSH 密钥和验证码)。

步骤 5 — 恢复对 Google MFA 的访问(可选)

与您加固和保护的任何系统一样,您将负责管理该安全性。在这种情况下,这意味着不会丢失您的 SSH 密钥或 TOTP 密钥并确保您可以访问您的 TOTP 应用程序。但是,有时会发生一些事情,您可能会失去对需要进入的按键或应用程序的控制。

丢失您的 TOTP 密钥

如果您丢失了 TOTP 密钥,您可以将恢复过程分成几个步骤。第一个是在不知道验证码的情况下重新登录,第二个是找到密钥或重新生成它以进行正常的 MFA 登录。如果您获得一部新手机并且没有将您的秘密转移到新的身份验证器应用程序,这通常会发生。

要在 DigitalOcean Droplet 上丢失 TOTP 密钥后进入,您可以\s[使用虚拟控制台](https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean- console-to-access-your-droplet) 从您的仪表板使用您的用户名和密码登录。这是因为我们只使用 MFA 保护您的用户帐户以进行 SSH 连接。非 ssh 连接,例如控制台登录,不使用 Google Authenticator PAM 模块。

如果您使用的是非 Droplet 系统,那么您有两种重新获得访问权限的选项:

  1. 对系统的控制台(本地/非 ssh)访问(通常是物理的或通过 iDrac 之类的东西)

  2. 有一个未启用 MFA 的其他用户

第二个选项是不太安全的选项,因为使用 MFA 的目的是加强所有 SSH 连接,但如果您无法访问 MFA 身份验证器应用程序,这是一个故障安全选项。

登录后,有两种方法可以帮助获取 TOTP 密码:

1.恢复现有密钥

  1. 生成新密钥

在每个用户的主目录中,密钥和 Google Authenticator 设置都保存在 ~/.google-authenticator 文件中。该文件的第一行是密钥。获取密钥的一种快速方法是执行以下命令,该命令会显示“google-authenticator”文件的第一行(即密钥)。然后,获取该密钥并手动将其输入 TOTP 应用程序:

头 -n 1 /home/sammy/.google_authenticator

恢复现有密钥后,您可以手动将其输入到您的身份验证器应用程序中,也可以在下面的 URL 中填写相关详细信息,然后让 Google 生成一个二维码供您扫描。您需要添加您的用户名、主机名、“.google-authenticator”文件中的密钥,然后添加您为“entry-name-in-auth-app”选择的任何名称,以便轻松识别此密钥与不同的 TOTP 代币:

https://translate.google.com/translate?hl=en&sl=auto&tl=zh&u=https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/username@hostname%3Fsecret%3D16-char-secret%26issuer%3Dentry-name-in-auth-app

如果有不使用现有密钥的原因(例如,无法轻松安全地与受影响的用户共享密钥),您可以直接删除 ~/.google-authenticator 文件。这将允许用户仅使用一个因素再次登录,假设您没有通过删除“nullok”选项来强制执行 MFA。然后他们可以运行“google-authenticator”来生成一个新密钥。

无法访问 TOTP 应用程序

如果您需要登录您的服务器但无权访问您的 TOTP 应用程序来获取您的验证码,您仍然可以使用您第一次创建密钥时显示的恢复码登录,并且是最后五个.google-authenticator 文件的行。请注意,这些恢复代码是一次性使用的。但是,要使其正常工作,您需要在无法访问 TOTP 应用程序时提供您的恢复代码。

步骤 6 — 更改身份验证设置(可选)

如果您想在初始配置后更改 MFA 设置,而不是使用更新的设置生成新配置,您只需编辑 ~/.google-authenticator 文件即可。此文件中的选项以下列方式显示:

.google-authenticator 布局

<密钥>
<选项>
<恢复代码>

此文件中设置的选项在选项部分中有一行;如果您在初始设置期间对特定选项回答“否”,则程序会排除相应选项。

以下是您可以对此文件进行的一些更改:

  • 要启用顺序代码而不是基于时间的代码,请将 " TOTP_AUTH 行更改为 " HOTP_COUNTER 1

  • 要允许多次使用单个代码,请删除行 " DISALLOW_REUSE

  • 要将代码过期窗口延长至 4 分钟,请添加行 " WINDOW_SIZE 17

  • 要禁用多次失败登录(速率限制),请删除行 " RATE_LIMIT 3 30

  • 要更改限速阈值,找到“RATE_LIMIT 3 30”行并调整数字。原文中的“3”表示一段时间内的尝试次数,“30”表示以秒为单位的时间。

  • 要禁用恢复代码,请删除文件底部的五个八位代码。

步骤 7 — 避免对某些帐户进行 MFA(可选)

可能存在单个用户或几个服务帐户(即应用程序使用的帐户,而不是人类使用的帐户)需要 SSH 访问但未启用 MFA 的情况。例如,某些使用 SSH 的应用程序(如某些 FTP 客户端)可能不支持 MFA。如果应用程序无法请求验证码,则请求可能会卡住,直到 SSH 连接超时。

要控制用户使用哪些因素,您可以编辑 /etc/pam.d/sshd 文件。

要为某些帐户允许 MFA,而只允许其他帐户使用 SSH,请确保 /etc/pam.d/sshd 中的以下设置处于活动状态:

/etc/pam.d/sshd

# Secure Shell 服务的 PAM 配置

# 标准的 Un*x 认证。
#@include 通用认证

. . .

# 标准 Un*x 密码更新。
@include 通用密码
需要验证 pam_google_authenticator.so nullok

这里,@include common-auth 被注释掉了,因为密码需要被禁用。如果某些帐户禁用了 MFA,则无法强制执行 MFA,因此请在最后一行保留“nullok”选项。

设置此配置后,请为任何需要 MFA 的用户运行 google-authenticator,不要为只使用 SSH 密钥的用户运行它。

步骤 8 — 使用配置管理自动设置(可选)

许多系统管理员使用 配置管理工具,如 Puppet、Chef 或 Ansible,来管理他们的系统。每当新用户创建帐户时,您都可以使用这样的系统来安装和设置密钥。

google-authenticator 支持命令行开关以在单个非交互式命令中设置所有选项。要查看所有选项,您可以输入“google-authenticator --help”。以下是按照步骤 1 中所述设置所有内容的命令:

谷歌身份验证器 -t -d -f -r 3 -R 30 -w 3

上面提到的选项如下:

  • -t u003d> 基于时间的计数器

  • -d u003d> 禁止令牌重用

  • -f u003d> 强制将设置写入文件而不提示用户

  • -r u003d> 输入正确密码的尝试次数

  • -R u003d> 用户可以尝试输入正确代码的时间(以秒为单位)

  • -w u003d> 一次可以有多少个代码有效(这引用了有效代码的 1:30 分钟 - 4 分钟窗口)

这完全配置了身份验证器,将其保存到文件中,然后输出密钥、二维码和恢复码。 (如果您添加标志 -q,则不会有任何输出。)如果您以自动方式使用此命令,请确保您的脚本捕获密钥和/或恢复代码并将它们提供给用户。

步骤 9 — 强制所有用户进行 MFA(可选)

如果您想对所有用户强制执行 MFA,即使是在第一次登录时,或者不想依赖您的用户生成他们的密钥,有一种快速的方法来处理这个问题。您可以为每个用户使用相同的“.google-authenticator”文件,因为文件中没有存储用户特定的数据。

为此,在创建配置文件后,特权用户需要将该文件复制到每个主目录的根目录,并将其权限更改为相应的用户。您还可以将文件复制到/etc/skel/,在创建时自动将文件复制到每个新用户的主目录。

**警告:**这可能是一个安全风险,因为每个人都共享相同的第二个因素。这意味着,如果它被泄露,就好像每个用户只有一个因素。如果您想使用这种方法,请考虑到这一点。

另一种强制创建用户密钥的方法是使用 bash 脚本:

  1. 创建一个 TOTP 代币,

  2. 提示他们下载 Google Authenticator 应用程序并扫描将显示的 QR 码,并且

  3. 在检查 .google-authenticator 文件是否已经存在后,为他们运行 google-authenticator 应用程序。

为确保脚本在用户登录时运行,您可以将其命名为“.bash_login”并将其放在用户主目录的根目录下。

结论

在本教程中,您通过两个通道(您的计算机 + 您的手机)将两个因素(一个 SSH 密钥 + MFA 令牌)添加到您的服务器。你让外部代理很难通过 SSH 强行进入你的机器,并大大提高了你机器的安全性。

请记住,如果您正在寻求有关保护 SSH 连接的进一步指导,请查看这些 [关于强化 OpenSSH 的教程](https://www.digitalocean.com/community/tutorials/how-to-harden-openssh-on-ubuntu- 20-04) 和 强化 OpenSSH 客户端。

Logo

Ubuntu 社区为您提供最前沿的新闻资讯和知识内容

更多推荐