ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SamWaf开源轻量级网站防火墙:独立引擎部署与OWASP CRS规则实践

SamWaf开源轻量级网站防火墙:独立引擎部署与OWASP CRS规则实践 简介SamWaf 是一款开源轻量级网站防火墙的完整源码包专为中小公司、工作室及个人站长设计用于解决网站安全防护和私有化部署的核心需求。它支持多个主流操作系统和硬件平台能够在本地一键启动所有数据均加密保存且不对外泄露防护引擎完全独立无需依赖外部服务器组件。这份资源共包含七百零一个文件其中绝大多数是采用 Go 语言编写的核心代码另外还配有配置文件、说明文档、界面图标、构建脚本等多种辅助材料整体压缩包大小约为二十兆字节。功能方面从自定义防护规则到黑白名单管理再到访问频率控制、分站独立防护、日志加密脱敏以及集成开放标准的 Web 攻击规则集并支持安全证书的自动申请与续期可以说覆盖了日常网站运维所需的主要场景。目前已有九十七人学习下载非常适合希望从源码层面理解防护机制、进行二次开发或深度定制安全策略的研究者与小型团队。1. SamWaf 开源轻量级网站防火墙一个能私有化部署的独立防护方案做个人站或者小公司官网的都知道业务没起来流量扫描器先来了。每天后台一堆 /wp-login.php、/phpmyadmin 的探测请求偶尔还被 CC 刷到 CPU 跑满。上云 WAF 要改 DNS、要付费用 Nginx 插件方案又得折腾 OpenResty 编译和规则库更新对小站点来说太重。SamWaf 这款开源轻量级网站防火墙的思路很直接独立引擎不依赖 IIS、Nginx数据加密只存本地解压就能跑。代码完全开源适合二次开发也能直接当生产防护用。看完这篇你至少能搞清楚它的部署结构、规则体系和常见坑位。2. 部署与源码结构一键启动背后的跨平台构建逻辑2.1 为什么轻量不依赖 IIS/Nginx 的独立引擎设计传统 WAF 方案大致分两类。一类是云 WAF流量先到云端清洗再回源防御能力强但要改 DNS、要等 CNAME 生效而且请求链路多一跳。另一类是 Web 服务器插件比如 Nginx 上的 ModSecurity 或者 lua-resty-waf好处是不用改 DNS坏处是你得先有一套 Nginx/OpenResty 环境版本升级和规则热更新都是维护负担。SamWaf 走的是第三条路自带 HTTP 解析和防护引擎监听端口直接接管流量然后转给后面的源站。这意味着你的 Nginx、IIS 不用做任何改动甚至可以把 SamWaf 放在内网入口前面只让它一个进程暴露公网。对于源站本身没有独立防火墙能力的小站点这种架构最直观一个进程搞定 TLS 终止、HTTP 解析、规则匹配、日志加密。源码目录下那批构建脚本也能印证这个设计思路。release_pub.bat 是发布产物的构建入口build-releases-win-upx.bat 负责打 Windows 安装包build_docker_release_linux.bat 用来构建 Linux Docker 镜像。它们服务的都是同一个目标让用户在不同平台上都能一键跑起来而不是要求用户先去装一套 Web 服务器。2.2 Linux、Windows 与 Docker 三种启动方式拿到源码最快验证的方式是本地起一个实例。Windows 环境下直接把 release_pub.bat 放到纯英文路径双击脚本会把可执行文件和 conf、规则目录整理到一起。Linux 下我一般手动指定配置和日志目录便于区分不同站点的实例# Linux x64 启动示例先给可执行权限 chmod x samwaf # 启动并指定配置与日志目录 ./samwaf -config conf/samwaf.ini -log_dir logs这里-config指向主配置文件监听端口、TLS 证书路径、全局规则开关都在里面-log_dir单独指定日志目录方便日志加密落盘和定期清理。首次启动后控制台会打印实际监听地址和管理入口浏览器打开就能进配置界面。如果你偏好容器化部署源码里的 Dockerfile 配合构建脚本直接出镜像# 在项目根目录构建镜像 bash build_docker_release_linux.bat # 启动容器映射 80/443挂载数据目录 docker run -d --name samwaf --restartunless-stopped \ -p 80:80 -p 443:443 \ -v /opt/samwaf/data:/data \ samwaf:latest端口映射按实际站点情况改443 是给自动申请的 SSL 证书用的。挂载数据目录必须做不然容器重建后规则配置和加密日志全没了。我在测试环境踩过这个坑重启容器发现白名单规则全部回到默认值后来一律把 data 目录持久化。2.3 构建脚本与目录release_pub.bat 到 UPX 压缩拆开源码包文件结构大致是下面这样samwaf/ ├── conf/ │ └── samwaf.ini # 主配置 ├── release_pub.bat # 发布构建入口 ├── build-releases-win-upx.bat # Windows 版构建UPX 压缩 ├── build-releases-win7-upx.bat # Windows 7 兼容构建 ├── build_docker_release_linux.bat # Linux Docker 镜像构建 ├── REQUEST-920-PROTOCOL-ENFORCEMENT.conf ├── REQUEST-932-APPLICATION-ATTACK-RCE.conf ├── REQUEST-941-APPLICATION-ATTACK-XSS.conf └── REQUEST-942-APPLICATION-ATTACK-SQLI.conf几个 bat 各有分工。release_pub.bat 是总入口负责把编译产物、规则文件、配置模板打包成可分发目录两个 win 版本用 UPX 对可执行文件做压缩win7 版是为了兼容老系统。我给别人交付离线环境时一般用 win7 版兼容性最稳。四个 REQUEST 开头的 conf 是 OWASP CRS 规则集文件分别对应协议强制、RCE、XSS、SQLi 四类攻击检测不属于启动必需项但建议全部启用。UPX 压缩会让杀毒软件偶尔误报实际部署如果遇到误报换未压缩的 release 版本再试。3. OWASP CRS 规则集与自定义防护规则优先级怎么排3.1 内置四类 CRS 规则文件对应什么攻击OWASP CRSCore Rule Set是开源社区维护的一套通用攻击检测规则SamWaf 把其中四个核心文件直接内置了。这四类对应 Web 攻击里最常被自动化工具利用的几大类字段和检测重点我整理成了表规则文件防护类别典型检测对象REQUEST-920-PROTOCOL-ENFORCEMENT.confHTTP 协议强制畸形请求、非法方法、Content-Type 校验REQUEST-932-APPLICATION-ATTACK-RCE.conf远程命令执行system、eval、命令拼接特征REQUEST-941-APPLICATION-ATTACK-XSS.conf跨站脚本攻击script 标签、onerror 事件属性REQUEST-942-APPLICATION-ATTACK-SQLI.confSQL 注入union select、sleep、报错注入特征920 是协议层兜底很多扫描器第一步就是发畸形的 HTTP 包探测服务器类型协议强制规则能直接挡掉一批。932、941、942 是业务层主力对应命令注入、XSS 和 SQL 注入。实际效果上942 的命中率通常最高因为自动化脚本扫 SQL 注入的频次远高于其他类型。这四类规则是基础防线但对特定业务的误报也集中在这四类里。比如 URL 里带 select 关键词的正常接口、搜索参数里含特殊字符的请求都可能被 942 拦下来。这也是为什么后面必须有白名单和自定义规则的兜底层。3.2 界面编辑与脚本式自定义规则CRS 规则是通用防线到了具体业务场景你得有自己说了算的规则。SamWaf 支持两种自定义方式界面表单式编辑和脚本式编辑。界面编辑适合简单场景比如“匹配 User-Agent 含某个特征就拦截”“客户端 IP 等于某地址就放行”填表单就行不用接触代码。脚本式编辑适合复杂判断逻辑比如多条件组合、来源 IP 与路径交叉匹配。以 Lua 风格为例演示一下判断逻辑-- 自定义规则脚本示例拦截 /admin 下非白名单来源 function check(ctx) -- ctx.uri: 当前请求的相对路径 -- ctx.client_ip: 连接来源 IP if string.find(ctx.uri, /admin, 1, true) and ctx.client_ip ~ 192.168.1.100 then return false -- false 表示拦截 end return true -- true 表示放行 end这段逻辑的核心是校验两个条件请求路径落在 /admin 下且来源 IP 不是内网运维地址。两个条件同时成立才拦截避免把内网管理员的正常操作挡掉。string.find的第四个参数true表示纯文本匹配不把路径里的点号当正则元字符。实际脚本引擎的字段名以你下载版本的注释为准不同小版本可能有差异但拦截与放行的返回语义是一致的。写脚本规则有一个经验先只写日志不拦截观察一周命中情况确认没有误报再打开拦截动作。直接上线拦截规则是最容易翻车的操作我吃过这个亏。3.3 规则优先级与白名单边界多套规则同时存在时执行顺序必须明确不然会出现“黑名单拦了但白名单又放了”的冲突。SamWaf 的常见做法是白名单权重最高依次是 URL 白名单、IP 黑名单、自定义规则、CRS 规则。配置示例[access] whitelist_ip 192.168.1.0/24, 127.0.0.1 whitelist_url /api/health,/monitor/ping blacklist_ip 45.10.xx.xx [rule] # 自定义规则总开关 enable_custom true # CRS 规则级别建议先跑 2 再逐步调高 crs_level 2为什么要让白名单优先因为监控探活和健康检查接口不接受误伤。/api/health这类地址如果被 CRS 规则误判报警系统会连续误报最后你不得不关掉整个规则集。把白名单放在最前面等于给了运维一个明确的逃生通道。注意白名单 URL 配的是路径前缀匹配/api/health会匹配/api/health和它的子路径不要配得太宽。IP 黑名单是另一个极端直接封禁连日志都不记录请求详情。适合拉黑已知扫描器来源段。黑名单生效后被拉黑的 IP 请求会直接收到自定义拦截页。4. CC 频率防护与访问控制阈值、黑名单和分站策略4.1 CC 防护判定逻辑与参数调整CC 攻击的本质是高频发请求耗尽应用资源SamWaf 的 CC 防护用滑动窗口计数统计单位时间内同一 IP 的请求次数超过阈值就触发动作。参数和合理范围大致是这样参数项示例值调整建议统计窗口60 秒按业务接口响应时长调整周期内最大请求数100 次/分钟正常峰值 QPS 的 2-3 倍触发后封禁时长300 秒攻击结束后建议保留 5 分钟观察期触发动作拦截或人机校验老系统选拦截新系统可上校验我刚部署时把阈值设成 30 次/分钟觉得小型站点够用结果公司自己的监控探活 UA 被连坐页面没挂监控反而把告警发了一堆。后来按正常峰值 QPS 乘 2.5 倍重设阈值误伤才消失。调参的原则是阈值要比正常流量高出一截但低到真攻击时能触发不要用默认值直接上线。分网站场景下要单独调整。比如一个主站流量很小但第三方回调接口的请求频率稳定在每秒几次全局 CC 阈值就可能把回调冲掉这种接口必须在分站策略里单独放开。4.2 IP 黑名单、URL 白名单与限制 URL 访问访问控制这块适合直接枚举典型场景功能适用场景配置要点IP 黑名单拉黑扫描器、撞库来源 IP 段按来源段封禁避免单 IP 误伤出口URL 白名单健康检查、支付回调、Webhook精确到路径严格限制子路径范围限制 URL 访问隐藏后台登录页、管理接口只允许特定 IP 段访问限制 URL 访问这个功能我用的最多。后台登录页放在/admin公网任何人都能访问密码再强也怕暴力破解。配置成只允许公司出口 IP 段访问之后日志里的后台探测请求直接清零。注意白名单放行的请求不参与 CC 计数支付回调这类高频请求一定要提前放进去。4.3 分网站独立策略与全局一键配置的取舍全局一键配置适合统一基线所有站点先按同一套 CRS 级别和白名单跑起来。但站点类型差异大时全局配置就是一把双刃剑。我手上有三个站点一个公网官网、一个内网 API、一个管理后台。公网官网要开全套 CRS 和 CC 防护内网 API 只开协议强制和 IP 白名单管理后台把 URL 限制和 CC 阈值都拉满。这三个需求用全局策略没法同时满足只能分站配。我的建议是全局只保留最基础的协议强制和日志配置把 CRS 级别、CC 阈值、黑白名单全部下放到分站策略里每个站按自己的流量特征设置。保护规则多了不好维护少了又等于裸奔分站配置就是为了让每类业务都有刚好够用的防护强度。“指定界面数据隐私输出”这个开关也放在分站级别。开启后管理界面查看日志时会对 POST body、查询参数里的敏感字段做脱敏显示避免运维同学在排查问题时把用户手机号看了一圈。这个开关和生产数据安全直接相关建议所有站点默认开启。5. 部署避坑与常见问题五个高频翻车点5.1 误报与盲封CRS 规则误伤正常流量现象网站上线后部分正常用户请求返回 403 拦截页搜索词里带单引号或含 select 字样的 URL 命中率特别高。原因CRS 942 规则对 SQL 特征很敏感业务侧如果存在 URL 参数直接拼接查询条件的场景误报会被放大。解决先去拦截日志看命中的规则 ID 和具体请求参数确认是误报后把对应接口路径加入 URL 白名单或者把 CRS 级别从 3 降到 2。不要直接关整条 SQLi 规则那样等于给攻击者留了个口子。只针对具体路径放行范围越小越好。另一个高阶问题自己在后端对参数做了充分转义觉得 WAF 是多余的。但从立体防护角度看WAF 的价值在于攻击者连应用层都到不了省下的资源消耗是实打实的。5.2 启动与链路问题闪退、路径和源站直连现象一Windows 服务器双击 release_pub.bat 闪退控制台什么都没留下。原因最常见的是路径里有中文或空格批处理脚本解析路径时出错次要原因是系统缺少 VC 运行库。解决把项目放到纯英文路径比如C:\samwaf重新执行脚本。还是闪退就用命令行手动跑可执行文件错误信息会留在控制台里。给老系统部署优先用 build-releases-win7-upx.bat 构建版本兼容性更好。现象二域名走了 WAF 防护但攻击者直接通过服务器 IP 访问到了源站。原因只把域名解析指到了 SamWaf 所在的入口但源站 IP 仍然暴露在公网安全组没有做来源限制。解决源站防火墙只放行 WAF 节点的 IP 段其他来源全部拒绝。或者源站端口绑定内网网卡让请求只能从内网跳到源站。独立引擎部署不等于自动安全网络层入口同样要收紧。5.3 SSL 证书自动续签失败的排查现象证书到期后没有自动续上浏览器访问提示不安全但 WAF 控制台上证书状态还显示正常。原因自动续签走 ACME 协议做域名校验要求 80 端口从公网可达同时域名解析必须指向当前机器。常见情况是解析切到了 CDN 或负载均衡上校验请求没到 SamWaf 本机。解决先验证校验路径是否可达# 检查 ACME 校验路径是否能从公网访问 curl -I http://your-domain/.well-known/acme-challenge/test如果返回 404 但能连通说明链路没问题等下一个续签周期会自动处理如果连接超时检查安全组是否放行 80 端口以及域名 A 记录是否指向本机 IP。证书续签是周期任务每次改过 DNS 或防火墙规则后主动手动触发一次续签是最稳妥的验证方式。另外源码里的 SSL 证书批量检测功能适合手里有多张证书的场景。我一般每月跑一次批量检测把到期时间在 30 天内的证书列出来提前处理不要等到站点断链了再去翻日志。批量检测脚本的导出列表里注意区分到期时间和最近续签时间两个字段有的证书刚续过签最近续签时间是新的但到期时间是明年的别被表象误导。6. 规则上线前的攻击验证curl 五连探与日志脱敏自查部署完成不等于防护生效规则真正能拦住攻击才算。我每次配置完规则都会用一组模拟攻击请求做上线前验证确认每类规则都工作在预期状态# 1. SQL 注入探测期望返回拦截页或非正常业务状态码 curl -i http://your-domain/item.php?id1 AND SLEEP(5)-- - # 2. XSS 探测编码后的 script 标签 curl -i http://your-domain/search?kw%3Cscript%3Ealert(1)%3C/script%3E # 3. 命令执行探测URL 参数拼接系统命令 curl -i http://your-domain/ping?ip127.0.0.1;id # 4. CC 高频模拟连续 500 次请求观察是否触发频率限制 ab -n 500 -c 50 http://your-domain/api/list # 5. 白名单确认健康检查接口必须放行 curl -i http://your-domain/api/health前三个验证 CRS 规则第四个验证 CC 阈值是否真正触发第五个确认白名单没有被误伤。逐个执行完检查响应码模拟攻击的请求应该落到拦截页状态码和自定义拦截界面一致健康检查请求必须正常返回业务状态。如果模拟攻击返回了正常页面说明规则没生效或配置没保存回去查对应规则开关。验证规则之后别忘了顺手做一次日志脱敏自查。开启“信息脱敏保存”和“指定界面数据隐私输出”后去日志页面看刚才几条攻击请求的原始记录POST body 里的参数应该显示为掩码而不是明文。如果还能看到完整手机号或 Token检查是不是脱敏开关没在对应分站生效或者脱敏字段配置不完整。从那以后我每次部署完 WAF 都强制把五连探测走一遍确定拦截、放行、脱敏三件事都符合预期才放心把解析切过来。这套流程救了我好几次希望帮到你。本文还有配套的精品资源点击获取
返回列表