Linux 服务器安全加固:从 SSH 到防火墙的纵深防御

一台新服务器上线前,安全加固做到位能挡掉九成自动化攻击。这篇文章覆盖 SSH 密钥登录、Fail2Ban 封暴破、防火墙基线、自动安全更新与 lynis 审计,给你一套可照做的加固清单。

把一台新服务器直接暴露在公网,等于在闹市放了一台没锁门的保险柜。脚本小子们用自动化工具全天候扫描 22 端口、试弱密码、找漏洞。好消息是,只要做几件低成本的事,就能挡掉绝大多数自动化攻击。这篇文章给你一套"纵深防御"清单:SSH 加固打头阵,Fail2Ban 封暴破,防火墙收口,自动更新堵漏洞,最后用 lynis 做个安全体检。照着做一遍,服务器的安全水位立刻不同。

一、SSH 加固:密钥、禁 root、关密码

SSH 是第一道防线。先建一个普通用户并加 sudo,再用 ssh-keygen -t ed25519 生成本地密钥对(ed25519 比 RSA 更短更安全),ssh-copy-id 把公钥推上去。然后改 /etc/ssh/sshd_config:PermitRootLogin no(禁 root 直登)、PasswordAuthentication no(关密码,只认密钥)、MaxAuthTries 3(限制尝试次数)。改完务必 sshd -t 校验语法,并在保留活跃会话的前提下重启 sshd——千万别把自己锁门外。改端口到非 22 能减少一大半噪音日志,但记得同步防火墙。

sudo adduser deploy
sudo usermod -aG sudo deploy
ssh-keygen -t ed25519
ssh-copy-id deploy@server_ip
sudo sshd -t
sudo systemctl restart sshd

二、Fail2Ban:自动封禁暴破 IP

即便你关了密码,仍会有海量请求来撞。Fail2Ban 盯着 auth.log,发现某 IP 在短时间内多次失败就自动用防火墙封它一段时间。配 /etc/fail2ban/jail.local 的 [sshd] 段,设 maxretry=5、bantime=1h。装完记得 systemctl enable --now,否则重启不生效。它是"被动但自动"的防御层,和 SSH 加固配合,暴破基本失去意义。

sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

三、防火墙基线:默认拒绝,只开必要

防火墙的黄金法则是"默认拒绝入站,只放行必须的"。Debian/Ubuntu 用 ufw:先 allow OpenSSH 和 Nginx Full,再 enable(enable 前若没先开 SSH,你可能被踢)。RHEL 用 firewalld:--permanent --add-service 加 ssh/http/https 再 reload。原则很简单——每多开一个端口,就多一个攻击面。数据库端口(3306/5432/6379)绝对不要对公网开放,只留内网或 SSH 隧道。

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo firewall-cmd --permanent --add-service={ssh,http,https}
sudo firewall-cmd --reload

四、自动安全更新:只更安全补丁

漏洞被发现后,厂商通常很快出补丁。手动更新容易忘,全量自动升级又可能弄挂生产(比如 MySQL 大版本)。折中方案是只自动装安全更新:Debian/Ubuntu 装 unattended-upgrades 并 dpkg-reconfigure 启用;RHEL 装 dnf-automatic 并把 upgrade_type 设为 security、apply_updates 设为 yes。注意内核补丁要重启才生效,用 needrestart 检查哪些服务还跑着旧代码。

sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
sudo dnf install dnf-automatic
sudo systemctl enable --now dnf-automatic.timer

五、安全体检:lynis 与 rootkit 扫描

加固完,用 lynis 做一次基线审计:sudo lynis audit system 会扫描几十项安全配置,给出分数和修复建议,是免费的"安全顾问"。再装 chkrootkit / rkhunter 扫一遍 rootkit,排除系统已被植入后门。这类工具不是装一次就完,建议每月跑一次,把报告变化记下来——安全是持续状态,不是一次性动作。

sudo apt install lynis chkrootkit
sudo lynis audit system
sudo chkrootkit

六、纵深防御清单

把上面串成上线清单:①建普通用户+sudo;②推密钥、禁 root 密码登录;③Fail2Ban 启用;④防火墙默认拒绝只开 22/80/443;⑤自动安全更新;⑥lynis 月检。再加两条习惯:不用弱密码、密钥存好;最小权限原则,应用账号不给 sudo。做到这些,你的服务器在公网里已经比绝大多数目标安全。剩下的风险,交给监控和备份去兜住。

补充与延伸:安全是持续的姿势,不是一次的设置

很多人以为"按教程把防火墙开了、root 禁了"就安全了,这是最大的错觉。攻击者每天都在扫描全网,今天安全的配置,三个月后可能就出了新漏洞。真正的安全是一个持续过程:订阅你所用发行版和关键软件(Nginx、OpenSSH)的安全公告,及时打补丁;定期用 lynis 跑一遍体检,盯着它提示的 WARNING 一条条消掉;把自动安全更新打开,让小修小补不依赖你记得去手动 apt upgrade。把安全当成"每天呼吸"而不是"偶尔体检",你的服务器才熬得过时间。

再讲一个认知:纵深防御(defense in depth)。不要指望任何一道防线万无一失,而是要层层设卡——即使 SSH 密钥泄露,还有防火墙限 IP;即使某端口开了,还有 Fail2Ban 挡暴破;即使应用被入侵,还有非 root 用户 + 只读挂载限制爆炸半径。任何单一措施被突破都不等于全盘崩溃,这才是稳健。反过来,把宝压在"我密码够复杂"上,一旦那一个点被攻破,后面就一马平川了。安全的本质是冗余,不是单点英雄。

还有一个常被忽略的软环节:人。弱密码、把密钥明文发到聊天群、用同一套密码走天下、在公开仓库提交 .env 文件——这些比任何系统漏洞都常见。给你的团队立几条铁律:密钥用密码管理器保管、不在任何地方粘贴私钥、.gitignore 必须忽略 .env、多人共用机器时每人独立账号并开双因子。技术加固能挡住大部分自动化攻击,但最后的薄弱环节往往是人,守好人的习惯,才守住真正的门。

最后是监控与响应。hardening 不是设完就结束,你得知道有没有人正在打你。把 Fail2Ban 的封禁事件、SSH 的失败登录、异常的 CPU/流量 spike 都接进监控和告警,才能在被攻破的窗口期里及时反应。安全没有终点线,只有"今天比昨天更难被打穿"这一条向上的曲线。把这份警觉维持住,你的服务器才真正谈得上安全。

再补一个常被问到的:要不要改 SSH 端口?把 22 改成高位端口(如 22222)能挡掉绝大部分全网扫描脚本,降低日志噪音,但它是"隐蔽而非安全"——真想打你的人端口扫描一下就找到了。所以它值得做(省心),但不能替代密钥登录和 Fail2Ban 这些主干措施。安全里没有银弹,只有一层层的累加,任何单点优化都只是整体拼图的一块。

另一个值得做的:给重要操作留审计。把 sudo 的命令记录打开(Defaults logfile=/var/log/sudo.log),谁在什么时间执行了什么提权命令一清二楚;关键配置变更前用 etckeeper 把 /etc 纳入 git,改错了能 diff 能回滚。当机器多了、人多了,可追溯性本身就是一种安全——它既威慑误操作,也让你在出事后有迹可循,而不是面对一台被改乱的服务器束手无策。

安全的本质是"让攻击者觉得不划算"。当你的机器有密钥、有防火墙、有限制、有监控、有审计,绝大多数自动化扫描脚本会自动跳过你,转而去找那些裸露在公网、还在用弱密码的软目标。你不需要比所有攻击者都强,只需要比隔壁那台更弱的机器更难打——这份"相对安全",靠的就是本文这些一项项叠起来的基本功。坚持做,时间会站在你这边。

再强调一次:安全不是比谁配置多,而是比谁不间断。一次性的加固一周后就可能被新漏洞击穿,唯有"持续关注公告、持续打补丁、持续复盘告警"这条链路,才能让你长期安全。把 lynis 和自动更新设为开机自启、把安全公告源加进你的 RSS,让安全成为一种不需要额外想起的背景习惯,它才会真正护住你。

安全没有及格线,只有不断加码的过程。今天多做一步,明天就少一分被攻破的可能——这件事,值得你一直做下去。