SSH是服务器远程管理的核心通道,也是攻击者最常扫描的目标。仅依赖密码或密钥认证存在被暴力破解和密钥泄露的风险。本文介绍SSH双因素认证(2FA)的完整配置流程,以及fail2ban入侵防护系统的部署方法,构建多层次的SSH访问安全防护体系。
SSH安全基线检查与配置加固
在部署双因素认证前,先完成基础SSH安全配置。编辑/etc/ssh/sshd_config:
# 禁用root直接登录
PermitRootLogin no
# 限制登录用户
AllowUsers deploy admin
# 修改默认端口(可选但推荐)
Port 58222
# 禁用空密码
PermitEmptyPasswords no
# 限制认证重试次数
MaxAuthTries 3
# 登录超时
LoginGraceTime 30
# 禁用X11转发(非必要)
X11Forwarding no
# 空闲超时自动断开
ClientAliveInterval 300
ClientAliveCountMax 2
配置完成后验证语法并重启服务:
sshd -t # 语法检查
systemctl restart sshd # 重启SSH服务
注意:修改SSH端口后,务必保持当前会话不断开,新开终端验证新端口可连接后再关闭旧会话。
Google Authenticator PAM模块安装与配置
使用google-authenticator-libpam实现TOTP(基于时间的一次性密码)双因素认证:
# CentOS/RHEL
yum install -y google-authenticator
# Ubuntu/Debian
apt install -y libpam-google-authenticator
为需要双因素认证的用户生成密钥:
su - deploy
google-authenticator
# 交互式配置选择:
# 1. 是否基于时间令牌? -> y
# 2. 是否更新~/.google_authenticator文件? -> y
# 3. 是否禁止同一令牌多次使用? -> y
# 4. 是否延长时间窗口? -> n(默认30秒即可)
# 5. 是否启用速率限制? -> y
执行后会输出一个二维码和5组紧急备用码。用手机上的Google Authenticator或FreeOTP应用扫码绑定,之后登录时需要输入6位动态验证码。
PAM与SSH集成配置
编辑PAM配置文件,在SSH认证流程中加入Google Authenticator验证:
# /etc/pam.d/sshd 末尾添加
auth required pam_google_authenticator.so nullok
# 注意:nullok参数表示未配置2FA的用户仍可登录
# 生产环境建议移除nullok确保所有用户强制启用
同时修改SSH配置启用ChallengeResponse认证:
# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
KbdInteractiveAuthentication yes
UsePAM yes
# 如果使用密钥+2FA组合认证:
AuthenticationMethods publickey,keyboard-interactive
重启SSH服务生效:
systemctl restart sshd
此时SSH登录流程变为:先验证SSH密钥(或密码),再要求输入6位TOTP验证码。两个因素都通过才能登录。
fail2ban入侵防护系统部署
fail2ban通过监控SSH日志,自动封禁多次认证失败的IP地址:
# 安装
yum install -y fail2ban # CentOS
apt install -y fail2ban # Ubuntu
# 创建本地配置(不要直接修改jail.conf)
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 86400
findtime = 600
maxretry = 3
banaction = firewallcmd-ipset # CentOS用firewalld
# banaction = iptables-multiport # Ubuntu用iptables
[sshd]
enabled = true
port = 58222
logpath = %(sshd_log)s
backend = systemd
maxretry = 3
bantime = 86400
EOF
启动并设置开机自启:
systemctl enable fail2ban
systemctl start fail2ban
# 查看SSH防护状态
fail2ban-client status sshd
# 输出示例:
# Status for the jail: sshd
# |- Filter
# | |- Currently failed: 2
# | |- Total failed: 47
# | `- File list: /var/log/secure
# `- Actions
# |- Currently banned: 5
# |- Total banned: 23
# `- Banned IP list: 192.168.1.100 10.0.0.5 ...
fail2ban自定义规则与告警配置
针对特定攻击模式自定义failregex规则,提升检测精度:
# /etc/fail2ban/filter.d/sshd-aggressive.local
[INCLUDES]
before = common.conf
[Definition]
_daemon = sshd
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failed|error) for .* from ( via \S+)?\s*$
^%(__prefix_line)s(?:error: )?Failed(?: password| publickey) for .* from ( port \d+)?(?: ssh\d*)?( preauth)?\s*$
^%(__prefix_line)sDisconnected from authenticating user .* port \d+ \[preauth\]\s*$
ignoreregex =
配置邮件告警,当有IP被封禁时发送通知:
# /etc/fail2ban/jail.local [DEFAULT] section
destemail = admin@yunthe.com
sender = fail2ban@yunthe.com
mta = sendmail
action = %(action_)s
%(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", sender="%(sender)s", chain="%(chain)s"]
运维巡检与常见问题处理
2FA时间不同步导致验证失败:确保服务器NTP时间同步正常,TOTP依赖准确时间:timedatectl set-ntp true,执行chronyc tracking确认时间偏差小于1秒。
误封合法IP:使用fail2ban-client set sshd unbanip 1.2.3.4手动解封。可将可信IP加入ignoreip白名单:ignoreip = 127.0.0.1/8 192.168.0.0/16 10.0.0.0/8。
2FA设备丢失:使用紧急备用码登录,或由root用户删除~/.google_authenticator文件后重新配置。建议将备用码妥善保存至密码管理器。
firewalld规则冲突:fail2ban使用ipset管理封禁IP,确认firewalld允许ipset:firewall-cmd --permanent --add-rich-rule='rule source ipset=fail2ban-sshd drop',重载后生效。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/ssh-shuang-yin-su-ren-zheng-pei-zhi-yu-fail2ban-ru-qin-fang/