SamWaf v1.3.20:轻量私有 WAF 的实用升级,隧道 SSL 与压缩终于到位

2026-05-28 27 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:8 分钟

对小团队和独立开发者来说,网站防火墙往往处在"想用但嫌重"的尴尬位置——商业 WAF 按域名收费、云 WAF 要把流量过别人的节点,而自建 ModSecurity 规则维护成本不低。SamWaf 走的是另一条路:开源、单机私有部署、轻量到一台低配 VPS 就能跑。v1.3.20 这版补上了几个被反复催的功能,尤其是隧道 SSL 和压缩支持,让它在内网穿透和零信任场景下真正可用。

这次升级解决了什么

隧道 SSL:内网穿透不再裸奔

之前 SamWaf 的隧道模式只转发 TCP 流量,没有 TLS 加密。实际使用中,内网服务通过 FRP、NPS 等工具暴露到公网时,如果 WAF 隧道段不加密,等于在公网留了一段明文通道。v1.3.20 加了隧道 SSL 支持,WAF 本身充当 TLS 终端或中继,适用于三种典型场景:

  • 内网穿透:外部请求 → SSL 隧道 → SamWaf → 内网 HTTP 服务,公网段全程加密。
  • 跨网络安全通信:两个隔离网络之间通过 WAF 隧道建立加密通道,避免中间链路窃听。
  • 零信任架构:每个服务入口都经过 WAF 的 TLS 校验与访问控制,而非依赖网络边界信任。

站点压缩:gzip 与 Brotli

之前版本不做响应压缩,小带宽环境下静态资源加载慢。现在支持 gzip 和 Brotli(br)两种压缩,可以按站点单独开关。Brotli 在现代浏览器上压缩率比 gzip 高 15-25%,对文本类资源效果明显。

静态服务响应头自定义

安全头(X-Content-Type-OptionsContent-Security-Policy 等)和业务头(Cache-Control、自定义 CORS 头)终于可以在 WAF 层统一配置,不用再改后端代码或 Nginx 配置。

开放平台与统计查询

新增的开放平台接口让外部系统可以拉取网站访问统计、攻击日志等数据,方便接入 Grafana 或内部监控面板。

实战:用 Docker 部署并配置隧道 SSL

下面是一个最小可运行的部署示例,假设你要把内网一个 HTTP API 服务通过 SamWaf 的 SSL 隧道安全暴露到公网。

1. 拉取镜像并启动

docker run -d \
  --name samwaf \
  -p 443:443 \
  -p 80:80 \
  -p 9999:9999 \
  -v /opt/samwaf/data:/app/data \
  -v /opt/samwaf/logs:/app/logs \
  -v /opt/samwaf/certs:/app/certs \
  --restart unless-stopped \
  samwaf/samwaf:latest

管理面板默认在 http://你的服务器IP:9999,首次访问设置管理员密码。

2. 准备 SSL 证书

把域名证书放到容器映射的 certs 目录:

# 假设你已经用 acme.sh 或其他工具申请了证书
mkdir -p /opt/samwaf/certs
cp /root/.acme.sh/yourdomain.com/fullchain.cer /opt/samwaf/certs/
cp /root/.acme.sh/yourdomain.com/yourdomain.com.key /opt/samwaf/certs/

3. 在管理面板配置隧道 SSL 站点

进入面板后操作路径:网站管理 → 添加站点 → 选择隧道模式,关键配置项:

配置项 说明
监听端口 443 外部 HTTPS 入口
隧道目标 10.0.0.5:8080 内网 HTTP API 地址
SSL 开关 启用 隧道启用 TLS
证书路径 /app/certs/fullchain.cer 容器内路径
密钥路径 /app/certs/yourdomain.com.key 容器内路径

保存后,外部请求流程变为:

客户端 HTTPS → SamWaf:443 (TLS 终端 + WAF 规则检测) → 隧道转发 → 10.0.0.5:8080

内网服务无需自己配置证书,TLS 由 WAF 层统一处理。

4. 添加安全响应头

在同一站点的"响应头自定义"中添加:

# 在管理面板的响应头配置区域逐条添加,这里用 YAML 格式方便阅读
response_headers:
  - name: X-Content-Type-Options
    value: nosniff
  - name: X-Frame-Options
    value: DENY
  - name: Strict-Transport-Security
    value: "max-age=63072000; includeSubDomains"
  - name: Content-Security-Policy
    value: "default-src 'self'; script-src 'self'"
  - name: X-XSS-Protection
    value: "1; mode=block"

这些头在 WAF 层注入,后端服务完全不用改。

5. 开启 Brotli 压缩

站点配置中找到压缩选项,启用 br + gzip。浏览器通过 Accept-Encoding 头自动协商,SamWaf 会优先返回 Brotli 压缩的响应。

开放平台:把攻击日志拉到 Grafana

新增的开放平台 API 可以用简单脚本对接监控系统。一个 Python 定时拉取的例子:

import requests
import json
from datetime import datetime, timedelta

SAMWAF_HOST = "https://yourdomain.com:9999"
API_TOKEN = "你的开放平台Token"  # 在管理面板 → 开放平台 中生成

headers = {"Authorization": f"Bearer {API_TOKEN}"}

# 查询最近1小时的攻击日志
params = {
    "start_time": (datetime.now() - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S"),
    "end_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
}

resp = requests.get(
    f"{SAMWAF_HOST}/openapi/log/attack",
    headers=headers,
    params=params,
    timeout=10,
)

attacks = resp.json().get("data", [])
print(f"最近1小时拦截攻击: {len(attacks)} 次")

# 按攻击类型统计,可推送到 Grafana / Prometheus
type_counts = {}
for a in attacks:
    t = a.get("attack_type", "unknown")
    type_counts[t] = type_counts.get(t, 0) + 1

for t, c in type_counts.items():
    print(f"  {t}: {c}")

运行前需要先在面板生成 Token,并确保管理端口可访问。

选用 SamWaf 的几个现实考量

适合的场景:

  • 个人站点、小团队内部系统,不想把流量过第三方云 WAF。
  • 内网穿透需要 TLS 加密 + 入口防护的组合。
  • 已有 Nginx 反代但不想在 Nginx 上维护 WAF 规则集。

需要注意的边界:

  • 单机部署,没有集群同步机制——多节点场景需要自己做配置同步。
  • 规则库更新依赖社区贡献,攻击覆盖面不如商业 WAF 的云端规则库。
  • 隧道 SSL 目前是 TLS 终端模式,如果后端服务本身也是 HTTPS,需要确认是否需要双向 TLS 或改用纯转发模式。

升级建议:

已经在跑旧版的,这版建议尽快升级——修复了多处逻辑缺陷和稳定性问题,压缩和响应头自定义是日常高频需求。新部署的话,Docker 一行命令就能跑起来,先在测试域名上验证规则和隧道配置,再切到生产域名。


相关推荐