TOTP Vault DocsDeployment & Recovery
TOTP VAULT · OPERATIONS GUIDE · v1.2.0

故障排查

第七章 故障排查

说明

按实际部署中出现过的错误逐项定位,不再靠猜。

#38. 实际部署中遇到的问题与解决方法

说明

🧯 用途:故障排查;先看症状,再执行对应检查命令

下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。

#38.1 Composer 报 putenv undefined

报错:

Call to undefined function Composer\XdebugHandler\putenv()

旧版原因:宝塔禁用了 putenv,但安装脚本强行运行 Composer。

最终版:

如果 putenv 不可用,install.sh 自动跳过 Composer。
项目已经自带 vendor/autoload.php。

如果仍想运行 Composer:

宝塔 → PHP 8.2 → 禁用函数 → 删除 putenv → 重启 PHP

#38.2 age binary FAIL

旧报错:

[FAIL] age binary /usr/local/bin/age

Ubuntu apt 实际:

/usr/bin/age

最终版安装脚本自动执行等效:

command -v age

并写入 .env

手动修复:

cd /www/wwwroot/2fa.example.com
AGE_PATH="$(command -v age)"
sed -i "s#^AGE_BINARY=.*#AGE_BINARY=${AGE_PATH}#" .env
grep '^AGE_BINARY=' .env

#38.3 网站浏览器 ERR_CONNECTION_CLOSED

检查:

ufw status verbose
ss -lntp | grep -E ':80|:443'
/www/server/nginx/sbin/nginx -t
getent ahostsv4 2fa.example.com

云安全组必须开放 TCP 80/443。


#38.4 HTTPS 本机返回 404

检查:

grep -nE 'server_name|root|include enable-php|fastcgi_pass' /www/server/panel/vhost/nginx/2fa.example.com.conf

必须:

root /www/wwwroot/2fa.example.com/public;

必须有:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

不要同时保留一个冲突的默认 PHP location。

最终版 Router 也已经把 HEAD 当 GET,避免旧版 curl -I 假 404。


#38.5 CLI 说管理员存在,网页却说未创建管理员并 500

典型命令:

sudo -u www /www/server/php/82/bin/php artisan totp:health

旧报错:

ERROR: Unable to create database directory.

原因:

/www/server/totp-vault

父目录是 root:root 700,www 无法穿过。

手动修复:

chown root:www /www/server/totp-vault
chmod 750 /www/server/totp-vault
chown -R www:www /www/server/totp-vault/data
chown -R www:www /www/server/totp-vault/secrets
chown -R www:www /www/server/totp-vault/tmp
chmod 700 /www/server/totp-vault/data
chmod 700 /www/server/totp-vault/secrets
chmod 700 /www/server/totp-vault/tmp
chmod 600 /www/server/totp-vault/data/database.sqlite
chmod 600 /www/server/totp-vault/secrets/vault.key

最终版安装脚本已自动处理父目录。


#38.6 open_basedir 导致数据库或 vault.key 无法访问

检查:

find /www/wwwroot/2fa.example.com -maxdepth 2 -name '.user.ini' -print

部署阶段关闭宝塔“防跨站攻击”。

不要用 chmod -R 777 解决。


#38.7 Graph Explorer 查到的是 User ID,不是 Drive

旧版曾需要 Drive ID,容易误填用户 Object ID。

最终 v1.2.0:

完全不需要 Drive ID。

不要再配置 Drive ID。


#38.8 Files.ReadWrite.AppFolder + client_credentials 返回 400

旧架构:

Application Files.ReadWrite.AppFolder
/drives/{drive-id}/special/approot

实际企业 OneDrive 环境中返回:

HTTP 400 invalidRequest

最终版已经取消该架构。


#38.9 点击“连接 Microsoft OneDrive”没反应

原因:CSP 仍是:

form-action 'self'

OAuth POST 后跳 Microsoft 被浏览器拦截。

最终 PHP + Nginx CSP 必须:

form-action 'self' https://login.microsoftonline.com

最终源码已修复。


#38.10 Microsoft 授权成功,但 callback 显示 Graph 400

旧 Delegated 热修复仍使用:

/me/drive/special/approot

最终版取消 approot,改为:

/me/drive/root:/TOTP-Vault-Backup
/me/drive/root:/TOTP-Vault-Backup/Backups

#38.11 备份报 proc_open undefined

报错:

Call to undefined function TotpVault\Services\proc_open()

处理:

宝塔 → PHP 8.2 → 禁用函数 → 删除 proc_open → 重启 PHP

检查:

/www/server/php/82/bin/php -r '
echo function_exists("proc_open") ? "AVAILABLE\n" : "DISABLED\n";
'

proc_open 必须长期可用。

最终健康检查会把它作为阻断项。