Skip to content

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 步:验证通过后才能关闭当前会话

reloadrestart 的关键区别: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 收紧、暴力破解防护、账号权限约束、内核参数加固、攻击面最小化。这些让机器更难被攻进来。

但安全不是做一次就完——新漏洞会出现、人员会变动、配置会漂移。被攻进来之后怎么发现、怎么排查入侵痕迹,以及怎么响应新出的漏洞,是下一篇的内容。