做网站做了快十年,我一直有一个很深的感触:网站被攻击这件事,跟体量没关系。
我帮一家只有五个人工作室维护官网的时候,遇到过半夜后台被爆破、页面被挂马的状况;也接过一位个人站长朋友的请求,他那个访问量不过每天几百次的博客,被扫描器盯上后日志一天能刷出几十万条恶意请求。这些场景里,你需要的不是一套军工级别的安全设施,而是一个能看懂、能掌控、能迅速部署的轻量级网站防火墙。于是我自己动手做了一个:私有化部署,数据加密且仅保存本地,多端支持,源码一并附上。这篇文章会把设计思路、关键实现、部署步骤和踩过的坑完整记录下来,供同样困扰的小公司、工作室和个人站长参考。
1. 小公司、工作室和个人网站,为什么也要上网站防火墙
1.1 小体量并不等于“没人惦记”
很多朋友喜欢说“我们站点小,没人会黑”。我实测下来,这想法不成立。攻击者手里的扫描器根本不分目标大小,全网扫,扫到就顺手试几下。弱口令、后台暴露、未授权接口,这些在小站里更常见。自动化工具的成本极低,一天扫几千个域名,你的小站只是其中之一。
我给A同学维护过某公司官网,遇到的情况就是被扫出后台登录页,然后字典爆破。密码简单,直接进去挂了个页面。流量没有太大损失,但客户搜索到的是被篡改的页面,信任感一下就没了。处理过程包括备份恢复、补漏洞、锁定后台、排查后门,前前后后花了一整周。
更别提CC攻击了,小站带宽本来就小,几十个并发就能把源站打挂。你去问云服务商,流量清洗要加钱,不加钱只能干等。这些真实遭遇让我相信,小站也得有基础防护,但最需要的是轻量、看得懂、自己能管的方案。
1.2 商用方案和小站点之间存在的“空心地带”
市面上安全产品很多,但坐下细看会发现,小团队常处在夹缝里。
大型商用设备的授权费对一家小公司来说不便宜,而且需要专人维护,很多时候买回来就是吃灰。云端的WAF服务呢?优势是省心,但日志和请求数据都要经过对方平台。这不是说厂商不可信,而是很多团队在数据本地化上有硬约束,老板一句“数据不能出去”,产品经理就得另想办法。还有一些开源的大而全安全项目,规则库动辄几千条,界面复杂,新手上去根本不知道哪些开关能碰。对只有一台小服务器的个人网站来说,光是性能开销就让人犹豫。
这类“空心地带”正好是目标:功能上能挡住绝大多数自动化攻击,部署上不引入额外组件,体感上像一台普通轻量服务。私有化部署意味着代码、规则、数据都放在自己手里;数据加密且仅保存本地,保证日志不外泄;多端支持则让日常管理不用每次都搬电脑上服务器敲命令。所以这个项目我起了个代号“极简盾”。没有复杂集群,不需要专门安全团队,一个小服务可以跑在1核1G的机器上,加压几千条规则也能稳定工作。
2. 核心功能与设计思路:私有化、加密、多端
2.1 私有化部署:把安全控制权握在自己手里
先说“私有化部署”。SaaS服务很流行,但“私有化”对这些场景的最大意义不是赶时髦,而是三点:控制权、成本和审计。
控制权指规则自己定。云WAF给的规则是厂商的策略,调节项虽多,终归在黑盒里。极简盾所有规则以明文形式存在配置文件里,你随时可以翻看、修改,甚至注释掉不想用的规则。规则引擎如何工作,代码里一目了然。这一点对喜欢追根究底的人非常有吸引力。
成本上,没有按流量计费,没有每月的订阅费,只有一台你自己的服务器。对个人站点来说,多跑一个轻量服务几乎感觉不到开销。
审计能力也很实在。因为日志全是自己的,出了事想复盘、想追溯,所有数据都在本地,随时可以翻出来。尤其给客户做项目时,对方问“你的安全方案日志在哪”,你能明确回答“在我方私有服务器上,密钥由我方保管”,沟通成本低很多。
当然,私有化不等于免费午餐。安全补丁、密钥备份、系统漏洞都需要自己负责,我在后面的部署部分会给出实操做法。
2.2 数据加密与仅保存本地:日志安全同样重要
很多小型安全工具只防外人,不防自家数据。攻击者如果拿下了服务器,默认你所有的日志都会裸奔。既然强调私有化,就不能只是“数据在本地”,而必须做到“即使被拖走也读不懂”。
极简盾把三类数据纳入了加密:接入日志、告警事件、规则变更记录。落盘前统一加密,用的对称加密算法是AES-256-GCM,带认证标签,防篡改也防读取。密钥不是写死在配置里的,而是在初始化时随机生成,经过密钥派生函数加工后存到独立密钥文件,并限制为仅部署用户可读。你可以为高安全场景再绑定一层设备指纹,具体做法后面会讲。
“仅保存本地”还意味着默认不出网。没有遥测上报,没有自动更新拨号,没有第三方统计接口。升级靠手动下载安装包,行为完全可预期。很多人觉得不出网土,但在内网环境、敏感项目、还有那些要求“所有数据不出服务器”的客户那里,这是刚需。
另一个容易被忽略的设计是日志轮转。默认按天和按大小双重条件滚动,加密日志超过阈值就自动归档或删除,避免小硬盘被日志塞满。毕竟一个不设防的日志文件,放久了本身就是风险。
2.3 多端支持:不是堆功能,而是同一逻辑
“多端支持”是我在项目后期才加的特性,因为不想为了做端而做端,而是想解决一个实际痛点:日常维护还需要频繁登录服务器敲命令吗?
上下文很清晰:小站没有专门运维,站长的手机经常随手放边上。半夜收到告警,你不可能掏电脑去调规则。所以极简盾统一提供一套本地REST接口,然后在此基础上做了三个端:
Web管理端适合在电脑前看全量报表、批量改规则,过滤条件、模拟测试都在这里做;移动端是H5页面,不依赖应用商店,用于看实时拦截、操作开关、撤销误封;命令行端适合脚本集成,比如每天定时拉取告警摘要,或接到事件后自动封禁IP。
你不用学三套操作,因为三端操作对象是同一套引擎。比如在Web端创建的一条IP封禁规则,移动端和命令行端都能看到并撤销。整体体验就像一套遥控器配了三个按键布局,底层的接口完全一致。多端支持如果变成三套割裂的东西,那就是负优化。
3. 源码导读:架构设计、规则引擎与加密存储的实现
3.1 整体架构与流量接入方式
极简盾的整体架构不复杂,按数据流可以分成四个环节:接入模块、规则引擎、事件存储、管理接口。
接入模块负责接收真正的业务流量。项目支持两种接入方式:反向代理模式和透明网关模式。反向代理模式是将站点流量先打到极简盾监听端口,由它把合法请求转发给后面的业务源站,适合绝大多数单站点或小集群。透明网关模式则需要配合路由或内网设备,让流量经过但不改变业务原有结构。从部署稳定性考虑,绝大多数情况下我推荐反向代理模式,原因写在实操部分。
规则引擎是核心,接收接入模块解析出的请求对象,包括来源IP、请求方法、URL路径、请求头、Cookie、POST参数等。每条规则被设计成可独立启停的过滤器,最终返回“放行”“观察”或“拦截”三个动作。返回“观察”时,请求正常放行,但完整事件会被记录,用来评估规则是否过严。这个概念对上线初期调参极其重要。
事件存储负责把动作结果落到加密文件里,同时维护一份内存索引,保证管理端查询不会每次都扫全量磁盘。管理接口则对外暴露统一API,服务Web端、移动端和命令行端。源码里最值得先看的是目录结构,大概三段:内核、管理接口、前端:
minishield/ ├── core/ # 内核:接入、规则引擎、加密存储 ├── api/ # 管理接口 ├── web/ # Web管理端 ├── cli/ # 命令行工具 └── config/ # 规则、密钥与运行时配置代码量不多,一个能读懂单线程Web服务的人,花两个晚上基本能理清。
3.2 规则引擎与拦截逻辑设计
规则引擎决定了好不好用。极简盾的过滤体系分成四类:
第一类是黑名单与白名单,直接针对IP、路径和User-Agent。白名单优先级最高,比如管理后台别误伤,就加白;黑名单用于封禁明显恶意的来源。
第二类是速率控制。很多攻击不是靠规则像,而是靠频率,比如登录接口疯狂爆破、短时间内大量扫页面。速率控制基于滑动窗口实现,按来源IP和请求路径组合统计,超过窗口阈值就触发拦截。阈值不是写死的,你可以按站点真实访问量调,滑动窗口长度和统计单元时间都可配置。
第三类是语义规则,也就是常见的注入、跨站脚本、路径探测等。这里有个容易犯错的点,正则别写太宽。早期版本里一条“检测带SQL关键词的URL”规则过于激进,把正常用户搜索里包含“select”的文章页也拦了。后来改成“关键词出现的位置和上下文匹配”才解决。
第四类是自定义脚本,给有编程能力的用户准备。脚本接收一个标准化请求对象,返回处理建议,适合处理冷门场景。配置里写脚本要谨慎,因为它是高权限的,建议先用“观察”模式跑一段时间再启用。
规则优先级逻辑简单总结:白名单 → 精确命中黑名单 → 速率判定 → 语义规则 → 自定义脚本 → 默认放行。理解这条顺序,调试规则才不会一脸懵。
3.3 加密存储与密钥管理
前面提了落盘文件用AES-256-GCM加密,这里讲密钥管理,因为密钥才是最值钱的东西。
部署初始化时,程序会生成一个随机主密钥,然后用部署密码经过密钥派生函数生成加密密钥,去包裹主密钥,最后写入密钥文件。登录管理端时密码不会直接用于解密数据,加密流程和身份验证的密钥是分开的。这样即使管理账号被攻破,历史数据仍然由主密钥保护。
密钥文件的使用权限需要重点盯。默认创建后只允许部署账号读取,权限值设为600,目录700。很多部署事故都是因为把整个安装目录权限改成777导致的,这相当于把保险柜钥匙挂在保险柜外面。
我更推荐的做法是开启“设备绑定”。极简盾会把当前机器的系统特征采集出来,生成一段设备指纹,加密时与主密钥一起参与派生。也就是说,哪怕密钥文件被拷贝到另一台机器,也无法解密。这在服务器备份时会有影响,所以备份密钥和指纹信息时要一起备份,否则灾备恢复后会打不开日志。
最后,日志轮转后的旧文件如果没有保留需求,直接删除就好,不要反复用覆写操作。对SSD寿命不友好,也容易留下半截加密片段。只要删除前做过必要审计,删除本身不是问题。
3.4 多端接入的实现与权限控制
多端并非各做各的。管理接口是一套基于时间戳和令牌认证的REST API,Web端、移动端、命令行端都走这套接口,只是表现层不同。
每一个管理端账号会绑定独立的访问令牌,令牌在创建时只完整展示一次,之后就只存在本地加密配置里。这样即使手机丢了,也不需要重新部署整套系统,只需在Web端撤销对应令牌,移动端立即失效。
接口按“最小权限”划分。默认管理员拥有全部权限,但日常建议创建一个只读账号给同事或客户查看报表,处置动作只保留给管理员。最近版本里还加入了IP白名单限制管理接口的来源地址,进一步降低管理面暴露风险。
移动端走H5还有一个优势:不需要应用商店审核,也不需要安装任何客户端,使用浏览器即可。对内网环境网速友好。唯一的代价是离线情况下只能看到本地缓存的最近500条事件,不过对日常巡检来说足够。
4. 从零部署的完整实操记录
4.1 部署前的准备与规划
部署前把几个问题想清楚,能少走弯路。
第一个是硬件。实测在1核1G的机器上可以稳定运行,前提是业务站点每天的请求量不超过几十万。如果站点规模较大,建议2核2G,并把日志轮转周期调短。磁盘建议至少留2GB用于日志,具体视业务而定。
第二个是接入方式。我几乎一律推荐反向代理模式,原因是调试直观、回滚容易。把网关停掉,把监听端口改回业务端口,站点立刻恢复,不需要动路由和底层网络。透明网关模式虽然“透明”,但对网络要求高,一旦配置错误,排查网络问题会很崩溃。
第三个是域名规划。最好给管理端单独划一个子域名,不给业务共用。不是怕资源不够,而是业务域名日志里全是对外请求,管理域名负责的管理流量混在一起,后续分析很不方便。
第四个是确保服务器时间准确。加密、令牌、速率窗口全部依赖时间戳,时间漂移会导致令牌校验和日志时间错乱。这是我早期踩过的坑,当时一台内网机器时间快了五分钟,手机端一直登不上,排查了半小时才发现。
4.2 安装、初始化与默认安全动作
拿到源码包后,第一件事是校验文件完整性。项目里附带校验值文件,下载后用常见校验工具比对一下。这一步不能省,毕竟要安装的程序是防护层本身,装到一个被篡改过的包,还不如不装。
解压后直接运行初始化命令:
./minishield init初始化过程会做几件事:生成主密钥、创建管理账号、写入默认规则、启动本地管理接口。注意这个接口默认只监听127.0.0.1,不对外网开放。如果要从外部访问Web管理端,需要手动开启管理入口并配置来源IP白名单。首次登录会强制要求修改初始密码,并建议开启第二步验证,具体是生成一次性动态口令。
安装完成后建议立刻做三件事。第一,给系统打补丁,系统和运行环境都更新到当前维护版本。第二,备份初始化生成的密钥文件,放到离线位置,建议是加密的U盘。第三,测试重启恢复,确认重启后极简盾能自动拉起。很多小站没有专职运维,这套自动化恢复我一律用进程守护实现,配置很简单。
我还会顺手把默认规则库改成“观察模式”。这个阶段比拦截更重要的是熟悉流量,让规则先写日志不加动作,跑24到48小时,你才能真正了解自己站点的正常访问长什么样。等有了基线,再逐步切换到拦截。
4.3 将网站流量安全接入防护层
设置好后,把流量切到极简盾。以反向代理模式为例,部署后站点配置变成这样:
用户请求 -> 极简盾(公网端口) -> 校验拦截 -> 业务源站(127.0.0.1:8080)用户请求先到极简盾监听的安全端口,极简盾完成检测后,再把请求转发到业务源站监听端口。业务源站不再直接监听公网端口,只监听内网回环地址,从网络层面减少暴露面。
在反向代理组件里做对应的转发配置,加上“来源IP透传”相关的请求头,就能让业务源站看到用户的真实IP。这一步必须做,否则后面所有按IP统计的规则全部失真。透传请求头时需要限制来源,防止客户端伪造,否则攻击者随便加一个伪造头就能绕过IP限制。
切换过程中有一个稳妥的操作顺序:先在原端口保留业务访问,用测试域名或改本机HOST方式验证极简盾转发正常,确认无误后再改正式域名的解析或端口映射。不要在生产环境白天直接切,选低峰时段,准备好回滚步骤。我在某公司官网切换时,预先把回滚脚本写好,失败了十秒内切回原地址,心里完全不慌。
接入完成后跑几条测试请求,看看事件日志里是否正常记录来源IP、路径和动作。确认没问题再把源站的公网监听关闭,只保留内网监听。
4.4 多端绑定与日常使用
接入成功后,生成访问令牌。在管理端页面创建管理员令牌和管理员/只读账号,移动端扫描初始二维码绑定,命令行端把令牌写入配置文件。三端可以在同一局域网或公网接入,前提是管理接口允许对应来源IP访问。
日常巡检我基本只用手机端:早晚各看一眼拦截趋势和告警。Web端则用在批量调整规则和查看报表。命令行端我写了一个小脚本,每周一把上一周的拦截流量统计发到内部群里,省得每次都手动查。
要提醒的是,初始化生成的密钥文件和管理员令牌绝不能发到聊天工具里。我之前遇到一个团队,为了图方便把部署密钥截图发到工作群,导致后来整个密钥体系都不可信,只能重置重来。这类教训不值得重复踩。
5. 上线后遇到的典型问题和排坑心得
5.1 误拦截率高的排查方法
上线初期最容易遇到的问题就是误拦截。我第一次给工作室网站切拦截模式,当天就接到反馈,说某个搜索页面打不开。上去看事件日志,发现是一条语义规则把URL里的关键字参数判成了非法关键词。问题出在规则只做了子串匹配,没有处理边界和上下文。
排查这类问题,我有一套固定流程。先看拦截事件里有没有大量来自同一出口IP、同一页面路径的请求,如果有,说明是规则覆盖面太宽。然后把规则临时设为“观察”模式,让这条规则只记日志不拦截,观察一段时间确认影响范围。确认后收紧规则:能精确匹配路径就不要用子串匹配,能枚举参数白名单就不要全部放开。最后留下一批可复现的测试样本,每次改规则后跑一遍回归。
新用户我强烈建议先跑至少48小时“观察模式”,利用这个窗口期把规则调准,再开启拦截。安全不是越狠越好,而是在有效拦截和不影响正常业务之间找到平衡。
5.2 资源占用偏高的优化过程
有一次在低配机器上部署后,CPU占用一直在30%左右,对一个小站来说很难接受。逐个排查后发现两个因素:一是日志加密是每条请求即时写盘,I/O压力大;二是某个规则用了一个性能很差的正则表达式,每条请求都要跑一遍,非常耗时。
优化思路分两条。事件写入改成批量模式,先写内存缓冲,达到阈值或按固定时间刷盘,既能保证不丢事件,又能大幅降低I/O频率。正则部分用预编译,避免每次请求重复编译同一模式。这两处优化后,CPU占用降到了5%以下,效果明显。
给低配服务器的建议是:规则宁少勿多,能合并的合并,能走速率控制的别用正则。速率控制逻辑简单,开销是常数量级;正则则是无底洞,特别容易写出指数级回溯的表达式。规则上线前可以用压测工具打一下,心里有数。
5.3 反向代理场景下的IP获取和循环问题
接入反向代理后必须处理真实IP透传。不把来源IP透传对,后面所有IP封禁规则都形同虚设。正确做法是信任层级顺次连接:极简盾只信任上一层代理,同时保留原始来源IP,业务源站只接收来自极简盾的连接。配置里要严格限定可信代理来源,不要向所有来源开放添加请求头的权限。
另一个高频故障是重定向循环。常见原因是业务源站检测不到HTTPS协议,以为自己是HTTP明文访问,又强制跳转到HTTPS,于是跳来跳去。解决办法是在转发时正确传递协议头,并让业务源站配置成信任这个头与协议标记。这个坑在接入证书服务时很容易出现,一定多测几轮。遇到这类问题,别靠直觉猜,先在事件日志里看到底是哪一层把请求转回来了,再逐层配置,稳得多。
5.4 密钥与令牌管理的几个坑
安全工具的密钥管理是高风险区。以下几个坑我见过不止一次:密钥文件权限太宽松、系统账密和管理账号共用一套、令牌发送到聊天工具、备份的时候只备份了数据没备份密钥文件。
我的建议是给极简盾单独创建一个系统账号,端口权限、文件权限、进程守护都归它管理,不让业务代码和管理代码混在同一账号下。密钥备份到离线介质,并在备份清单里注明对应的设备指纹信息。令牌按人按端创建,一旦有人离职或手机丢失,立刻撤销对应令牌,不要让多个端共用同一个令牌。
另外,长期不用的管理令牌可以设置过期时间。默认三个月有效,到期重新认证。这些细节在遇到真实事故之前都觉得繁琐,但等到密钥真的泄露那天,你就会庆幸当初做得够细。
下面把上线初期最常遇到的几类问题整理成速查表,方便直接对照:
| 现象 | 可能原因 | 快速排查步骤 |
|---|---|---|
| 误拦截集中在某路径 | 语义规则过宽 | 规则先切观察模式,定位后收紧匹配条件 |
| CPU占用长期偏高 | 低效正则、日志写盘频繁 | 正则预编译,事件批量刷盘 |
| 管理端无法登录 | 服务器时间漂移、令牌过期 | 校准时间同步,重新生成令牌 |
| 业务看到虚假来源IP | 透传头未限制信任来源 | 按层级限定可信代理来源 |
| 配置改动后异常 | 规则顺序理解不一致 | 对照优先级:白名单优先,默认放行兜底 |
6. 我沉淀下来的几条部署习惯与扩展计划
6.1 多次部署后固定下来的习惯
经过几次真实部署,我固定下来了几个习惯,现在每个新环境都会照做。
第一,初始化后立刻重启一次,确认自动拉起能力正常。不是所有环境都有专职运维,这一条能避免服务器重启后网关不工作导致业务全断。
第二,规则改动走“预览”模式。不是直接改生效,而是先预览匹配效果,再点击生效。极简盾内置了这个机制,每次改规则都先在预览里跑几条样本请求。
第三,固定每周一次的巡检节奏。周一看上一周的拦截统计、误拦情况、日志增长量。对一个每天几百请求的小站,十分钟足够。坚持下来,站点流量结构和异常苗头都会很清晰。
第四,给服务器做时间同步。前面踩过时间不准的坑后,我所有环境都强制开启时间自动同步,并把偏移阈值设置在很小的范围,超过就告警。
6.2 后续想做的扩展方向
当前版本已经能满足大多数小团队需要,但后续还有几个我比较想做的扩展:插件机制,让贡献者能独立发布规则包;一键迁移工具,方便把当前策略完整导入另一台机器;面向多站点的集中控制台,适合工作室同时维护多个客户站点,按项目隔离权限。
另外,源码一直开放,任何人都可以自行审计、修改。我写这个项目最初是为了解决自己的痛点,分享出来只是觉得很多小团队在同样处境里,与其在复杂和昂贵之间二选一,不如有一个中间选项。
如果你正被小站的安全问题困扰,建议先跑一遍观察模式,看看自己的日志,也许你会跟我一样发现:原来每天有这么多你根本不知道的请求,在敲你的门。