4.3 防火墙与防护:只开必要端口的清单

网站上线热闹劲儿还没过,朋友某天转发给我一条推送,说某某服务器被勒索软件加密勒索。他紧张地问我:“咱这台服务器安全不?”说实话,一台小服务器没有人专门盯着,唯一靠谱的办法就是把门关紧——只开必要的端口,其余一律拒绝。这一节记录我做的一次完整加固:云平台防火墙、WordPress 应用层、密码与插件,外加一份可照做的检查清单。

先说一个心态上的转变:很多人以为安全是装个安全软件、买高防 IP 之类的事,对小站点来说恰恰相反——最有效的安全动作是做减法,把不必要的入口全堵上。一台只开三个端口、后台带二次验证、插件全最新的服务器,已经挡掉了互联网上绝大多数的自动化攻击。那些扫描器都是无差别的,它们找的是疏于维护的站点,而不是你的业务价值。

轻量防火墙:默认只开三条门缝

轻量应用服务器自带实例级防火墙(不是操作系统里的 iptables,是在云平台这一层拦截,流量根本到不了操作系统),默认只放行少量端口,规则在控制台实例详情的防火墙页维护,添加和修改都是实时生效。我接手时的现状加我调整后的清单:接手那天我先截了个图存底,把防火墙页的每条规则原样记下来,万一改坏了还能照着恢复,这个习惯是从配错规则被关在门外那一次学来的。

端口 协议 放行策略 我的调整
22 TCP 默认放行所有来源 限制为我的家庭 IP 和公司 IP
80 TCP 默认放行 保持,HTTP 跳转用
443 TCP 默认放行 保持,HTTPS 主入口
3306 TCP 默认拒绝公网 保持拒绝,MySQL 只走本地
面板端口 TCP 默认 8888 暴露公网 改成随机高位端口并限源 IP

两个动作最关键。一是把 22 端口从“所有 IPv4”改成只有我和朋友的两三个来源 IP——SSH 暴力扫描是互联网上最常见的噪音,限制来源后访问日志瞬间清净了,也顺手降低了被撞库成功的概率。操作时有一点提醒:来源 IP 最好是固定宽带出口,如果是家用动态 IP 偶尔会变,要么定期更新规则,要么留一个备用通道(比如手机热点固定 IP 的服务器做跳板)。我第一次配的时候就只填了办公室 IP,周末在家改东西死活连不上,还以为是服务器挂了。二是把面板端口从默认值改掉,搜索引擎上按面板默认端口扫描的脚本一抓一大把,换掉能挡掉九成的自动扫描,再配上限源 IP 就更稳。改完之后我还检查了数据库的监听地址,MySQL 只监听 127.0.0.1,公网再怎么扫也连不上。这里注意一个原则:限源 IP 要把所有管理员 IP 填全,不然哪天自己去外地出差,SSH 连不上会有点狼狈——经验之谈,我后来给了自己一个备用跳板。

需要补一句的是:接入 CDN 之后,节点回源的流量也是走公网到源站的 443 端口,443 不能限制来源,否则节点取不到文件。所以防火墙策略要和 4.1 节的接入配合看,不能为了安全把回源也堵死。同理,如果未来换成 COS 做源站(见 4.4 节的转存方案),源站这侧的端口压力还会进一步下降——安全架构和加速架构是一盘棋,落下任何一子都要看整盘。操作细节见轻量应用服务器文档。

配完之后我故意错密码试了几次确认封禁生效,再去日志里看爆破量,肉眼可见地降了下来。朋友担心二次验证会影响他发文章的效率,实际用下来就是登录时多看一眼手机验证码,比起时不时被刷屏的告警,这个成本可以忽略。

再往下说细一点,WordPress 后台还有两个开关值得关掉:一个是注册功能(企业官网根本不需要开放注册,默认开启等于给攻击者送账号),一个是文件编辑功能(后台外观编辑器能直接改主题代码,一旦账号被盗,攻击者就能在面板里埋马)。注册开关在常规设置里关,文件编辑要在配置文件里加一行禁用,具体写法查 WordPress 文档即可。这两步加上前面的登录加固,后台这个口子才算真正堵住。

WordPress 层面:插件这个口子

云防火墙管的是端口,WordPress 自己的口子得在应用层管,这两层不能互相替代。

首先是后台路径。wp-admin 和 wp-login.php 是爆破重灾区,日志里一眼看过去全是乱试密码的请求。我做了两件事:给登录页加了二次验证插件(登录时多一步手机验证码),再把登录失败限频打开(同 IP 五分钟内失败五次就临时封二十分钟)。再彻底点可以改掉默认的 wp-login.php 路径,不过改路径要跟主题和插件兼容性权衡,我图省事只做了前两样。配完之后我故意错密码试了几次确认封禁生效,再去日志里看爆破量,肉眼可见地降了下来。

然后是插件漏洞。这是最容易被忽视的一条:后台装了十几个插件,其中半数装上就再没动过。每个插件都是潜在入口,隔几个月就会有流行插件爆出漏洞,小站尤其吃亏——漏洞详情一旦公开,扫描器会全网批量探测没来得及更新的站点,我们这种没人盯的小官网往往最先遭殃。我的做法是定期进后台把停用不用的插件直接删掉(停用不等于文件不存在,删掉才彻底),保留的插件看到更新提示就当场点掉,绝不攒着。这套面板和服务管理的通用思路,1Panel 面板运维里也讲过,原理一样。

最后是弱密码。朋友的初始密码是企业拼音加 123 那种,被我强制换成了随机长密码,用密码管理器存。WordPress 后台、服务器 root、数据库 root,三个口子全部换掉。日志里那些爆破请求能成功的基本都是弱密码,这一步的性价比比什么花哨配置都高。

养成习惯:定期看一眼访问日志

规则配得再好,也不如亲自看一眼日志来得直观。我给自己定了每周五花十分钟扫一次日志的习惯,主要看两类东西:一类是 SSH 相关的失败记录,看看有没有新增的陌生来源 IP 在试端口;另一类是网站访问日志里有没有异常的 URL 模式(比如莫名其妙的 .env、wp-config.php 探测请求,这些都是自动化扫描的特征)。轻量自带面板里有日志查看入口,直接看面板最省事,命令行可以这样快速统计尝试登录的来源:

grep "POST /wp-login.php" /path/to/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

跑一次就知道哪些 IP 在反复试登录,配上防火墙的限源规则直接封掉。日志看多了会有手感:正常的企业官网流量曲线是工作日双峰、周末低谷,突然冒出来的平稳高峰往往就是爬虫或盗链——后者正是 4.4 节那次事故的先兆,其实在日志里早有端倪,只是我当时没养成看的习惯。另外日志本身也要保护:访问日志的读取权限别设置成所有人可读,更别在面板里默认对外暴露,信息泄露本身就是攻击面的一部分。

一份可照做的检查清单

帮朋友弄完之后,我把整个过程整理成清单,后来给别的小项目也照着执行:

检查项 目标状态 验证方式
端口 22 仅限管理员 IP 控制台防火墙页核对来源
端口 80/443 放行(CDN 回源需要) 浏览器 HTTP 和 HTTPS 访问
端口 3306 公网拒绝 外网 telnet 不通
面板端口 非默认值且限源 非白名单 IP 打不开
登录入口 二次验证加限频 故意错密码试五次
插件 删除停用项且全部最新 后台插件列表过一遍
密码 随机长密码 密码管理器核对

清单不长,但执行完之后习惯性看访问日志,发现的异常请求确实少了很多。另外强调一点容易被忽略的:所有加固动作之前,先给服务器打一个快照(快照的用法见 5.1 节)。防火墙规则失手、面板端口改错、SSH 限源忘了加备用 IP,这些事故我都见过——轻则自己被关在门外,重则网站半天打不开。有快照在手,大不了回滚到改之前的状态,几分钟恢复;没有快照,就得在面板里跟一条条规则较劲,出一身冷汗。朋友的服务器我每次大改前都手动打一个快照,这个习惯后来真的救过他一次。安全这事儿没有什么一劳永逸,就是把门关紧、把口子堵严,再定期巡一遍。

更多服务器运维和故障排查的通用方法,可以看服务器常见问题;想要一套带面板的完整建站环境管理方案,参考1Panel 面板运维。

延伸阅读