前言

双重认证(英语:Two-factor authentication,缩写为2FA),又译为双重验证、双因子认证、双因素认证、二元认证,又称两步骤验证(2-Step Verification,又译两步验证),是一种认证方法,使用两种不同的元素,合并在一起,来确认用户的身份,是多因素验证中的一个特例。

前段时间学校几台服务器被入侵,有Windows和Linux,无一例外都是被SSH和RDP爆破进来然后植入木马。还好这些机子都是内部不能连接外网的,挖矿木马没有和C&C服务器通信起来,没有成功挖矿,但是这件事仍然给我们敲响了警钟。
和师兄在一起交流的时候,突然想到了现在流行的两步验证(2FA),就想着能不能给SSH和RDP上面套一层,在输入密码登录完成之后还需要经过二次认证才能成功访问服务器,想到这里就开始查文章,折腾了几天终于成功解决了这个问题,特写一篇文章分享一下:

安装过程参考了 DigitalOcean 的:https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-ubuntu-16-04


我用一台Ubuntu 18.04 LTS作为测试机来演示。首先我们要把 SSH 配置好,确保常规 SSH 可以成功连接

然后在你的手机上安装Google Authenticator这个应用,AndroidiOS 都有。

安装 Google authenticator

我们需要先更新一下软件包:sudo apt update,然后安装 Google PAM:

$ sudo apt-get install libpam-google-authenticator

安装好后,直接在命令行中运行 google-authenticator

它会提示你是否生成基于时间的 Token,这时候根据你的喜好选择,我这里选择是,输入Y。

此时会出现一张二维码图片,我们这时候打开刚刚下载的身份验证器,点击右下角的加号,选择“扫描条形码”,然后将 SSH 窗口放大,用摄像头扫描出现的二维码,此时就会多出一个账号信息(六位数的动态码),另外记得妥善保存你的Emergency Key

如果成功扫描的话就可跳过此步,如果你无法扫描二维码的话,请点击下方的“输入提供的密钥”


账号名随便输入,不过建议取一个容易记住的名字,“您的密钥”一栏输入二维码下面跟着的那串Your new secret key is后面的内容,“时间选项”里面,如果你在第一步输入了Y,就选择基于时间,否则就选基于计数器,完成后点击添加。

提示Do you want me to update your "/home/wb/.google_authenticator" file? (y/n),输入Y。
接下来提示你是否设置为动态码复用,以防止攻击,当然选Y。

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

接下来我个人推荐第一项选择N,第二项选Y,这样可以防止攻击。

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

配置 SSH

第一步配置完成了,这时候请重新打开一个 SSH 连接,第一个不要关闭,以防止配置错误导致自己也连接不上

用你喜欢的文本编辑器打开/etc/pam.d/sshd,然后将auth required pam_google_authenticator.so nullok添加到文件的尾部。

注意:nullok 的意思是这项验证是可选的,如果你没有TOTP令牌的话,仍然可以使用SSH密码和密钥登录,我们为了保险起见先使用这个,等到配置好了之后就可以去掉了。

接下来打开/etc/ssh/sshd_config,找到ChallengeResponseAuthentication,并将其设置为Yes

然后保存退出,sudo systemctl restart sshd,重启一下 SSH 服务

接下来重新 SSH 连接一下你的服务器,你会发现需要输入额外的验证码才能登录服务器了。



让 SSH 知道 MFA(只使用密码登录可跳过此步)

因为 SSH 密钥会覆盖掉2FA设置,所以用账号密码登录是没有问题的,但是如果你在使用公私钥登录的时候,就不会出现 Google Authenticator 的提醒,所以我们需要做以下操作:

打开 /etc/ssh/sshd_config 文件,加入这行:

AuthenticationMethods publickey,password publickey,keyboard-interactive

然后打开/etc/pam.d/sshd,取消注释#@include common-auth这一行。


保存退出后再次重启 SSH 服务即可,如果正常的话,在使用私钥登录的时候也可以输入密码了。

丢失了令牌怎么办

还记得那几个 Emergency Code吗?


如果在没有令牌的情况下,可以使用这五个 Emergency Code 进行登录,当然这五个Code是一次性的,使用完成后就会失效。

更改身份验证设置

打开 /home/YourName/.google_authenticator文件,你会看到下面的内容:

BWZBHD7TPTI3R3PK52TG6GNBX4
" RATE_LIMIT 3 30 1558529144
" DISALLOW_REUSE 51950963
" TOTP_AUTH
36705104
62558944
24965430
29372119
  • 第一行就是你在扫描二维码或者手动输入的密钥,可以进行更换。
  • RATE_LIMIT 为限制多次登录的次数,也可以修改
  • 要允许多次使用单个代码,请删除DISALLOW_REUSE这一行
  • TOTP_AUTH对应的是上面的"基于时间",如果你要改成“基于计数器”,请将TOTP_AUTH换成HOTP_COUNTER 1
  • 下面的几行就是一次性恢复代码了,你可以自己添加,也可以全部删除掉。

点击收藏 | 1 关注 | 2
登录 后跟帖