项目安装与上线
第四章 项目安装与上线
说明上传最终源码、执行安装脚本、修复权限、配置 Nginx/SSL 并完成后台首次登录。
#19. 上传最终源码
服务器 SSH / 终端🖥️ 执行位置:服务器 SSH / 终端
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
最终 ZIP:
TOTP-Vault-v1.2.0-Baota-Final-20260824.zip
上传到:
/www/wwwroot
终端:
cd /www/wwwroot
unzip TOTP-Vault-v1.2.0-Baota-Final-20260824.zip
如果 ZIP 解压得到:
/www/wwwroot/totp-vault
移动为你的站点目录:
rm -rf /www/wwwroot/2fa.example.com/*
cp -a /www/wwwroot/totp-vault/. /www/wwwroot/2fa.example.com/
rm -rf /www/wwwroot/totp-vault
注意:如果网站目录里已有重要文件,不要先执行 rm -rf。首次空站才使用上面的清理命令。
检查:
cd /www/wwwroot/2fa.example.com
ls -la
必须能看到:
.env.example
artisan
bootstrap.php
app
public
routes
scripts
storage
vendor
tools
#20. 执行最终安装脚本
服务器 SSH / 终端🖥️ 执行位置:服务器 SSH / 终端
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
cd /www/wwwroot/2fa.example.com
export PATH=/www/server/php/82/bin:$PATH
php -v
bash scripts/install.sh
填写:
#20.1 正式网站地址
https://2fa.example.com
#20.2 SQLite
SQLite 路径 [/www/server/totp-vault/data/database.sqlite]:
直接 Enter。
#20.3 vault.key
vault.key 路径 [/www/server/totp-vault/secrets/vault.key]:
直接 Enter。
#20.4 secure-store.enc
加密配置路径 [/www/server/totp-vault/secrets/secure-store.enc]:
直接 Enter。
#20.5 PHP-FPM 用户
PHP-FPM 用户 [www]:
直接 Enter。
#20.6 管理员
设置唯一管理员用户名与强密码。
如果安装中断后重新执行:
bash scripts/install.sh
最终脚本会检测已有管理员并自动跳过,不会重复创建。
#21. 安装后权限检查
服务器 SSH / 终端🖥️ 执行位置:服务器 SSH / 终端
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
namei -l /www/server/totp-vault/data/database.sqlite
ls -ld /www/server/totp-vault
ls -ld /www/server/totp-vault/data
ls -ld /www/server/totp-vault/secrets
ls -ld /www/server/totp-vault/tmp
ls -l /www/server/totp-vault/data/database.sqlite
ls -l /www/server/totp-vault/secrets/vault.key
推荐:
/www/server/totp-vault root:www 750
data www:www 700
secrets www:www 700
tmp www:www 700
database.sqlite www:www 600
vault.key www:www 600
用网页运行用户检查:
sudo -u www test -r /www/server/totp-vault/data/database.sqlite && echo 'DB READ OK' || echo 'DB READ FAIL'
sudo -u www test -w /www/server/totp-vault/data/database.sqlite && echo 'DB WRITE OK' || echo 'DB WRITE FAIL'
sudo -u www test -w /www/server/totp-vault/data && echo 'DB DIR WRITE OK' || echo 'DB DIR WRITE FAIL'
必须:
DB READ OK
DB WRITE OK
DB DIR WRITE OK
#22. 宝塔运行目录
宝塔面板🧰 执行位置:宝塔面板(部分步骤配合 SSH)
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
宝塔 → 网站 → 站点 → 网站目录
设置:
网站目录:/www/wwwroot/2fa.example.com
运行目录:/public
最终 Nginx root 必须:
/www/wwwroot/2fa.example.com/public
#23. Nginx 最终配置
宝塔面板🧰 执行位置:宝塔面板(部分步骤配合 SSH)
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
项目自带:
docs/nginx-baota-location.conf
先生成适合当前域名的临时版本:
cd /www/wwwroot/2fa.example.com
DOMAIN='2fa.example.com'
PHP_VER='82'
sed "s#SITE_PATH#$DOMAIN#g; s#php-cgi-82#php-cgi-$PHP_VER#g" docs/nginx-baota-location.conf > /root/totp-nginx-location.conf
cat /root/totp-nginx-location.conf
把输出的 location、安全响应头等规则整合到宝塔当前 HTTPS server {} 中。
必须:
root /www/wwwroot/2fa.example.com/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Direct TOTP:Secret 位于 URL 中,因此该路径不写访问日志。
location ^~ /2fa/ {
access_log off;
log_not_found off;
error_log /dev/null crit;
try_files /index.php =404;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-cgi-82.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param HTTP_PROXY "";
fastcgi_read_timeout 60s;
fastcgi_hide_header X-Powered-By;
}
location = /index.php {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/tmp/php-cgi-82.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_hide_header X-Powered-By;
}
location ~ \.php(?:/|$) {
return 404;
}
CSP 必须包含:
form-action 'self' https://login.microsoftonline.com
否则点击“连接 Microsoft OneDrive”后浏览器可能不跳 Microsoft 登录页。
不要同时保留宝塔默认:
include enable-php-82.conf;
如果它会再创建任意 PHP 执行规则,就删除该 include,使用上面的精确 /index.php 规则。
检查:
/www/server/nginx/sbin/nginx -t
必须:
syntax is ok
test is successful
然后:
/etc/init.d/nginx reload
#24. SSL
宝塔面板🧰 执行位置:宝塔面板(部分步骤配合 SSH)
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
宝塔 → 网站 → SSL → Let's Encrypt
申请后开启:
强制 HTTPS
检查:
ss -lntp | grep -E ':80|:443'
#25. 本机 HTTPS 测试
服务器 SSH / 终端🖥️ 执行位置:服务器 SSH / 终端
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
不要只用旧版程序的 HEAD 结果判断。 最终版已经兼容 HEAD,但建议测试真实 GET:
curl -k --resolve 2fa.example.com:443:127.0.0.1 \
https://2fa.example.com/ \
-o /dev/null \
-w 'HTTP_CODE=%{http_code}\n'
正常:
HTTP_CODE=200
后台:
curl -k --resolve 2fa.example.com:443:127.0.0.1 \
https://2fa.example.com/admin \
-o /dev/null \
-w 'HTTP_CODE=%{http_code}\nREDIRECT=%{redirect_url}\n'
未登录通常:
302
/admin/login
#26. 基础健康检查
服务器 SSH / 终端🖥️ 执行位置:服务器 SSH / 终端
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
cd /www/wwwroot/2fa.example.com
sudo -u www /www/server/php/82/bin/php artisan totp:migrate
sudo -u www /www/server/php/82/bin/php artisan totp:test
sudo -u www /www/server/php/82/bin/php artisan totp:health
重点必须 PASS:
PHP version
pdo_sqlite
sodium
curl
json
mbstring
SQLite connection
Database outside web root
Vault key
Vault key outside web root
Vault key permissions
storage writable
Backup temp writable
HTTPS URL
APP_DEBUG
proc_open
age binary
tar binary
OneDrive/备份/计划任务尚未配置时 WARN 正常。
#27. 管理员后台
浏览器 / Microsoft Entra🌐 执行位置:浏览器 / Microsoft Entra / 网站后台
下方命令块可以直接复制;带“检查/预期”的内容用于核对结果,不要当作命令输入。
打开:
https://2fa.example.com/admin
登录后立即:
安全设置 → 开启管理员 MFA
管理员 MFA 不要只保存在这个 Vault 自己内部。