这是《Linux 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 SSH 是 Linux 生产环境的主要入口。治理 SSH 的目标是:只有可信来源能连、只有授权用户能登录、登录后操作可追踪、异常登录可发现、密钥可轮换。
22.1 SSH 基础
连接:
ssh -i ~/.ssh/id_ed25519 app@192.0.2.10
ssh -J bastion@203.0.113.10 app@192.0.2.20
配置:
~/.ssh/config
示例:
Host web-prod
HostName 192.0.2.10
User app
IdentityFile ~/.ssh/id_ed25519
ProxyJump bastion.example.internal
ServerAliveInterval 30
ServerAliveCountMax 3
文件:
| 文件 | 用途 |
|---|---|
~/.ssh/id_ed25519 |
私钥 |
~/.ssh/id_ed25519.pub |
公钥 |
~/.ssh/authorized_keys |
服务器授权公钥 |
~/.ssh/known_hosts |
已知主机 |
~/.ssh/config |
客户端配置 |
22.2 密钥管理
生成:
ssh-keygen -t ed25519 -a 100 -C "dev01@laptop"
上传公钥:
ssh-copy-id -i ~/.ssh/id_ed25519.pub app@192.0.2.10
权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
轮换:
- 生成新密钥;
- 添加新公钥;
- 验证登录;
- 删除旧公钥;
- 记录变更;
- 发现泄露立即撤销。
22.3 sshd 配置
查看:
sudo sshd -T
sudo systemctl status sshd
常见配置:
Port 22
AddressFamily any
ListenAddress 0.0.0.0
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 10
LoginGraceTime 30
AllowGroups ssh-users
X11Forwarding no
AllowTcpForwarding yes
ClientAliveInterval 300
ClientAliveCountMax 2
不同发行版服务名可能是 ssh 或 sshd。
修改流程:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F-%H%M)
sudo vim /etc/ssh/sshd_config
sudo sshd -t
sudo systemctl reload sshd
严禁关闭现有会话后直接改配置。应保留一个已登录会话,并用新终端验证。
22.4 限制来源
防火墙:
sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="22" protocol="tcp" accept'
云安全组应只允许堡垒机或办公出口访问 SSH,不建议 0.0.0.0/0 开放 22。
hosts.allow / deny 在不同发行版支持情况不同,现代系统更常用防火墙、云安全组或 fail2ban。
22.5 多因素认证
常见方式:
| 方式 | 特点 |
|---|---|
| SSH 密钥 + TOTP | 本机策略 |
| 跳板机 + SSO / MFA | 集中身份 |
| 硬件密钥 FIDO2 | 安全性强 |
| 云平台临时证书 | 可控生命周期 |
高权限账号、生产变更入口和特权操作必须具备第二因素。
22.6 跳板机模型
User
-> Bastion / MFA
-> SSH key / short-lived cert
-> Production host
-> sudo command allowlist
-> audit log
建议:
- 生产主机不直接暴露公网;
- 按环境划分跳板机;
- 登录身份与业务身份区分;
- 会话录像;
- 文件传输受控;
- 定期审计账号。
22.7 sudo 审计
授权:
ops01 ALL=(app) /opt/app/bin/deploy.sh
dba01 ALL=(mysql) /usr/bin/mysqladmin
日志:
sudo journalctl -t sudo --since today
sudo grep sudo /var/log/auth.log
sudo grep sudo /var/log/secure
要求:
- 命令路径绝对;
- 限制参数;
- 不使用
NOPASSWD: ALL; - 定期回收;
- 与工单关联。
22.8 会话审计
命令记录:
history
fc -l -100
审计增强:
| 方案 | 说明 |
|---|---|
| auditd execve | 记录命令执行 |
| syslog / journald | 集中系统日志 |
| 堡垒机会话录像 | 可回放 |
| sshd ForceCommand | 强制包装命令 |
| rootsh / sudo log | 特权操作记录 |
方案要防止普通用户关闭。审计日志集中发送到独立系统。
22.9 异常登录排查
last -a
lastb | head -50
who
journalctl -u ssh --since '24 hours ago'
grep 'Accepted publickey' /var/log/auth.log
grep 'Failed password' /var/log/secure
关注:
| 现象 | 风险 |
|---|---|
| 深夜陌生 IP 登录 | 可能入侵 |
| 新 authorized_keys | 持久化 |
| 大量失败后成功 | 爆破成功 |
| 未知用户创建 | 权限提升 |
| sshd 配置被改 | 后门 |
| 日志中断 | 痕迹清理 |
应急:
- 隔离主机;
- 禁用异常 key;
- 锁定账号;
- 保留内存和磁盘证据;
- 排查横向移动;
- 轮换相关凭据;
- 按安全事件流程通知。
22.10 SSH 故障排查
ssh -vvv app@192.0.2.10
sudo journalctl -u ssh -n 200
sudo sshd -T | grep -Ei 'permitroot|password|pubkey|allowgroups'
客户端:
ls -l ~/.ssh
ssh-keygen -y -f ~/.ssh/id_ed25519
nc -vz 192.0.2.10 22
常见问题:
- 私钥权限过宽;
- authorized_keys 权限错误;
- 用户 home 权限过宽;
- AllowGroups 未包含用户;
- 密码认证被禁;
- 账号锁定或 nologin;
- PAM 配置错误;
- 防火墙阻断。
本章小结
SSH 治理应从入口、身份、密钥、授权和审计五方面入手。生产环境使用密钥或短期证书,禁用 root 和密码登录,只允许可信来源访问,并把 sudo 与会话日志集中保存。修改 sshd 时必须保留现有会话并校验配置。
思考题
- 修改 sshd 时为什么要保留现有会话?
- 如何安全轮换 SSH key?
- 如何设计跳板机与生产主机访问链路?
- 哪些 SSH 异常日志需要告警?
- 如何把 sudo 操作和工单关联?