Files
nxxy335 25a2e8a42c 文档部署到 /ny-exam-platform 子路径 + 移除快照/趋势/异常 + 打印与 UI 全面完善
文档站(#88)
- base 默认改为 /ny-exam-platform/,可用 DOCS_BASE=/ 覆盖本地预览
- 新增 DOCS_OUT 环境变量,避免构建时清空输出目录失败导致产物半截
- 新增 tools/docs-preview.js:按子路径重写路由的本地预览服务
- 删除 docs/guide/snapshot.md,同步清理全部相关文档

移除存快照 / 趋势 / 异常(#89)
- 后端:删除 api.php 的 snapshot_save/list/delete/trend 四个 action 与
  $WRITE_ACTIONS 中的同名条目;删除 lib/Snapshot.php 与自动加载注册;
  DataService 移除 detectAnomalies() 及其调用
- 前端:移除三个按钮与三个弹窗、相关 JS 处理与 state 字段
- 测试:移除对应用例,补充 5 条名单导入列识别断言(17+9+18+32+29+11 全过)

打印完善(#90)
- 改用隐藏 iframe 输出,规避弹窗拦截;@page A4 支持纵向/横向
- 表头每页重复、行内不跨页断开、全表连续名次、可选「是否合格」列
- 分组小计(人数/平均/最高/最低/合格人数与合格率)、可附缺考名单另起一页
- 末尾签字栏;缺考名单打印改为同一套输出

UI / 交互 / Bug 修复(#91)
- dashboard.php:补「← 主系统 / 退出」入口(此前全屏后无法离开);
  修复成员下钻 onclick 里 JSON.stringify 双引号提前闭合属性导致点击报错,
  改为 data-sid 事件委托;补 Esc 关弹窗;后台标签页暂停轮询、切回自动补拉;
  刷新中断原因写入 title;数值字段统一兜底,避免 NaN / undefined%
- draw.php / draw.js:结果表新增「登陆账号」列(导出前可核对,缺失显示 学号 ⚠);
  弹窗只关最上层且支持 Esc;「全部」改为跟随候选池,手工改人数即解除;
  候选池不足时给出明确提示;自定义比例框隐藏时清空,避免旧权重被误读
- app.js / dashboard.php:成绩着色改为按「占本卷满分的百分比」判断,
  修复满分不是 100 时整列误标红
- style.css:数值列右对齐;新增 subbar、draw-stage-sub;
  看板顶栏窄屏下拉与按钮换行,消除横向滚动
2026-09-11 16:23:08 +08:00

156 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部署加固清单
按 **P0 → P2** 顺序执行。P0 不做等于把配置和名单暴露在公网上。
## P0:屏蔽数据目录(必做)
`data/` 位于 Web 根目录内,里面有 `ny.db`(配置 / 名单 / 卷王账号密码)、
`config.json`、`roster.json`、令牌缓存。**必须禁止直接访问。**
### nginx(生产环境默认,必做)
```nginx
location ^~ /data/ {
deny all;
return 404;
}
```
若站点部署在子路径下(例如 `/index/`),改为对应的前缀:
```nginx
location ^~ /index/data/ {
deny all;
return 404;
}
```
```bash
nginx -t && nginx -s reload
```
验证(应返回 404 或 403,而不是文件内容):
```bash
curl -I https://你的域名/data/config.json
```
### Apache
仓库已自动生成 `.htaccess`。仍需确认:
```apache
<Directory "/path/to/ny-exam-platform/data">
Require all denied
</Directory>
```
且虚拟主机的 `AllowOverride` 不为 `None`。
### PHP 内置服务器(开发环境)
**内置服务器既不解析 `.htaccess`,也没有 location 规则**,开发时不要把 8080 端口暴露到公网。
## P0:排查是否已被上传过 Webshell
如果你运行过修复前的版本,请立即检查:
```bash
ls -la data/uploads/
```
- 正常情况:目录为空(新版本解析后立即删除);
- 若存在 `.php` / `.phtml` / `.phar` / `.htaccess` 之外的可疑文件,立即删除;
- 检查 nginx access 日志中是否有对 `/data/uploads/*.php` 的 `POST` 请求;
- 如确认被利用,请**轮换卷王后台密码**并重新部署干净的目录。
## P1:全站 HTTPS
```nginx
server {
listen 80;
server_name sj.example.com;
return 301 https://$host$request_uri;
}
```
登录密码经 RSA 加密后再提交,但令牌 Cookie 在 HTTP 下可被中间人截获。
## P1:限制上传体积
与后端 20 MB 校验保持一致:
```nginx
client_max_body_size 20m;
```
PHP 侧:
```ini
upload_max_filesize = 20M
post_max_size = 24M
```
## P1:关闭信息泄漏
```nginx
server_tokens off;
```
```ini
expose_php = Off
display_errors = Off
log_errors = On
```
## P1:PHP-FPM 最小权限
- PHP-FPM 进程用户(如 `www`)只对 `data/` 有写权限,其它目录只读;
- 禁止在 Web 根目录放 `.git`:
```nginx
location ~ /\.git {
deny all;
return 404;
}
```
## P2:来源 IP 限制(内网场景)
```nginx
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
```
## P2:定期备份
备份 `data/` 目录即可,包含:
| 文件 | 内容 |
| --- | --- |
| `data/ny.db` | 配置、名单、每卷配置(SQLite) |
| `data/config.json` | 配置(文件备份) |
| `data/roster.json` | 名单(文件备份) |
## P2:改掉卷王默认口令
卷王后台默认 `admin / 123456` 请务必修改,并在平台 **设置** 中同步更新。
## 加固自检清单
- [ ] `curl -I https://域名/data/config.json` 返回 404 / 403
- [ ] `curl -I https://域名/data/ny.db` 返回 404 / 403
- [ ] 上传一个 `.php` 后缀文件被拒绝
- [ ] 正常导入 `.xlsx` 后 `data/uploads/` 为空
- [ ] 全站 HTTPS,HTTP 自动跳转
- [ ] `server_tokens off`、`expose_php = Off`
- [ ] `data/` 可写,其它目录只读
- [ ] 卷王后台已改默认密码
- [ ] `data/` 已纳入定期备份
## 相关
- [安全总览](./index.md)
- [环境要求与部署](../guide/install.md)