Appearance
16|系统安全加固:让机器更难被攻
一台 Linux 放到公网上,几小时内就会被扫描。SSH 被暴力破解、弱口令被撞库、多余的服务暴露攻击面——这些是服务器最常见的入侵入口。
本篇讲怎么加固一台 Linux,让这些攻击更难得手。核心思路是:收紧远程入口、约束账号权限、最小化攻击面。做好这三件事,绝大多数自动化攻击都打不进来。
被攻之后怎么查入侵痕迹、怎么响应漏洞,是下一篇的内容。
一、SSH 加固
SSH 是远程管理的主要入口,也是公网服务器最高频被扫描的目标。SSH 一旦失守,通常意味着整个系统被攻破。SSH 加固优先级最高。
加固顺序很重要
正确的加固顺序:先确保密钥登录可用 → 再禁用密码登录和 root 直接登录 → 最后限制来源 IP 与算法。顺序反了会把自己锁在外面——禁了密码登录才发现密钥没配好,就再也连不上了。
强制要求:改 SSH 配置前,开一个新窗口测试能否登录。所有改动只通过新窗口验证后才能关掉当前会话。一旦新窗口连不上,当前会话还活着,可以立即回滚。
推荐的 sshd_config 配置
bash
# 备份原配置
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
vim /etc/ssh/sshd_config核心加固项:
sshconfig
# === 认证方式 ===
PermitRootLogin no # 禁止 root 直接 SSH 登录
PasswordAuthentication no # 关闭密码认证(必须先确认密钥能用)
PubkeyAuthentication yes # 允许公钥认证
PermitEmptyPasswords no # 禁止空密码登录
# === 行为限制 ===
MaxAuthTries 3 # 单次连接最多 3 次失败尝试
LoginGraceTime 30 # 30 秒内未完成登录,断开连接
ClientAliveInterval 300 # 5 分钟无活动发探测
ClientAliveCountMax 2 # 探测 2 次无回应断开
# === 用户访问控制 ===
AllowUsers deploy admin # 白名单,仅允许这些用户登录
# 或基于组:
# AllowGroups ssh-users
# === 横向移动收紧 ===
AllowAgentForwarding no # 禁用 agent 转发(防止跳板机泄露密钥)
AllowTcpForwarding no # 禁用端口转发(除非业务必需)
X11Forwarding no # 禁用 X11 转发改端口号(Port 22 改成非标端口)只能减少扫描噪音,不是核心安全措施——别以为改了端口就安全了。
改完先 sshd -t 再 reload
这是 SSH 加固保命的核心动作:
bash
# 第 1 步:语法检查,无输出表示通过
sshd -t
# 第 2 步:reload(不会断现有连接)
systemctl reload sshd
# 第 3 步:在另一个终端窗口验证能否新建立 SSH 连接
ssh -v deploy@<服务器IP>
# 第 4 步:验证通过后才能关闭当前会话reload 和 restart 的关键区别:reload 只重读配置,不影响已建立的连接;restart 会断所有现有连接。远程改 SSH 必须用 reload,即使配置有错,当前连接也不会断,有机会回滚。
sshd -t 跳过会出大事——配置里漏个大括号、写错关键字,reload 时 sshd 可能启动失败,新连接全部失败。永远在 reload 前先 -t。
密钥登录
加固后密码登录关了,登录要靠密钥。推荐用 ed25519 算法,比 RSA 短、快、安全:
bash
# 生成密钥对
ssh-keygen -t ed25519 -C "deploy@workstation"
# 上传公钥到服务器
ssh-copy-id deploy@<服务器IP>私钥权限要收好。.ssh 目录和 authorized_keys 权限过宽(group/other 可写),SSH 会拒绝使用密钥:
bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys家目录本身也不能过宽——drwxrwxrwx 的家目录会让 SSH 认为不安全,拒绝密钥认证。
限制来源 IP
如果能确定管理来源的 IP 范围(如办公网出口),用防火墙限制只有这些 IP 能连 SSH:
bash
# 只允许 10.0.0.0/8 访问 SSH 端口
firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=10.0.0.0/8 port port=22 protocol=tcp accept'
firewall-cmd --reload这样即使密钥泄露,外部 IP 也连不上。
二、fail2ban:暴力破解防护
SSH 暴露在公网上,会被大量机器自动尝试密码(即使关了密码登录,这些尝试也会刷日志)。fail2ban 监控登录失败日志,对反复失败的 IP 自动封禁。
bash
# 安装
yum install fail2ban -y # RHEL 系
apt install fail2ban -y # Debian 系
# 配置
cat > /etc/fail2ban/jail.local <<'EOF'
[sshd]
enabled = true
maxretry = 5 # 5 次失败后封禁
bantime = 3600 # 封禁 1 小时
findtime = 600 # 10 分钟内的失败计数
EOF
systemctl enable --now fail2ban查看封禁状态:
bash
fail2ban-client status sshd
# Status for the jail: sshd
# |- Currently banned: 5
# | `- Banned IP list: 1.2.3.4 5.6.7.8 ...手动解封某个 IP:
bash
fail2ban-client set sshd unbanip 1.2.3.4三、账号与 sudo 治理
禁用 root 直接登录
第 1 讲提过,root 权限最大,敲错命令可能删掉整个系统。生产环境里不用 root 直接干活,用普通账号 + sudo 提权。SSH 也禁了 root 直接登录(上一节)。
检查 UID 为 0 的账号
UID 为 0 的账号是 root 级权限,正常应该只有 root 一个:
bash
awk -F: '$3==0 {print $1}' /etc/passwd
# root如果输出里有别的账号,说明被加了后门 root,要立即排查。
sudo 授权要精确
sudo 让普通账号临时获得 root 权限。授权要精确,不能图省事给全权限免密:
bash
# 错误:全权限免密(等于把 root 给出去了)
deploy ALL=(ALL) NOPASSWD: ALL
# 按命令授权,免密只给确实需要的具体动作
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
deploy ALL=(ALL) /usr/bin/systemctl status *需要日志审计的操作(如修改系统配置)要保留密码确认,不能免密。
清理多余账号
人员变动会留下不再使用的账号,这些账号是潜在风险。看长期未登录的账号:
bash
lastlog | awk '$2!="**Never"'离职人员的账号应当及时禁用或删除。给临时账号设过期时间:
bash
# 账号在 2026-12-31 后自动失效
chage -E 2026-12-31 outsourcer四、内核参数加固:sysctl
一些内核参数和网络安全相关,通过 sysctl 调整。配置写在 /etc/sysctl.d/ 下:
bash
# /etc/sysctl.d/99-security.conf
# === 网络层加固 ===
net.ipv4.tcp_syncookies = 1 # 防 SYN flood
net.ipv4.conf.all.send_redirects = 0 # 禁止发送 ICMP 重定向
net.ipv4.conf.all.accept_redirects = 0 # 拒绝 ICMP 重定向
net.ipv4.conf.all.accept_source_route = 0 # 拒绝源路由包
net.ipv4.icmp_echo_ignore_broadcasts = 1 # 忽略广播 ping(防 smurf)
# === 内核行为加固 ===
kernel.kptr_restrict = 2 # 隐藏内核指针,防内核地址泄露
kernel.dmesg_restrict = 1 # 非 root 不能读 dmesg
kernel.sysrq = 0 # 禁用 SysRq 魔术键生效:
bash
sysctl --system # 加载所有 sysctl 配置五、最小化服务暴露面
每多开一个服务,就多一个被攻击的面。看当前监听的端口,关掉不需要的:
bash
# 看监听的端口
ss -lntp
# 找服务对应的 systemd unit
systemctl list-unit-files --state=enabled --type=service
# 禁用并停止不需要的服务
systemctl disable --now avahi-daemon # 例:不需要的 mDNS 服务常见不需要但默认开的:avahi-daemon(mDNS)、cups(打印)、postfix(邮件,除非这台机器真要发邮件)。关掉前确认这台机器确实不用。
加固之后
到这里,主动防御做完了:SSH 收紧、暴力破解防护、账号权限约束、内核参数加固、攻击面最小化。这些让机器更难被攻进来。
但安全不是做一次就完——新漏洞会出现、人员会变动、配置会漂移。被攻进来之后怎么发现、怎么排查入侵痕迹,以及怎么响应新出的漏洞,是下一篇的内容。