SSH 安全
SSH 是远程管理 Linux 服务器的核心工具,也是攻击者最常针对的目标之一。本文介绍如何在 Ubuntu 26.04 中全面加固 SSH 安全。
密钥认证
生成 SSH 密钥对
在客户端(你的本地电脑)上生成密钥:
# 生成 Ed25519 密钥(推荐,更安全更快)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 如果需要兼容旧系统,使用 RSA 4096 位
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# 生成时会提示:
# Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):
# 强烈建议设置密码短语(passphrase)将公钥部署到服务器
# 方法一:使用 ssh-copy-id(推荐)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# 方法二:手动复制
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# 方法三:手动操作
# 在服务器上:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
# 粘贴公钥内容
chmod 600 ~/.ssh/authorized_keys测试密钥登录
# 使用密钥登录
ssh -i ~/.ssh/id_ed25519 user@server
# 如果已配置为默认密钥,直接登录
ssh user@serverSSH Agent 管理密钥
# 启动 SSH Agent
eval "$(ssh-agent -s)"
# 添加密钥到 Agent(输入一次密码短语后即缓存)
ssh-add ~/.ssh/id_ed25519
# 列出已加载的密钥
ssh-add -l
# 删除所有缓存的密钥
ssh-add -DWarning
修改 SSH 配置前,请确保密钥认证已测试通过,并保持当前 SSH 会话不要关闭。在新终端验证能正常登录后再关闭旧连接,否则配置错误可能导致你被永久锁在服务器外。
加固 SSH 服务配置
编辑 SSH 服务端配置文件:
sudo nano /etc/ssh/sshd_config禁用密码登录
确认密钥登录正常后再禁用密码登录:
# 禁用密码认证
PasswordAuthentication no
# 禁用空密码
PermitEmptyPasswords no
# 禁用键盘交互认证
KbdInteractiveAuthentication no禁用 root 登录
# 完全禁止 root 通过 SSH 登录
PermitRootLogin no
# 或仅允许使用密钥登录 root(不推荐)
# PermitRootLogin prohibit-password修改默认端口
# 使用非标准端口(减少自动扫描)
Port 2222修改端口后要更新防火墙规则:
sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp限制登录用户
# 只允许特定用户登录
AllowUsers admin deployer
# 只允许特定群组登录
AllowGroups sshusers
# 拒绝特定用户
DenyUsers guest test其他安全配置
# 限制认证尝试次数
MaxAuthTries 3
# 限制同时认证的连接数
MaxStartups 3:50:10
# 会话超时(300 秒无活动断开)
ClientAliveInterval 300
ClientAliveCountMax 2
# 禁用 X11 转发(服务器通常不需要)
X11Forwarding no
# 禁用 Agent 转发(除非确实需要)
AllowAgentForwarding no
# 禁用 TCP 转发(除非确实需要)
AllowTcpForwarding no
# 使用强加密算法
# 注意:OpenSSH 10.2(26.04)默认 KEX 已首选后量子算法 mlkem768x25519-sha256,
# 建议不要覆盖 KexAlgorithms——硬编码一份列表会冻结算法集合,
# 反而可能在未来移除新加入的后量子默认算法。请沿用安全默认值。
#
# 仅在排障、需与旧客户端临时互通时才覆盖,且务必把后量子算法放在首位:
# KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256@libssh.org,curve25519-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# 显示登录横幅
Banner /etc/ssh/banner.txt
# 登录宽限时间
LoginGraceTime 30应用配置
# 检查配置语法
sudo sshd -t
# 重启 SSH 服务(Ubuntu 单元名为 ssh.service,sshd 只是别名)
sudo systemctl restart ssh
# 注意:26.04 默认 ssh 经 socket activation 监听端口,
# 修改端口后需重载 socket 单元才能生效:
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
# 重要:在新的终端窗口测试连接,不要关闭当前连接!
ssh -p 2222 user@serverfail2ban 防护
fail2ban 监控日志文件,自动封禁多次登录失败的 IP 地址。
安装与配置
# 安装
sudo apt install fail2ban
# 启动并设置开机自启
sudo systemctl enable --now fail2ban创建本地配置
不要直接修改 /etc/fail2ban/jail.conf,而是创建本地配置:
sudo nano /etc/fail2ban/jail.local[DEFAULT]
# 封禁时间(秒)
bantime = 3600
# 检测时间窗口(秒)
findtime = 600
# 最大失败次数
maxretry = 3
# 封禁动作
banaction = ufw
# 忽略的 IP(白名单)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
# 邮件通知
# destemail = admin@example.com
# sendername = Fail2Ban
# mta = sendmail
# action = %(action_mwl)s
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600管理 fail2ban
# 查看状态
sudo fail2ban-client status
# 查看 SSH jail 状态
sudo fail2ban-client status sshd
# 查看被封禁的 IP
sudo fail2ban-client status sshd | grep "Banned IP"
# 手动封禁 IP
sudo fail2ban-client set sshd banip 203.0.113.50
# 手动解封 IP
sudo fail2ban-client set sshd unbanip 203.0.113.50
# 查看 fail2ban 日志
sudo tail -f /var/log/fail2ban.log
# 重新加载配置
sudo fail2ban-client reload高级 fail2ban 配置
保护其他服务:
# Nginx 认证保护
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
# Nginx 恶意请求
[nginx-botsearch]
enabled = true
filter = nginx-botsearch
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2SSH 客户端配置
在客户端创建 SSH 配置文件简化连接:
nano ~/.ssh/config# 全局设置
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
# 生产服务器
Host prod
HostName 203.0.113.10
User admin
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
# 跳板机
Host bastion
HostName 203.0.113.20
User jump
Port 2222
IdentityFile ~/.ssh/id_ed25519
# 通过跳板机连接内网服务器
Host internal
HostName 10.0.1.50
User admin
ProxyJump bastion
IdentityFile ~/.ssh/id_ed25519使用配置后的简化连接:
ssh prod
ssh internal双因素认证
为 SSH 添加 Google Authenticator 双因素认证:
# 安装
sudo apt install libpam-google-authenticator
# 每个用户运行初始化
google-authenticator
# 按提示完成配置,扫描二维码
# 配置 PAM
sudo nano /etc/pam.d/sshd
# 添加:
# auth required pam_google_authenticator.so
# 配置 SSH
sudo nano /etc/ssh/sshd_config
# 设置:
# AuthenticationMethods publickey,keyboard-interactive
# KbdInteractiveAuthentication yes
sudo systemctl restart sshOpenSSH 后量子密钥交换
Ubuntu 26.04 自带 OpenSSH 10.2,默认密钥交换算法首选 后量子混合方案 mlkem768x25519-sha256(ML-KEM-768 与 X25519 混合),可抵御”先采集后解密”(harvest-now-decrypt-later)攻击。
# 确认本机 OpenSSH 支持的 KEX 算法(应包含 mlkem768x25519-sha256)
ssh -Q kex
# 连接时查看实际协商的 KEX 算法
ssh -v user@server 2>&1 | grep "kex:"Note
后量子 KEX 仅在双方都支持时才会启用。与较旧客户端/服务器(OpenSSH 9.0 以下)互通时会自动回退到经典算法 curve25519-sha256,无需手动配置。除非确有兼容性问题,否则不建议覆盖 KexAlgorithms 默认值,以免意外移除后量子保护。
监控与审计
# 查看登录成功记录
last -n 20
# 查看登录失败记录
lastb -n 20
# 查看 SSH 认证日志
journalctl -u ssh.service --since today | grep -E "Accepted|Failed"
# 统计登录失败的 IP
journalctl -u ssh.service | grep "Failed" | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# 查看当前 SSH 连接
who
w
ss -tnp | grep :22安全检查清单
在应用更改前,确认以下检查项:
- 密钥认证已配置且测试通过
- 有一个备用的访问方式(控制台访问、其他用户等)
- 防火墙已更新对应端口规则
- fail2ban 白名单中包含了你的常用 IP
- 在新终端测试连接成功后再关闭旧连接
- SSH 配置语法已通过
sshd -t验证
Last updated on