2. 安装
本章适用于 Linux 服务器(CentOS 7+ / Ubuntu 18.04+ / Debian 10+)。Windows 版本暂不提供。
2.1 开始之前:三样东西必须先有
畅来WAF 不是一个二进制跑起来就完事,它依赖两个外部服务。这两样在交付包的部署说明里没写全,很多人卡在这一步。
| 依赖 | 版本要求 | 为什么必需 |
|---|---|---|
| MySQL | 8.0 及以上 | 建表语句用了 utf8mb4_0900_ai_ci 排序规则,MySQL 5.7 不支持,导入会直接失败 |
| Redis | 5.0 及以上 | 存 QPS 计数器、人机验证会话、CC 限频计数。没有 Redis,人机验证和 CC 防护全部不可用 |
剩下的是系统层面:
| 项 | 要求 |
|---|---|
| 内存 | 建议 2G 以上 |
| 文件描述符 | LimitNOFILE 至少 65535,WAF 要撑大量并发连接 |
| 端口 | 业务端口(如 80/443)、后台端口(默认 49463) |
| 权限 | 绑定 80/443 需要 root 或 CAP_NET_BIND_SERVICE |
先确认 MySQL 版本和 Redis 连通性,再往下走:
mysql -uroot -p -e "select version()"
redis-cli ping # 返回 PONG 才算通
2.2 交付包结构
解压后是这样一个目录,所有文件必须放在同一层,程序靠当前工作目录找配置和页面:
waf/
├── wafd 进程守护,唯一入口,托管下面三个
├── waf WAF 引擎(由 wafd 拉起,不要单独启动)
├── admin 后台管理(由 wafd 拉起)
├── cron 定时任务(由 wafd 拉起)
├── wafctl.sh 一键启停脚本
├── config/
│ ├── app.json 端口、日志路径
│ ├── database.json MySQL / Redis 连接
│ └── custom.json 密钥、云平台地址(交付时留空)
├── web/ 后台页面与静态资源
├── sql/init.sql 建库脚本,全新安装时自动导入
└── 部署说明.txt
2.3 部署
第一步:解压
mkdir -p /usr/local/waf
tar -zxvf waf-free-v1.1.0.tar.gz -C /usr/local/waf --strip-components=1
cd /usr/local/waf
用
--strip-components=1可以去掉压缩包里的顶层目录,避免变成/usr/local/waf/waf-free-v1.1.0/这种嵌套。
第二步:填数据库连接
编辑 config/database.json,只需要改 mysql.default 这一段:
{
"mysql": {
"default": {
"host": "127.0.0.1",
"port": "3306",
"user": "root",
"pwd": "你的密码",
"dbname": "waf",
"charset": "utf8mb4",
"pre": "waf_"
}
}
}
| 字段 | 说明 |
|---|---|
host | 建议写 127.0.0.1 而不是 localhost,避免走 socket 造成权限账号不匹配 |
dbname | 库名,不存在会自动创建 |
pre | 表前缀,不要改,改了就找不到表 |
redis.default | 默认 127.0.0.1:6379,密码为空。Redis 有密码就填 pwd |
第三步:启动
./wafctl.sh start
这一条命令会依次做四件事:
- 执行数据库初始化检查(
admin -initdb)
- 连不上:打印分步排查说明(MySQL 是否启动、账号权限、防火墙)
- 空库:自动建库并导入 sql/init.sql,然后打印默认管理员账号
- 已初始化:直接跳过
- 后台拉起
waf、admin、cron三个子进程 - 轮询等待启动完成(最多 30 秒)
- 打印三个进程状态
看到类似输出才算成功:
名称 PID 运行时长 自动重启
waf 12345 3s 0
admin 12346 3s 0
cron 12347 3s 0
第四步:访问后台
浏览器打开 http://服务器IP:49463(端口见 config/app.json 的 admin.http.addr)。
默认账号 admin / admin123,首次登录后立刻改密码。
2.4 后台端口在哪里改
后台默认监听 49463,这个端口写在一个地方:config/app.json 的 admin.http.addr。
{
"admin": {
"http": {
"addr": ":49463"
}
}
}
说明:
| 项 | 说明 |
|---|---|
| 配置位置 | config/app.json → admin.http.addr |
| 格式 | :端口 表示监听本机所有网卡;127.0.0.1:端口 表示只监听本机(配合 SSH 隧道或反向代理访问,更安全) |
| 改完生效 | ./wafctl.sh restart(systemd 托管则 systemctl restart wafd),配置不支持热生效 |
| 同步动作 | 防火墙/安全组放行新端口,旧端口规则删掉 |
改端口完整示例(改成 8443):
# 1. 编辑配置
vim config/app.json
# 把 "addr": ":49463" 改为 "addr": ":8443"
# 2. 重启生效
./wafctl.sh restart
# 3. 防火墙放行(firewalld 为例)
firewall-cmd --permanent --add-port=8443/tcp
firewall-cmd --reload
# 4. 验证
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8443/login.html
注意区分两种端口:
admin.http.addr是后台管理端口;各站点的业务端口(80/443)是在后台「站点管理」里按站点配置的,两者互不相干。业务端口不需要写进app.json。
安全建议:后台端口不要对公网裸奔。两种做法任选其一:
- 防火墙限制来源 IP,只允许自己的办公网段访问(见 3.6 节的 iptables 示例)
addr改成127.0.0.1:49463,外网完全无法直连,需要时通过 SSH 隧道访问:
ssh -L 49463:127.0.0.1:49463 root@服务器IP
# 然后本机浏览器打开 http://127.0.0.1:49463
2.5 三个配置文件到底改哪个
| 文件 | 什么时候改 | 交付时状态 |
|---|---|---|
database.json | 必改,填 MySQL 密码 | 密码留空 |
custom.json | 一般不用改 | 全部留空,首次启动自动生成 |
app.json | 改端口时才动 | 默认 49463 |
custom.json 里的三项说明:
| 字段 | 说明 |
|---|---|
admin_session_secret | 后台会话加密密钥。留空即可,admin 首次启动自动生成随机密钥写回 |
license_secret | 实例签名密钥。留空即可,首次启动自动向云平台注册并颁发写回 |
platform_base_url | 云平台地址。为空则所有云平台功能自动禁用(云规则库、爬虫共享库、授权激活) |
免费版如果不需要云规则库和爬虫共享库,
platform_base_url可以一直留空,不影响本地防护。
2.6 开机自启
Linux 用 systemd 托管。创建 /etc/systemd/system/wafd.service:
[Unit]
Description=WAF Daemon (waf/admin/cron)
After=network-online.target mysqld.service redis.service
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/usr/local/waf
ExecStart=/usr/local/waf/wafd start
Restart=always
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
启用:
systemctl daemon-reload
systemctl enable --now wafd
WorkingDirectory必须写真实安装路径,写错就找不到config/和web/。服务托管后,停止和重启一律用
systemctl stop/restart wafd。因为配了Restart=always,直接执行wafctl.sh stop会被 systemd 立刻拉起来。
2.7 日常运维命令
| 命令 | 作用 |
|---|---|
./wafctl.sh status | 看三个进程的 pid、运行时长、累计自动重启次数 |
./wafctl.sh restart | 全量重启三个子进程(wafd 本身不退出) |
./wafctl.sh stop | 停机,人为停机不会被自动拉起 |
./wafctl.sh initdb | 手动执行数据库检查(排障用) |
进程崩溃时 wafd 会自动重启,规则是:
- 普通崩溃:立即重启,
status里的「自动重启」次数 +1 - 10 分钟内反复崩 3 次以上:进入指数退避,最长 30 分钟一次
- 稳定运行满 10 分钟:恢复正常重启间隔
- 连续 3 次「启动后 10 秒内退出」:判定为不可恢复故障(典型原因:端口被占用、数据库不可达、配置错误),wafd 直接停掉全部进程并打印该进程日志末尾,不会无限重试空转
2.8 升级
./wafctl.sh stop
# 覆盖二进制文件(config/ 和 web/ 保持不变)
./wafctl.sh start
注意:存量升级不要对已有数据执行 init.sql,会清表。版本间的表结构变更需要执行对应的 alter_*.sql。
2.9 安装失败怎么查
| 现象 | 原因 | 处理 |
|---|---|---|
MySQL Ping失败: Error 1045 | 账号密码不对,或 host 用了 localhost 走了 socket 权限 | 改成 127.0.0.1,核对密码 |
Redis 连接失败 | Redis 没启动或端口不对 | redis-cli -h 127.0.0.1 -p 6379 ping |
| 启动后 30 秒仍未运行 | 看 runtime/log/wafd/daemon.out.log | 日志里会写哪个子进程失败 |
| 全部站点端口监听失败 | 80/443 被 Nginx 占用 | 先停 Nginx,或给站点换端口 |
建表报 Unknown collation: utf8mb4_0900_ai_ci | MySQL 是 5.7 | 必须升到 8.0 |
日志位置:
| 路径 | 内容 |
|---|---|
runtime/log/wafd/daemon.out.log | 守护日志(子进程退出、重启、退避) |
runtime/log/wafd/<名称>.out.log | 各子进程控制台输出,含 panic 堆栈 |
runtime/log/engine|admin|cron/ | 各进程结构化业务日志 |
下一步:3. 首次登录