前言
一台公网服务器上线几小时,/var/log/secure 里就会堆满爆破记录。SSH 是大门,这篇是一份可以直接照抄的加固清单。
一、先看看有多少人在撬门
# 今天的爆破尝试
grep "Failed password" /var/log/secure | wc -l
# 谁在撬(来源 IP Top10)
grep "Failed password" /var/log/secure \
| grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn | head
# 用哪些用户名试
grep "Failed password" /var/log/secure | grep -oE "invalid user \S+" | sort | uniq -c | sort -rn | head
看完这些数字,你会立刻想做下面所有事。
二、第一优先级:密钥登录,禁用密码
1. 生成密钥对(在自己电脑上)
ssh-keygen -t ed25519 -C "zy@laptop"
# 一路回车( passphrase 可留空, 更安全是设一个)
# 生成: ~/.ssh/id_ed25519(私钥, 绝不外传) + id_ed25519.pub(公钥)
2. 公钥上服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@1.2.3.4
# 或手动: 把公钥内容追加到服务器 ~/.ssh/authorized_keys
3. 验证密钥能登录后,再关闭密码
vim /etc/ssh/sshd_config
三、sshd_config 加固清单
# ===== /etc/ssh/sshd_config 关键项 =====
# 1. 禁用 root 直接登录(先建好普通用户 + sudo!)
PermitRootLogin no
# 2. 禁止密码认证(前提: 密钥已验证可用!)
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
# 3. 只允许特定用户/组登录
AllowUsers zy deploy
# AllowGroups ops
# 4. 改默认端口(挡掉无脑扫描, 防不住针对性攻击)
Port 2222
# 5. 空闲超时自动踢下线
ClientAliveInterval 300
ClientAliveCountMax 2
# 6. 限制登录尝试与认证时限
MaxAuthTries 3
LoginGraceTime 30
# 7. 不用到的认证方式全关掉
GSSAPIAuthentication no
UseDNS no # 还能加快登录速度
# 生效前先验证语法!
sshd -t
# 用另一个终端保持现有连接不动, 新开连接测试(保命操作!)
systemctl restart sshd
⚠️ 顺序就是安全:先建普通用户并配好 sudo → 部署密钥 → 验证密钥登录 → 才能改 sshd_config 重启。反着来就是把自己锁在门外。
# 建用户 + sudo(wheel 组)
useradd -m -G wheel zy
passwd zy
改了端口后记得放行防火墙和安全组:
firewall-cmd --add-port=2222/tcp --permanent && firewall-cmd --reload
四、fail2ban:自动拉黑爆破者
dnf install -y epel-release && dnf install -y fail2ban
cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime = 3600 # 封禁 1 小时
findtime = 600 # 10 分钟窗口内
maxretry = 5 # 失败 5 次就封
banaction = firewallcmd-rich-rules
[sshd]
enabled = true
port = 2222 # 与 sshd 端口一致
EOF
systemctl enable --now fail2ban
# 查看战果
fail2ban-client status sshd
# 目前封禁列表、总攻击次数一目了然
fail2ban-client set sshd unbanip 1.2.3.4 # 手动解封
五、进阶招式
只允许证书 + 双因素(如 Google Authenticator)
dnf install -y google-authenticator
google-authenticator # 扫码绑定, 生成 ~/.google_authenticator
# sshd_config 追加:
# AuthenticationMethods publickey,keyboard-interactive
# ChallengeResponseAuthentication yes
跳板机模式(团队标准姿势)
所有服务器只监听内网/白名单 IP,外部统一走一台跳板机:
# 服务器 sshd_config
ListenAddress 10.0.0.5 # 只听内网
# 或者防火墙层面只放跳板机 IP
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.10 port port=2222 protocol=tcp accept' --permanent
# 客户端 ~/.ssh/config 简化跳板
Host web01
HostName 10.0.1.11
User zy
Port 2222
ProxyJump bastion.example.com # 一条命令直达: ssh web01
免密自动化(CI/CD 部署用)
# 服务器侧限制自动化密钥的能力(只能跑特定命令)
# ~/.ssh/authorized_keys:
command="/opt/deploy/pull.sh",no-pty,no-port-forwarding ssh-ed25519 AAAA... deploy@ci
六、加固核对清单
- 普通用户 + sudo 已就绪,不再日常使用 root
- ed25519 密钥登录验证通过
-
PasswordAuthentication no -
PermitRootLogin no -
AllowUsers白名单 - 改默认端口(同步防火墙 + 安全组)
-
sshd -t通过后才 restart,且保留旧会话保底 - fail2ban 运行中,
status sshd有数据 - 客户端
~/.ssh/config配好 ProxyJump
小结
安全是分层洋葱:密钥 > 禁密码 > 白名单 > 改端口 > fail2ban > 跳板机。每一层都在提高攻击成本。而加固的铁律是:每改一步,先验证,再进行下一步——把自己锁在门外是新手最贵的一课。
本文是「安全」系列第 1 篇。