故障排除
BunkerWeb 面板
如果您无法解决您的问题,您可以通过我们的面板直接联系我们。这里集中了与 BunkerWeb 解决方案相关的所有请求。
日志
在进行故障排除时,日志是您最好的朋友。我们尽力提供用户友好的日志,以帮助您了解正在发生的事情。
请注意,您可以将 LOG_LEVEL
设置为 info
(默认值为 notice
),以增加 BunkerWeb 的详细程度。
根据您的集成方式,以下是如何访问日志的方法:
列出容器
要列出正在运行的容器,您可以使用以下命令:
docker ps
您可以使用 docker logs
命令(将 bunkerweb
替换为您的容器名称):
docker logs bunkerweb
这是 docker-compose 的等效命令(将 bunkerweb
替换为 docker-compose.yml 文件中声明的服务名称):
docker-compose logs bunkerweb
列出容器
要列出正在运行的容器,您可以使用以下命令:
docker ps
您可以使用 docker logs
命令(将 bunkerweb
和 bw-autoconf
替换为您的容器名称):
docker logs bunkerweb
docker logs bw-autoconf
这是 docker-compose 的等效命令(将 bunkerweb
和 bw-autoconf
替换为 docker-compose.yml 文件中声明的服务名称):
docker-compose logs bunkerweb
docker-compose logs bw-autoconf
容器名称
一体化镜像的默认容器名称是 bunkerweb-aio
。如果您使用了不同的名称,请相应地调整命令。
您可以使用 docker logs
命令:
docker logs bunkerweb-aio
列出服务
要列出服务,您可以使用以下命令:
docker service ls
您可以使用 docker service logs
命令(将 bunkerweb
和 bw-autoconf
替换为您的服务名称):
docker service logs bunkerweb
docker service logs bw-autoconf
列出 Pod
要列出 Pod,您可以使用以下命令:
kubectl get pods
您可以使用 kubectl logs
命令(将 bunkerweb
和 bunkerweb-controler
替换为您的 Pod 名称):
kubectl logs bunkerweb
kubectl logs bunkerweb-controler
对于与 BunkerWeb 服务相关的错误(例如,无法启动),您可以使用 journalctl
:
journalctl -u bunkerweb --no-pager
通用日志位于 /var/log/bunkerweb
目录中:
cat /var/log/bunkerweb/error.log
cat /var/log/bunkerweb/access.log
权限
不要忘记,出于明显的安全原因,BunkerWeb 是以非特权用户身份运行的。请仔细检查 BunkerWeb 使用的文件和文件夹的权限,特别是如果您使用自定义配置(更多信息请参见此处)。您需要为文件设置至少 RW 权限,为文件夹设置 RWX 权限。
IP 解封
您可以手动解封一个 IP,这在进行测试时很有用,这样您就可以联系 BunkerWeb 的内部 API(将 1.2.3.4
替换为要解封的 IP 地址):
您可以使用 docker exec
命令(将 bw-scheduler
替换为您的容器名称):
docker exec bw-scheduler bwcli unban 1.2.3.4
这是 docker-compose 的等效命令(将 bw-scheduler
替换为 docker-compose.yml 文件中声明的服务名称):
docker-compose exec bw-scheduler bwcli unban 1.2.3.4
容器名称
一体化镜像的默认容器名称是 bunkerweb-aio
。如果您使用了不同的名称,请相应地调整命令。
您可以使用 docker exec
命令:
docker exec bunkerweb-aio bwcli unban 1.2.3.4
您可以使用 docker exec
命令(将 bw-scheduler
替换为您的服务名称):
docker exec $(docker ps -q -f name=bw-scheduler) bwcli unban 1.2.3.4
您可以使用 kubectl exec
命令(将 bunkerweb-scheduler
替换为您的 Pod 名称):
kubectl exec bunkerweb-scheduler bwcli unban 1.2.3.4
您可以使用 bwcli
命令(以 root 身份):
sudo bwcli unban 1.2.3.4
误报
仅检测模式
为了进行调试/测试,您可以将 BunkerWeb 设置为仅检测模式,这样它就不会阻止请求,而是像一个经典的反向代理一样工作。
ModSecurity
BunkerWeb 中 ModSecurity 的默认配置是以异常评分模式加载核心规则集,偏执级别 (PL) 为 1:
- 每条匹配的规则都会增加一个异常分数(因此许多规则可以匹配单个请求)
- PL1 包含误报率较低的规则(但安全性低于 PL4)
- 请求的异常分数默认阈值为 5,响应为 4
让我们以以下使用默认配置的 ModSecurity 检测日志为例(为了更好的可读性进行了格式化):
2022/04/26 12:01:10 [warn] 85#85: *11 ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `lfi-os-files.data' against variable `ARGS:id' (Value: `/etc/passwd' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"]
[line "78"]
[id "930120"]
[rev ""]
[msg "OS File Access Attempt"]
[data "Matched Data: etc/passwd found within ARGS:id: /etc/passwd"]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-multi"]
[tag "platform-multi"]
[tag "attack-lfi"]
[tag "paranoia-level/1"]
[tag "OWASP_CRS"]
[tag "capec/1000/255/153/126"]
[tag "PCI/6.5.4"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref "o1,10v9,11t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase"],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host: "localhost"
2022/04/26 12:01:10 [warn] 85#85: *11 ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:id' (Value: `/etc/passwd' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"]
[line "480"]
[id "932160"]
[rev ""]
[msg "Remote Command Execution: Unix Shell Code Found"]
[data "Matched Data: etc/passwd found within ARGS:id: /etc/passwd"]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-shell"]
[tag "platform-unix"]
[tag "attack-rce"]
[tag "paranoia-level/1"]
[tag "OWASP_CRS"]
[tag "capec/1000/152/248/88"]
[tag "PCI/6.5.2"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref "o1,10v9,11t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host: "localhost"
2022/04/26 12:01:10 [error] 85#85: *11 [client 172.17.0.1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `10' )
[file "/usr/share/bunkerweb/core/modsecurity/files/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"]
[line "80"]
[id "949110"]
[rev ""]
[msg "Inbound Anomaly Score Exceeded (Total Score: 10)"]
[data ""]
[severity "2"]
[ver "OWASP_CRS/3.3.2"]
[maturity "0"]
[accuracy "0"]
[tag "application-multi"]
[tag "language-multi"]
[tag "platform-multi"]
[tag "attack-generic"]
[hostname "172.17.0.2"]
[uri "/"]
[unique_id "165097447014.179282"]
[ref ""],
client: 172.17.0.1, server: localhost, request: "GET /?id=/etc/passwd HTTP/1.1", host: "localhost"
正如我们所见,有 3 条不同的日志:
- 规则 930120 匹配
- 规则 932160 匹配
- 访问被拒绝(规则 949110)
需要理解的一个重要事项是,规则 949110 并不是一个“真正”的规则:它是因为异常阈值达到(在本例中为 10)而拒绝请求的规则。您永远不应该删除 949110 规则!
如果是误报,您应该关注 930120 和 932160 规则。ModSecurity 和/或 CRS 的调整超出了本文档的范围,但不要忘记您可以在 CRS 加载前后应用自定义配置(更多信息请参见此处)。
不良行为
一个常见的误报情况是由于“不良行为”功能导致客户端被封禁,这意味着在一段时间内产生了过多的可疑 HTTP 状态码(更多信息请参见此处)。您应该首先查看设置,然后根据您的 Web 应用程序进行编辑,例如删除可疑的 HTTP 代码、减少计数时间、增加阈值等。
白名单
如果您有需要访问您网站的机器人(或管理员),推荐的方法是使用白名单功能将它们列入白名单,以避免任何误报。我们不建议使用 WHITELIST_URI*
或 WHITELIST_USER_AGENT*
设置,除非它们被设置为秘密且不可预测的值。常见的用例是:
- 健康检查/状态机器人
- 回调,如 IPN 或 webhook
- 社交媒体爬虫
常见错误
上游发送了过大的标头
如果您在日志中看到以下错误 upstream sent too big header while reading response header from upstream
,您将需要使用以下设置来调整各种代理缓冲区大小:
PROXY_BUFFERS
PROXY_BUFFER_SIZE
PROXY_BUSY_BUFFERS_SIZE
无法构建 server_names_hash
如果您在日志中看到以下错误 could not build server_names_hash, you should increase server_names_hash_bucket_size
,您将需要调整 SERVER_NAMES_HASH_BUCKET_SIZE
设置。
时区
当使用基于容器的集成时,容器的时区可能与主机的时区不匹配。要解决此问题,您可以在您的容器上将 TZ
环境变量设置为您选择的时区(例如 TZ=Europe/Paris
)。您可以在此处找到时区标识符的列表。
Web UI
如果您忘记了 UI 凭据或遇到 2FA 问题,您可以连接到数据库以重新获得访问权限。
访问数据库
安装 SQLite (Debian/Ubuntu):
sudo apt install sqlite3
安装 SQLite (Fedora/RedHat):
sudo dnf install sqlite
进入您的调度器容器的 shell:
Docker 参数
-u 0
选项用于以 root 身份运行命令(强制)-it
选项用于以交互方式运行命令(强制)<bunkerweb_scheduler_container>
:您的调度器容器的名称或 ID
docker exec -u 0 -it <bunkerweb_scheduler_container> bash
安装 SQLite:
apk add sqlite
进入您的 All-in-one 容器的 shell:
Docker 参数
-u 0
选项用于以 root 身份运行命令(强制)。-it
选项用于以交互方式运行命令(强制)。bunkerweb-aio
是默认的容器名称;如果您使用了自定义名称,请进行调整。
docker exec -u 0 -it bunkerweb-aio bash
访问您的数据库:
数据库路径
我们假设您正在使用默认的数据库路径。如果您正在使用自定义路径,您需要调整该命令。
对于 All-in-one,我们假设数据库是位于持久化 /data
卷中的 db.sqlite3
(/data/db.sqlite3
)。
sqlite3 /var/lib/bunkerweb/db.sqlite3
您应该会看到类似这样的内容:
SQLite version <VER> <DATE>
Enter ".help" for usage hints.
sqlite>
仅限 MariaDB / MySQL
以下步骤仅适用于 MariaDB / MySQL 数据库。如果您正在使用其他数据库,请参阅您数据库的文档。
凭据和数据库名称
您将需要使用 DATABASE_URI
设置中使用的相同凭据和数据库名称。
访问您的本地数据库:
mysql -u <user> -p <database>
然后输入数据库用户的密码,您就应该能够访问您的数据库了。
访问您的数据库容器:
Docker 参数
-u 0
选项用于以 root 身份运行命令(强制)-it
选项用于以交互方式运行命令(强制)<bunkerweb_db_container>
:您的数据库容器的名称或 ID<user>
:数据库用户<database>
:数据库名称
docker exec -u 0 -it <bunkerweb_db_container> mysql -u <user> -p <database>
然后输入数据库用户的密码,您就应该能够访问您的数据库了。
一体化镜像不包含 MariaDB/MySQL 服务器。如果您已将 AIO 配置为使用外部 MariaDB/MySQL 数据库(通过设置 DATABASE_URI
环境变量),您应使用标准的 MySQL 客户端工具直接连接到该数据库。
连接方法将类似于“Linux”选项卡(如果从运行 AIO 的主机或另一台机器连接),或者如果愿意,可以在一个单独的 Docker 容器中运行 MySQL 客户端,并指定您的外部数据库的主机和凭据。
仅限 PostgreSQL
以下步骤仅适用于 PostgreSQL 数据库。如果您正在使用其他数据库,请参阅您数据库的文档。
凭据、主机和数据库名称
您将需要使用 DATABASE_URI
设置中使用的相同凭据(用户/密码)、主机和数据库名称。
访问您的本地数据库:
psql -U <user> -d <database>
如果您的数据库在另一台主机上,请包含主机名/IP 和端口:
psql -h <host> -p 5432 -U <user> -d <database>
然后输入数据库用户的密码,您就应该能够访问您的数据库了。
访问您的数据库容器:
Docker 参数
-u 0
选项用于以 root 身份运行命令(强制)-it
选项用于以交互方式运行命令(强制)<bunkerweb_db_container>
:您的数据库容器的名称或 ID<user>
:数据库用户<database>
:数据库名称
docker exec -u 0 -it <bunkerweb_db_container> psql -U <user> -d <database>
如果数据库托管在其他地方,请相应地添加 -h <host>
和 -p 5432
选项。
一体化镜像不包含 PostgreSQL 服务器。如果您已将 AIO 配置为使用外部 PostgreSQL 数据库(通过设置 DATABASE_URI
环境变量),您应使用标准的 PostgreSQL 客户端工具直接连接到该数据库。
连接方法将类似于“Linux”选项卡(如果从运行 AIO 的主机或另一台机器连接),或者如果愿意,可以在一个单独的 Docker 容器中运行 PostgreSQL 客户端,并指定您的外部数据库的主机和凭据。
故障排除操作
表模式
bw_ui_users
表的模式如下:
字段 | 类型 | 空 | 键 | 默认 | 额外 |
---|---|---|---|---|---|
username | varchar(256) | NO | PRI | NULL | |
varchar(256) | YES | UNI | NULL | ||
password | varchar(60) | NO | NULL | ||
method | enum('ui','scheduler','autoconf','manual','wizard') | NO | NULL | ||
admin | tinyint(1) | NO | NULL | ||
theme | enum('light','dark') | NO | NULL | ||
language | varchar(2) | NO | NULL | ||
totp_secret | varchar(256) | YES | NULL | ||
creation_date | datetime | NO | NULL | ||
update_date | datetime | NO | NULL |
执行以下命令从 bw_ui_users
表中提取数据:
SELECT * FROM bw_ui_users;
您应该会看到类似这样的内容:
用户名 | 电子邮件 | 密码 | 方法 | 管理员 | 主题 | totp_secret | 创建日期 | 更新日期 |
---|---|---|---|---|---|---|---|---|
*** | *** | *** | manual | 1 | light | *** | *** | *** |
您首先需要使用 bcrypt 算法对新密码进行哈希处理。
安装 Python bcrypt 库:
pip install bcrypt
生成您的哈希值(将 mypassword
替换为您自己的密码):
python3 -c 'from bcrypt import hashpw, gensalt ; print(hashpw(b"""mypassword""", gensalt(rounds=10)).decode("utf-8"))'
您可以通过执行此命令来更新您的用户名/密码:
UPDATE bw_ui_users SET password = '<password_hash>' WHERE admin = 1;
如果您在此命令之后再次检查您的 bw_ui_users
表:
SELECT * FROM bw_ui_users WHERE admin = 1;
您应该会看到类似这样的内容:
用户名 | 电子邮件 | 密码 | 方法 | 管理员 | 主题 | totp_secret | 创建日期 | 更新日期 |
---|---|---|---|---|---|---|---|---|
*** | *** | *** | manual | 1 | light | *** | *** | *** |
您现在应该能够使用新凭据登录到 Web UI。
您可以通过执行此命令来停用 2FA:
UPDATE bw_ui_users SET totp_secret = NULL WHERE admin = 1;
如果您在此命令之后再次检查您的 bw_ui_users
表:
SELECT * FROM bw_ui_users WHERE admin = 1;
您应该会看到类似这样的内容:
用户名 | 电子邮件 | 密码 | 方法 | 管理员 | 主题 | totp_secret | 创建日期 | 更新日期 |
---|---|---|---|---|---|---|---|---|
*** | *** | *** | manual | 1 | light | NULL | *** | *** |
您现在应该能够仅使用您的用户名和密码登录 Web UI,而无需 2FA。
恢复码可以在 Web UI 的个人资料页面的 安全
选项卡下刷新。
使用 Web UI 中的支持页面来快速收集配置和日志以进行故障排除。
- 打开 Web UI 并转到支持页面。
- 选择范围:导出全局配置或选择特定服务。
- 点击下载所选范围的配置存档。
- 可选地下载日志:导出的日志会自动匿名化(所有 IP 地址和域名都被屏蔽)。
上传插件
在某些情况下,可能无法从 UI 上传插件:
- 您的集成缺少管理压缩文件的软件包,在这种情况下,您需要添加必要的软件包
- Safari 浏览器:'安全模式'可能会阻止您添加插件。您需要在您的机器上进行必要的更改