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 必须长期可用。
最终健康检查会把它作为阻断项。