Linux 服务器上线前的 12 项安全加固

举报
yd_213781742 发表于 2026/11/02 16:15:05 2026/11/02
【摘要】 按优先级列出服务器上线前必做的 12 项加固:端口梳理、SSH 禁 root 与密钥登录、账号最小化、防火墙默认拒绝、补丁策略、时间同步、日志审计、文件权限体检、内核参数、fail2ban、可恢复的备份,附一张上线检查清单。

一、为什么"能跑就行"不够

一台刚装好的 Linux 服务器,暴露到公网后平均能撑多久?

不用猜。看 /var/log/secure 或 auth.log 就知道——几小时内就会有成千上万次 SSH 爆破尝试,来自全球各地的扫描器。它们不需要针对你,只是在批量找"root + 弱密码"这种软柿子。

所以上线前的加固不是"等出事再说"的事,而是一份必须走完的清单。下面 12 项按优先级排列,前 6 项做完能挡掉绝大多数自动化攻击。

二、第 1 项:先搞清楚开了哪些门

动手改配置之前,先摸清现状:

# 哪些端口在监听(重点看 0.0.0.0 和 :: 的)
ss -lntup

# 哪些服务开机自启
systemctl list-unit-files --type=service --state=enabled

# 最近谁登录过
last -n 20
lastb -n 20    # 失败记录

判断标准很简单:每一条 0.0.0.0:PORT 都要能说出理由。说不出来的,要么关掉,要么改成只监听 127.0.0.1。

# 关掉不需要的服务
systemctl disable --now cups        # 打印服务
systemctl disable --now avahi-daemon # 局域网发现

三、第 2 项:SSH 加固(收益最大)

SSH 是攻击面最集中的地方,也是加固收益最高的一处。编辑 /etc/ssh/sshd_config:

# 禁止 root 直接登录
PermitRootLogin no

# 只允许密钥认证,关掉密码登录
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no

# 限制可登录用户
AllowUsers deploy ops

# 减少认证尝试次数与时间
MaxAuthTries 3
LoginGraceTime 20

# 空闲超时
ClientAliveInterval 300
ClientAliveCountMax 2

改完先验证再重启,这一步错了会把自己锁在外面:

sshd -t                       # 语法检查
# 另开一个终端保持连接,再执行:
systemctl reload sshd
# 用新终端测试能登录后,再关掉旧连接

顺序很重要:先配好密钥登录并验证成功,再关 PasswordAuthentication。反过来做,你就只能去控制台救援了。

四、第 3 项:账号最小化

# 找出可登录的账号(shell 不是 nologin/false 的)
awk -F: '($7 !~ /(nologin|false|sync|shutdown|halt)$/) {print $1, $3, $7}' /etc/passwd

# 锁定不需要的账号
usermod -L games

# 检查空密码账号(应该没有任何输出)
awk -F: '($2 == "") {print $1}' /etc/shadow

sudo 权限也要收:

# 只允许特定命令,而不是 ALL
echo "deploy ALL=(root) NOPASSWD: /bin/systemctl restart myapp" > /etc/sudoers.d/deploy
chmod 440 /etc/sudoers.d/deploy
visudo -c      # 校验语法

NOPASSWD: ALL 写起来省事,但等于给了第二个 root。能限定到具体命令就别偷懒。

五、第 4 项:防火墙默认拒绝

原则只有一条:默认 DROP,按需放行。

firewalld:

firewall-cmd --permanent --set-default-zone=public
firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload
firewall-cmd --list-all

ufw:

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 443/tcp
ufw enable
ufw status verbose

云服务器别忘了安全组。主机防火墙和安全组是两层,任何一层配错都可能导致"本地通、外网不通",排查时两边都要看。

六、第 5 项:补丁策略

漏洞利用大多数打的是没打补丁的已知漏洞。

# Debian/Ubuntu
apt update && apt list --upgradable
unattended-upgrade --dry-run -d

# RHEL/CentOS
dnf check-update
dnf updateinfo list security

建议开启自动安全更新(只装安全补丁,不升大版本):

# Ubuntu
dpkg-reconfigure --priority=low unattended-upgrades

# RHEL 系
dnf install -y dnf-automatic
sed -i 's/^apply_updates.*/apply_updates = yes/' /etc/dnf/automatic.conf
systemctl enable --now dnf-automatic.timer

内核更新后需要重启才生效,记得安排窗口,别让机器"打了补丁但没生效"跑上半年。

七、第 6 项:时间同步

时间不准会带来一堆诡异问题:TLS 证书校验失败、日志时间线错乱、分布式锁失效、TOTP 验证码永远对不上。

timedatectl                       # 看当前状态
timedatectl set-timezone Asia/Shanghai

# 启用 chrony
systemctl enable --now chronyd
chronyc sources -v
chronyc tracking

System clock synchronized: yes 才算正常。

八、第 7 项:日志与审计

出事后最怕的是"没有日志"。

# 确认 journald 是持久化存储,而不是只存内存
grep -E "^Storage" /etc/systemd/journald.conf
# 改成 Storage=persistent 后
systemctl restart systemd-journald

# 限制日志占用,防止撑爆磁盘
journalctl --vacuum-size=500M

关键文件单独留档:

# 记录当前所有关键文件的校验和,便于日后比对是否被篡改
rpm -Va > /root/baseline-rpm.txt 2>&1        # RHEL 系
debsums -c > /root/baseline-debsums.txt 2>&1 # Debian 系

需要合规审计的话再上 auditd,监控敏感文件的读写:

auditctl -w /etc/passwd -p wa -k identity
auditctl -w /etc/sudoers -p wa -k privilege

九、第 8 项:文件权限体检

# 全局可写的文件(排除 /tmp /proc /sys)
find / -xdev -type f -perm -0002 \
  ! -path "/tmp/*" ! -path "/var/tmp/*" ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null

# 无主文件(属主已被删除)
find / -xdev \( -nouser -o -nogroup \) 2>/dev/null | head -20

# 关键文件权限
ls -l /etc/passwd /etc/shadow /etc/sudoers
# 期望:passwd 644,shadow 600 或 640,sudoers 440

.ssh 目录权限错了会导致密钥登录莫名失败:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

十、第 9 项:内核与网络参数

/etc/sysctl.d/99-hardening.conf:

# 禁止 IP 转发(除非这台机器是网关/跑容器)
net.ipv4.ip_forward = 0

# 关闭 ICMP 重定向,防路由劫持
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

# 开启 SYN Cookie,缓解 SYN Flood
net.ipv4.tcp_syncookies = 1

# 记录伪造源地址的包
net.ipv4.conf.all.log_martians = 1

# 忽略 ICMP 广播
net.ipv4.icmp_echo_ignore_broadcasts = 1
sysctl --system      # 生效并校验

注意:如果这台机器要跑 Docker,ip_forward = 0 会让容器上不了网。跑容器的机器请保留为 1。

十一、第 10 项:爆破防护

即使关了密码登录,日志也会被刷满,不如直接挡掉:

# fail2ban:连续失败 N 次就封 IP
apt install -y fail2ban        # 或 dnf install -y fail2ban

cat > /etc/fail2ban/jail.local <<'EOF'
[sshd]
enabled = true
maxretry = 5
findtime = 10m
bantime  = 1h
EOF

systemctl enable --now fail2ban
fail2ban-client status sshd

bantime = 1h 对持续扫描的 IP 效果有限,可以调成 1d 甚至 1w。

十二、第 11 项:备份要能恢复

没验证过的备份不算备份。

# 备份脚本示例:数据库 + 配置
mysqldump --single-transaction --all-databases | gzip > /backup/db-$(date +%F).sql.gz
tar czf /backup/etc-$(date +%F).tar.gz /etc

# 定期检查备份是否可读
gzip -t /backup/db-*.sql.gz && echo "OK"

三条底线:

  1. 异地:备份不能和源数据在同一块盘上;
  2. 保留多份:至少保留 7 天日备 + 4 周周备;
  3. 定期演练:每季度真的恢复一次,否则你不知道备份是不是坏的。

十三、第 12 项:上线检查清单

把上面的内容固化成一张表,每次上线照着走:

# 检查项 命令/验证方式 通过标准
1 监听端口 ss -lntup 每个端口都有明确用途
2 SSH `sshd -T \ grep -E "permitrootlogin\ passwordauth"` 均为 no
3 可登录账号 awk -F: '$7!~/nologin/' /etc/passwd 只有预期账号
4 防火墙 firewall-cmd --list-all 默认拒绝,仅放行必要端口
5 补丁 apt list --upgradable 无安全更新待装
6 时间 timedatectl 已同步
7 日志 journalctl --disk-usage 持久化且容量受控
8 权限 ls -l /etc/shadow 600 或 640
9 内核参数 sysctl net.ipv4.tcp_syncookies = 1
10 爆破防护 fail2ban-client status sshd 运行中
11 备份 ls -lh /backup 有近期备份且校验通过
12 监控 探针/告警 能收到测试告警

十四、小结

这 12 项不是"做完一次就永久有效"的。真实的运维节奏是:

  • 上线前:全套走一遍;
  • 每周:看补丁、看日志异常、看备份;
  • 每季度:复核账号权限、演练恢复;
  • 变更后:重新核对端口和防火墙。

加固的本质不是把系统改成"谁都进不来",而是让每一个入口都是你有意留下的。凡是你说不出为什么开着的端口、账号、权限,都该关掉。

下一篇会讲 systemd 怎么把服务托管做对——那是上线之后马上要用到的。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。