464 字
2 分钟
让密码登录“先过 2FA”而私钥秒进:一份不说废话的 SSH 配置笔记

服务器搭好后,我把私钥扔进服务器ssh,一点就能连服务器,爽得像回自家。
Last seen 里偶尔冒出陌生 IP,说明 root 密码还在被爆破。
于是想:能不能让“输密码”的先去 Google Authenticator 报个到,
而用私钥的继续保持丝滑?
踩了两次“keyboard-interactive 找不到”的坑后,终于把最小改动集整理出来,
只改 3 处,给同样不想整行复制粘贴的你。


1 思路:让 PAM 做“安检员”,sshd 只做“引路员”#

登录方式sshd 默认允许PAM 脚本判断结果
私钥 (publickey)检测到 SSH_AUTH_SOCK → 放行免 2FA
密码 (keyboard-interactive)无 auth sock → 走 GA要 2FA

全程不碰 AuthenticationMethods,所以永远不会因为拼写错误把自己锁死


2 改 sshd_config#

Terminal window
sudo nano /etc/ssh/sshd_config

取消注释(或追加):

KbdInteractiveAuthentication yes
ChallengeResponseAuthentication yes

确保下面 3 项保持默认/启用(你的配置已满足):

PubkeyAuthentication yes
PasswordAuthentication yes
UsePAM yes

不需要 AuthenticationMethods 行!
改完 :wqsudo systemctl restart sshd


3 改 PAM 策略#

Terminal window
sudo nano /etc/pam.d/sshd
  1. 在最顶部加入“公钥免检”钩子(先 success 就跳过 GA)
    auth [success=1 default=ignore] pam_exec.so quiet /usr/local/bin/check_ssh_pubkey.sh
  2. 紧接着强制 GA 模块
    auth required pam_google_authenticator.so nullok

nullok 允许用户尚未绑定 GA 时仍可登录(过渡阶段友好)。


4 写免检脚本#

Terminal window
sudo nano /usr/local/bin/check_ssh_pubkey.sh
#!/bin/bash
# 如果环境变量里出现 SSH_AUTH_SOCK 说明是公钥登录
if [ -n "$SSH_AUTH_SOCK" ]; then
exit 0 # 公钥派 → 跳过 2FA
else
exit 1 # 密码派 → 继续走 GA
fi

加执行权限

Terminal window
sudo chmod +x /usr/local/bin/check_ssh_pubkey.sh

5 一分钟自测#

测试场景预期结果
ssh root@ip 有私钥直接进,不提示验证码
ssh -o PreferredAuthentications=password root@ip提示 Verification code:
输错 2FA 码Permission denied

全部通过后,把窗口关掉再开,留一条 SSH 会话别断,防止把自己锁外面。


安心睡觉,爆破党再见 👋

让密码登录“先过 2FA”而私钥秒进:一份不说废话的 SSH 配置笔记
https://blog.sheepmc.top/posts/让密码登录先过-2fa而私钥秒进一份不说废话的-ssh-配置笔记/
作者
LittleSadSheep
发布于
2025-10-12
许可协议
CC BY-NC-SA 4.0
封面
示例歌曲
示例艺术家
封面
示例歌曲
示例艺术家
0:00 / 0:00