Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
NcStatusCheck — 针对多个 Nextcloud 实例的集中监控 | Kitploit
工具/GitLabGitLab/jp.louvel/ncstatuscheck
漏洞分析配置审计云安全
GitLabjp.louvel/ncstatuscheck

NcStatusCheck

针对多个 Nextcloud 实例的集中监控

查看仓库
2117天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

NcStatusCheck

集中监控多个 Nextcloud 实例

NcStatusCheck 是一个监控工具,可让您通过单一 Web 界面跟踪多个 Nextcloud 服务器的运行状况。它分析 Nextcloud 和 PHP 版本,并提供更新建议。

NcStatusCheck 界面 NcStatusCheck 界面 - 2

🎯 功能

监控

  • 自动监控多个 Nextcloud 实例
  • 三种数据采集模式:每台服务器:基础(仅 NC 版本)、扩展(通过 serverinfo API 获取完整数据)和推送(远程实例发送的数据)
  • 版本分析:Nextcloud 和 PHP
  • Web 服务器检测(nginx、Apache)和 HTTP 协议
  • 在线/离线追踪(微型监控):当前可达性 + 上次状态变化,仅在离线时以红色“离线”徽章显示。边界转换日志还提供30 天可用性百分比以及最近的事件列表,显示在详情页面上
  • SSL 证书过期警报:从现有的 HTTPS 探测读取(无需额外请求),当证书即将过期时显示徽章(< 15 天 / < 7 天)
  • 已安装应用审计:将 occ app:list 与 Nextcloud 应用商店交叉比对,标记需要审查的应用——阻塞类(升级阻塞、不兼容、生产环境中使用测试应用)以及信息性的成熟度/动荡信号(近期发布、预 1.0 版、alpha/beta/rc 构建、发布爆发、新近发布版本)
  • 全队列监控模块:“待关注的应用”(📦)和对应的“待关注的容器”(🐳)模块汇总所有实例中每个被标记的应用 / Docker 镜像,每个项目一条记录,并带有按组类型筛选器以及一个弹出窗口列出受影响的实例及其版本
  • 主动告警(Webhook 和/或电子邮件):在确认的在线/离线状态变化(离线、维护、恢复)时触发,即使没有打开仪表板也能收到通知——Slack / Mattermost / Google Chat / Discord / 原始 JSON(ALERT_WEBHOOK_URL),以及每批次发送的摘要邮件(ALERT_EMAIL_TO),通过直接 SMTP 提交到邮件服务器(自带 PHPMailer;未配置 SMTP 中继时回退到本地 MTA)。同时涵盖慢速信号(ALERT_CHECKS):SSL 证书过期(分层次)、易受攻击/已弃用的 Nextcloud 版本、陈旧推送探测、关键审计报告、阻塞性应用发现——每个新条件触发一次告警,无提醒骚扰
  • 更新宽限期:实例仅在补丁发布几天后才被标记为过时(nc_update_grace_days),以避免追逐当天有缺陷的版本
  • 健康列采用“静默即一切正常”原则:仅在有问题时才显示徽章(⚠️ 警告、📦 应用、🔄 Docker、🔒 SSL、🔴 离线、🚧 维护)
  • 服务器数据和官方版本的缓存系统

详情页面

  • 完整视图:每个 Nextcloud 服务器的配置(PHP、OPcache、Redis、数据库…),适用于扩展/推送模式服务器
  • 基础详情页面:用于无探测的服务器:显示版本、Web 服务器、HTTP 协议以及升级提示
  • 30 天可用性百分比和最近事件列表(开始、结束、持续时间、原因),基于有边界在线/离线转换日志计算——当日志时间短于窗口时,显示诚实的“已测量 N 天”标签
  • 配置警告规则,带有 ⚠️ 指示符,每条均可确认(原因 + 可选到期时间)
  • 服务器审计报告部分:当实例推送其月度 nc-audit.sh 报告时显示
  • 点击任何服务器名称或健康指示器即可访问

界面

  • 集中仪表板,带有状态概览(摘要卡片仅在非零时显示离线/证书过期/待审核应用计数)
  • 高级筛选器:按 Nextcloud 状态、PHP 状态、整体状态、正在运行的 Docker 镜像以及文本搜索进行筛选
  • 官方版本自动从 Nextcloud 源获取
  • 发布计划,包含即将发布的版本日期
  • FR / EN / DE 界面(右上角语言切换器)

管理

  • 管理界面,用于配置版本规则
  • 探测模式摘要表位于顶部:一目了然解释三种采集方法(基础、扩展、推送)
  • 通过 Web UI 进行服务器管理,卡片布局:两个不同的探测区域(serverinfo / 推送),带遮罩的令牌,内联删除
  • **每台服务器的“配置探测”**按钮,用于切换令牌区域,状态保存在 localStorage 中
  • 实时服务器搜索,支持重音不敏感匹配
  • 推送脚本生成器:为远程 Nextcloud 实例生成一个即用型 bash cron 脚本(chmod 700),选项更改时自动更新
  • **仪表板上的“触发推送”**按钮:向所有配置的推送服务器发送推送请求(仅当至少存在一台推送服务器时可见,冷却时间 5 分钟)
  • 灵活配置每个 Nextcloud 分支的安全阈值

🏗️ 架构```

ncstatuscheck/ ├── Frontend │ ├── index.php # Main entry point │ ├── template.html # HTML template (dashboard) │ ├── admin.html # Administration interface │ ├── detail.php # Server detail page │ ├── audit.php # Server-audit script distribution page (nc-audit.sh) │ ├── troubleshooting.php # Probe troubleshooting guide │ ├── app.js / admin.js / detail.js / audit.js / troubleshooting.js │ └── style*.css # One stylesheet per page family ├── APIs (HTTP) │ ├── api.php # Main monitoring API │ ├── detail-api.php # Detail page API (serverinfo + warnings + acks + availability) │ ├── push-api.php # Push reception + trigger + audit-report reception │ ├── ack-api.php # Warning acknowledge / unmute │ ├── admin-api.php # Version configuration routing │ ├── servers-admin-api.php # Server list management │ ├── nextcloud-versions-api.php # Official version scraping │ ├── nextcloud-apps-api.php # App store catalog (slim cache) for the apps audit │ ├── php-versions-api.php # PHP branch support data │ └── apps-warnings-api.php # Manual app warnings (known-bug list) CRUD ├── Shared modules (lib/) │ ├── auth.php # Auth + CSRF + URL redaction (defense in depth) │ ├── csrf-client.js # Auto-inject X-CSRF-Token in fetch() │ ├── nextcloud-client.php # Centralized HTTP client → remote Nextclouds │ ├── servers-store.php # Single source of truth for servers.json │ ├── uptime-state.php # Up/down state machine + transition journal + availability │ ├── alerts.php # Proactive alert dispatch: webhook + email digest │ ├── alerts-checks.php # Slow-signal alerts (SSL/version/push/audit/apps) + dedup state │ ├── smtp-mailer.php # SMTP transport adapter over vendored PHPMailer │ ├── phpmailer/ # Vendored PHPMailer (3 files + LICENSE, pinned in VERSION) │ ├── apps-warnings-manager.php # Manual app warnings storage │ ├── ui-common.js # NcUI: notify / confirm / prompt + shared app-audit messages │ ├── url-guard.php # Anti-SSRF (loopback, RFC1918, link-local…) │ ├── json-cache.php # Locked JSON read/write helpers │ └── version-config-manager.php # Version rules CRUD ├── Business logic │ ├── version-rules.php # NC / PHP status analysis engine │ ├── warnings-rules.php # Configuration warning engine │ ├── apps-rules.php # Installed-apps audit engine (store catalog cross-check) │ ├── cron-update.php # Full collection script, CLI only (twice a day) │ └── cron-ping.php # Lightweight up/down probe, CLI only (every 5 min) ├── Tools (never web-served — blocked by nginx/.htaccess) │ ├── tools/nc-audit.sh # Standalone server audit script (root, read-only) │ └── tools/ncstatuscheck-push-core.sh # Generic Push probe core (fleet-shared) ├── Tests │ └── tests/run.php # Plain-PHP test suite (no framework): php tests/run.php ├── Configuration │ ├── config.php # Central configuration (git-ignored) │ └── servers.json # Server list with tokens (git-ignored) └── Cache ├── servers_data.json # All server data ├── serverinfo_.json # Raw per-server cache (Extended) ├── push_.json # Last push payload per server ├── ack_.json # Acknowledged warnings per server ├── audit_.json # Last nc-audit.sh report per server ├── version-config.json # Version configuration ├── uptime_state.json # Up/down state per server (mini uptime) ├── uptime_history.json # Bounded up/down transition journal (availability % + incidents) ├── alerts_state.json # "Already alerted" memory of the check alerts ├── nextcloud_versions.json # Official NC versions ├── nextcloud_apps.json # App store slim catalog (apps audit) ├── apps-warnings.json # Manual app warnings (admin-curated) ├── .csrf_secret # CSRF HMAC secret (binary, 0600) └── *.log # Activity logs

deploy/ansible/ # Fleet deployment of the Push core (Ansible / scp) deploy/docker/ # Container packaging of the monitor itself

root@kitploit:~
## 🔌 收集模式

模式并非互斥——一台服务器可以同时启用扩展模式和推送模式。

| 模式 | 徽章 | 源 | 收集数据 |
|------|-------|--------|----------------|
| **基本** | *(无)* | `/status.php` + HTTP 头 | Nextcloud 版本(若暴露则包含 PHP/Web 服务器) |
| **扩展** | `⚡ Extended`(错误/过期时紫色变橙色) | `/ocs/v2.php/apps/serverinfo/api/v1/info` 使用 `NC-Token` | NC 版本、PHP、Web 服务器、OPcache、Redis、数据库、活跃用户…… |
| **推送** | `📡 Push`(错误/过期时蓝色变橙色) | POST 到 `push-api.php` | 远程 NC 实例通过 cron 脚本推送的数据 |

**serverinfo NC-Token** 可在 **Nextcloud 设置 → 管理 → 系统** 中找到。

**推送令牌** 通过管理界面生成;管理员提供一个可直接使用的 bash cron 脚本(`chmod 700`)以部署在被监控的实例上。

扩展模式数据由 [nextcloud/serverinfo](https://github.com/nextcloud/serverinfo) 应用提供,该应用必须在被监控的实例上安装并启用。

**回退行为**:如果扩展 API 不可达(连接错误、无效令牌、应用未安装),NcStatusCheck 会自动回退到 `/status.php` 以至少获取 Nextcloud 版本。

**推送过期阈值**:如果在 `auto_push_interval + 30 分钟` 内未收到任何数据,则视推送服务器为过期。默认推送间隔为 12 小时。

### 仪表盘表格列

主仪表盘显示 5 列:**服务器** | **NC 版本** | **PHP** | **探测** | **健康**

**探测** 列显示每台服务器的活跃收集模式:
- `⚡ Extended` 徽章(紫色,连接错误或数据过期时变橙色)
- `📡 Push` 徽章(蓝色,在阈值内未收到数据时变橙色)
- 如果两种模式均活跃,两个徽章可同时出现
- 无徽章 = 仅基本模式

### 健康列

健康列仅在需要处理时显示内容:

| 指示器 | 徽章 | 含义 |
|-----------|-------|---------|
| 离线 | `🔴 Offline` | 实例不可达(HTTP 探测失败),显示“离线 X 时间” |
| 活跃警告 | `⚠️ N` | N 个配置问题 |
| 应用审计 | `📦 N` | N 个已安装应用需要审查(阻止升级/不兼容) |
| SSL 过期 | `🔒 N d` | 证书即将过期——橙色 `< 15 天`,红色 `< 7 天` 或已过期 |
| Docker 更新 | `🔄 M` | M 个容器更新可用 |
| 一切正常 | *(空)* | 无报告内容 |
| 无数据 | `?` | 基本模式且无推送数据 |

#### 上下线状态与 SSL 过期

NcStatusCheck 为每台服务器维护一个**最小化**的上下线状态(仅当前状态和最后变更日期——无时间序列,无历史页面)。“上线”表示出站 HTTPS 探测成功到达实例;红色 **Offline** 徽章仅在下线时出现。在同一个 HTTPS 探测中,**SSL 证书过期时间** 会被免费读取(`CURLOPT_CERTINFO`),并在即将过期时显示。详细信息在详情页完整展示。*注:这些出站检查不适用于监控器从不联系的纯推送实例。*

#### 应用审计(`📦`)

当推送服务器报告其已安装的应用时(`occ app:list`,推送脚本 v3+),NcStatusCheck 会将其与 Nextcloud 应用商店目录交叉检查,并标记值得审查的应用。**仅发出信号**——该工具从不禁用任何东西;它只是列出候选(无法知道应用是否实际使用)。只使用**事实性的、二元的**信号。`📦 N` 徽章计数阻止性发现(当前 NC 版本无兼容版本,NC N+1 无版本 → 阻止升级,或测试/开发应用在生产环境中保持启用)。信息性发现(实例上应用过时、上游弃用、PHP 不兼容)仅在详情页显示。发现可以通过与警告相同的确认机制静音。

### `servers.json` 格式```json
[
  {"url": "https://cloud.example.com"},
  {"url": "https://cloud2.example.com", "serverinfo_token": "abc123def456"},
  {"url": "https://cloud3.example.com", "serverinfo_token": "...", "push_token": "xyz789"}
]

🚀 安装

前提条件

  • PHP 8.1+ 且已安装 cURL 和 JSON 扩展——这是 CI 测试所依赖的最低语法版本,并非部署建议:8.1 和 8.2 都已过安全支持期限,对于面向互联网的任何用途,请使用当前受支持的版本(截至撰写本文时为 8.3+)
  • Web 服务器 支持 HTTPS 的 nginx 或 Apache
  • 网络访问 能够访问要监控的 Nextcloud 服务器

Web 服务器配置 (nginx)```nginx

server { server_name monitoring.your-domain.com; root /var/www/ncstatuscheck; index index.php;

root@kitploit:~
# HTTP Basic Authentication
auth_basic "Monitoring Access";
auth_basic_user_file /etc/nginx/.htpasswd;

# Protect sensitive files/dirs (tests/run.php has no CLI-only guard — it must
# never be reachable over HTTP; same blocklist as deploy/docker/nginx.conf)
location ~ ^/(cache/|\.git|deploy/|tools/|tests/) {
    deny all;
    return 404;
}

# .txt covers servers.txt (legacy server list — real monitored URLs)
location ~* \.(log|json|txt)$ {
    deny all;
    return 404;
}

# Security headers for static HTML pages (admin.html, template.html).
# PHP pages (index.php, detail.php) send the same headers themselves
# via send_security_headers() in lib/auth.php.
location ~* \.html$ {
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header Referrer-Policy no-referrer always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" always;
    try_files $uri =404;
}

# Standard PHP configuration (adjust the socket to your PHP version —
# use a security-supported one: 8.2 has been EOL since December 2025)
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location / {
    try_files $uri $uri/ =404;
}

}

root@kitploit:~
> **Apache**:仓库附带了 `.htaccess` 文件,与上述 `deny` 规则一致(根目录:阻止 `*.log`/`*.json`/`*.txt` 和 `.git`;`cache/`、`tools/`、`deploy/`、`tests/`:`Require all denied`)。这些文件仅在 vhost 设置了 `AllowOverride FileInfo AuthConfig`(或 `All`)时生效——Debian 的 `/var/www` 默认设置为 `AllowOverride None`,此时需直接在 vhost 中复制这些规则。无论如何,HTTP Basic auth 仍需在 vhost 中配置。

### 部署

1. **克隆仓库**```bash
git clone https://gitlab.com/jp.louvel/ncstatuscheck.git
cd ncstatuscheck
  1. 配置 根据模板创建你的配置文件:```bash cp config-example.php config.php
root@kitploit:~
编辑 `config.php` 并根据你的环境调整路径和 URL:```php
define('MONITOR_PATH', '/var/www/ncstatuscheck');
define('MONITOR_URL', 'https://monitoring.your-domain.com'); // your public URL
define('CACHE_DIR', MONITOR_PATH . '/cache');
  1. 添加服务器

服务器直接通过管理界面(⚙️ 管理按钮)进行管理。 您也可以手动创建 servers.json:```json [ {"url": "https://cloud.example.com"}, {"url": "https://nextcloud.mycompany.org", "serverinfo_token": "your_token_here"} ]

root@kitploit:~
> **从 `servers.txt` 迁移**:如果存在 `servers.txt` 文件,首次访问时会自动转换为 `servers.json`。之后你可以删除 `servers.txt`。

4. **设置权限**

nginx/PHP-FPM 以它们自己的用户身份运行(在 Debian/Ubuntu 上是 `www-data`,在 RHEL 系列上是 `nginx`/`apache` — 请根据实际情况调整)——如果你以你自己的登录用户克隆,那么该用户几乎肯定不是 `www-data` 或不属于其组,因此仅靠 `chmod` 会使网络服务器**完全无法访问**,甚至连读取权限都没有(每个请求都返回 403/404):```bash
chown -R www-data:www-data /var/www/ncstatuscheck   # adjust the user:group to your distro

chmod 750 /var/www/ncstatuscheck
chmod 750 cache img

chmod 640 *.php *.html *.js *.css *.md
chmod 600 config.php servers.json servers.txt   # secrets / serverinfo & push tokens
chmod 660 cache/*.json cache/*.log

如果 servers.json 尚不存在(您让管理 UI 创建它,而不是执行上面的手动步骤),那么上面的 chmod 600 就没有任何作用对象——这没问题:ServersStore::save() 在每次写入时都会自动将文件权限设置为 0600,因此通过管理 UI(重新)创建的 servers.json 永远不会让其中包含的服务器信息和推送令牌保持组/全局可读。

  1. HTTP 认证```bash htpasswd -c /etc/nginx/.htpasswd admin
root@kitploit:~
6. **定时任务(可选)**

两个互补的定时任务——使用**同一个 `crontab -` 调用**安装:
`crontab -` 从标准输入安装一个全新的 crontab,它不会追加,因此运行两次(每次一行)只会留下*第二个*任务——第一个会静默消失,没有错误。这也能保留你的 crontab 中已有的内容(首先通过管道输入 `crontab -l`),而不是覆盖它:```bash
(crontab -l 2>/dev/null; cat <<'EOF'
# Full collection (NC/PHP versions, serverinfo, app-store catalog) — twice a day
0 6,18 * * * cd /var/www/ncstatuscheck && php cron-update.php
# Lightweight reachability probe (status.php only -> up/down state) — every 5 min
*/5 * * * * cd /var/www/ncstatuscheck && php cron-ping.php
EOF
) | crontab -

重新运行会在这些行已存在时添加重复项——如果不确定,请先用 crontab -l 检查。

cron-ping.php 故意保持最小化:它仅检查每个实例的 status.php 并更新上下线状态 (cache/uptime_state.json),因此可以频繁运行而不造成负载。一个实例只有在连续 UPTIME_FAIL_THRESHOLD 次探测失败(默认 2 → 若以5分钟为间隔,约10分钟)后才会被标记为宕机;恢复为上线则是即时的。完整的 cron-update.php 保持不变用于其他一切。

Docker(替代裸机部署)

除了上述步骤 1–6 之外,NcStatusCheck 也可以作为一个小的 docker compose 堆栈运行(PHP-FPM + nginx + 一个 cron 容器)——仓库被原样绑定挂载,无需构建步骤或 Composer,因此它完全镜像了裸机布局,只是容器化了。仅提供纯 HTTP(默认端口 8080)——在你的前端放置自己的 TLS 终止反向代理。

完整的设置——配置、权限陷阱(uid 82、servers.json 预先创建)、HTTP 基本认证、cron、更新和备份——全部位于 deploy/docker/README.md 中。从那里开始;本节刻意仅作指引,以避免维护同一步骤的两个副本保持同步。

📋 使用

主界面

  • 访问 https://monitoring.your-domain.com
  • 查看所有服务器的状态仪表板
  • 使用过滤器按状态或搜索缩小范围
  • 检查官方版本和发布计划

管理

  • 通过“⚙️ 管理”按钮打开管理界面
  • 页面顶部的探测模式汇总表解释了基本、扩展和推送收集方法之间的差异
  • 服务器管理:每个服务器显示为一张卡片,包含两个可折叠的探测区域:
    • 服务器信息区域:配置读取令牌(NC → NcStatusCheck 拉取)
    • 推送区域:生成推送令牌并为远程实例下载可直接使用的 cron 脚本
  • Nextcloud 配置:按分支设置最低安全版本(行上有悬停效果)
  • PHP 配置:按版本设置推荐/支持状态

详情页面

可通过点击任意服务器名称或其健康指示器访问。

对于基本服务器(无扩展或推送探测),一个简化的页面显示可用数据(NC 版本、Web 服务器、HTTP 协议),并附带通知和建议启用探测。

对于扩展/推送服务器,完整详情页面显示不同的部分:

API

NcStatusCheck 暴露了几个 REST 端点:

主要 API (api.php)

  • GET ?action=get_data — 获取数据(缓存或刷新)
  • POST ?action=refresh_data — 强制更新所有服务器

推送 API (push-api.php)

  • POST 带有 push_token 头部 — 从远程 NC 实例接收推送数据
  • POST ?action=request_push_all — 请求所有已配置的推送服务器立即推送(设置一个由远程 cron 脚本使用的触发标志)

管理 UI 生成的 cron 脚本分为两部分:一个通用核心 /usr/local/bin/ncstatuscheck-push.sh — 在每台服务器上完全相同(包含所有逻辑)——由一个小型每个实例的配置驱动 /etc/ncstatuscheck/<slug>.conf (SERVER_URL, SLUG, OCC_CMD, DOCKER_ENABLED, SKOPEO_ENABLED)。它被调用时使用 ncstatuscheck-push.sh /etc/ncstatuscheck/<slug>.conf [--test]。核心拒绝加载组/全局可写的配置文件(防止代码注入)。

它是多目标(扇出):数据收集一次并推送到 /etc/ncstatuscheck/targets-<slug>.conf 中列出的每个监控器(每行一个 url|push_token[|http_user|http_pass] 行)。每个监控器的管理员会发出一个幂等命令来注册自身。

一台主机上多个 Nextcloud 实例:每个实例的路径通过从受监控 URL 派生的 <slug> 后缀(例如 latest.ezeo.coop → ): 、、、 、状态 。只有核心是共享的, 因此同一位置上的实例永远不会冲突。

详情 API (detail-api.php)

  • GET ?server=<url> — 完整的服务器信息数据 + 针对扩展/推送服务器的计算警告

管理 API

  • admin-api.php — 版本配置
  • servers-admin-api.php — 服务器管理(get_servers、add_server、remove_server、update_server_token、generate_push_token、remove_push_token)
  • nextcloud-versions-api.php — 官方版本

🩺 服务器审计 (nc-audit.sh)

一个独立于监控的子系统:一个独立的、只读的 bash 脚本(tools/nc-audit.sh),以 root 身份在 Nextcloud 服务器上运行,用于一次性/每月的审计,检查 Web + PHP + 数据库调优,并与机器的物理容量(RAM、CPU、磁盘类型)交叉核对。面向托管监控服务:客户端安装它,监控器仅接收报告——无需机器/网络访问。脚本仅读取配置(不做更改),打印彩色报告并将副本写入 /tmp。

它检查的内容:服务器容量(RAM/CPU/SSD-HDD、swappiness、共享服务器检测)· Nextcloud(版本、cron、缓存、Redis 运行时、数据库类型、日志)· PHP/PHP-FPM(实际服务 SAPI、OPcache 运行时、多池内存)· Apache(MPM 感知的工作内存)· Nginx · PostgreSQL · MariaDB · 安全卫生(fail2ban 或 CrowdSec + 拦截器 + 社区黑名单;待处理的更新/重启/基于陈旧库的服务)· RAM 预算核对(InnoDB + FPM + Apache vs 实际 RAM)· 如果已存在可选工具的深度分析(mysqltuner、pt-variable-advisor、apache2buddy、sar/iostat)。```bash

Download (the page distributes it; the repo raw URL is public)

curl -fsSL https://gitlab.com/jp.louvel/ncstatuscheck/-/raw/master/tools/nc-audit.sh -o /usr/local/bin/nc-audit.sh chmod 700 /usr/local/bin/nc-audit.sh

sudo nc-audit.sh # auto-detect, dedicated server sudo nc-audit.sh /var/www/nextcloud # explicit path (or NC_PATH=…) sudo NC_RAM_BUDGET_PCT=50 nc-audit.sh # shared host: size to 50% of RAM

root@kitploit:~
**多实例主机**(多个 Nextcloud + 一个共享数据库)。 `NC_RAM_BUDGET_PCT` 是**总**栈预算;其中 `NC_PHP_SHARE_PCT`%(默认 60,其余部分覆盖数据库 + Web + 操作系统——在数据库密集型服务器上应降低此值)是 PHP 份额,按**权重**(相对重要性——而非百分比或 MB)分配到各个 FPM 池,从而为每个池设定目标 `pm.max_children`:```
target = PHP_share × (weight / Σ weights) / ~50 MB per process

目标是一个预算允许的上限,而不是您必须设定的值(仅提升实际饱和的资金池)。权重由您决定——工具从不猜测它们。```bash

Weights you provide (a human judgment — the tool never guesses them):

sudo NC_RAM_BUDGET_PCT=70 NC_INSTANCES="poolA:4,poolB:2,poolC:1" nc-audit.sh

Interactive helper (terminal only): lists the pools, asks a weight for each,

prints the targets + a reusable NC_INSTANCES line:

sudo NC_RAM_BUDGET_PCT=70 nc-audit.sh --tune-fpm

root@kitploit:~
**报告推送(可选,复用推送基础设施):** `nc-audit.sh --push /etc/ncstatuscheck/<slug>.conf` 运行审计并将报告以 POST 方式发送至监控器,监控器存储报告并在服务器详情页("🩺 服务器审计"部分)显示。通常作为月度定时任务运行。管理后台(beta 版)中的 `audit.php` 页面分发脚本(支持下载、内联及 GitLab 一行命令),并显示其版本。

> **脚本绝不会安装深度分析工具**——这些工具仅在已存在时才会运行(无 `curl | bash`,无自动安装),每个工具都有 `timeout` 限制。

## 🔧 高级配置

### 版本规则自定义

评估规则可通过管理界面进行配置:

**Nextcloud 状态:**
- `dev` — 开发版本
- `stable` — 当前稳定版本
- `oldstable` — 之前支持的稳定版本
- `deprecated` — 已弃用版本

**PHP 状态:**
- `recommended` — 推荐版本
- `supported` — 支持版本
- `deprecated` — 已弃用版本

### 配置变量

编辑 `config.php` 以调整配置:```php
// Environment: 'dev' or 'prod'
define('ENV', 'prod');

// Paths and URLs
define('MONITOR_PATH', '/var/www/ncstatuscheck');
define('MONITOR_URL', 'https://monitoring.your-domain.com');

// Main server cache duration
define('CACHE_MAX_AGE', 86400); // 24 hours

// Official Nextcloud versions cache duration
define('VERSIONS_CACHE_AGE', 86400);

// Consecutive failed probes before a server is marked "down" (min 1)
define('UPTIME_FAIL_THRESHOLD', 2);

// Proactive alerts — webhook on a confirmed up/down state change.
// Empty URL = disabled. Format: 'slack' (default, also Mattermost/Google Chat),
// 'discord', or 'raw' (structured JSON). The URL usually carries a secret, so it
// is never logged in full — see config-example.php for details.
define('ALERT_WEBHOOK_URL', '');
define('ALERT_WEBHOOK_FORMAT', 'slack');

// Check alerts on top of up/down (cron-update cadence, 2×/day): SSL expiry
// tiers, vulnerable (below min_secure) or deprecated Nextcloud version, stale
// Push data, critical audit report, blocking apps-audit finding. Edge-triggered with a persisted state
// (cache/alerts_state.json): one alert per NEW condition, no reminders, re-arms
// when resolved (renewed cert, fixed/acked app…). First run arms silently.
define('ALERT_CHECKS', 'ssl,version,push_stale,audit,apps'); // '' = up/down only
define('ALERT_SSL_DAYS', '30,14,7');                          // days-left tiers

// Email channel, independent of the webhook (either one arms the alerting).
// One digest mail per batch. Recommended transport: direct SMTP submission to
// your mail server (vendored PHPMailer, lib/phpmailer/ — nothing to set up on
// the host). Without ALERT_SMTP_HOST it falls back to PHP mail() (local MTA).
define('ALERT_EMAIL_TO', '');    // comma list of recipients, '' = off
define('ALERT_EMAIL_FROM', '');  // default: ncstatuscheck@<hostname>
define('ALERT_SMTP_HOST', '');   // e.g. 'mail.example.org', '' = mail() fallback
define('ALERT_SMTP_PORT', 587);
define('ALERT_SMTP_SECURITY', 'starttls'); // 'starttls' | 'tls' | 'none'
define('ALERT_SMTP_USER', '');
define('ALERT_SMTP_PASS', '');

参见 config-example.php 以获取完整带注释的选项列表(包括 DEMO_MODE 和 PUSH_SCRIPT_VERSION)。

🛡️ 安全性

已实施的措施

  • 强制 HTTP 基本认证,并在每个管理端点上辅以应用级别的身份验证检查(纵深防御)
  • CSRF 保护:每个变更请求自动注入 HMAC 令牌(lib/csrf-client.js + csrf_require())
  • 反 SSRF 防护:针对每个操作员提供的 URL(拒绝回环地址、RFC1918 地址、链路本地地址;仅允许 HTTPS 重定向;连接后进行 IP 检查)
  • 要求 HTTPS,配合 Let's Encrypt 证书
  • 数据文件和日志保护:nginx 规则(见上文)通过附带的 Apache .htaccess 文件实现;servers.json 自动设为 0600 权限(包含令牌)
  • 安全标头(CSP、X-Frame-Options、nosniff、Referrer-Policy)应用于每个 PHP 提供的页面
  • 严格 URL 验证:对所有输入进行验证
  • root 运行的客户端脚本:实例配置以 root 身份加载,目标文件决定采集数据发送到哪里——两者均被拒绝,除非它们不属于组/全局可写,且不被第三方拥有
  • 受监控实例之间的隔离:仅当正文中的 URL 匹配某个条目,且 hash_equals() 通过该条目的令牌时,才接受推送,因此受感染的受监控服务器既不能读取也不能覆盖另一台服务器的数据。request_push / request_push_all 位于管理认证 + CSRF 之后。已针对受感染客户端场景进行了端到端验证

建议

  • 为 HTTP 认证使用强密码
  • 限制对已知地址的访问——管理IP 过滤标签页可为您生成规则(见下文)
  • 监控日志以发现入侵尝试
  • 保持 PHP 和系统依赖项为最新版本

config.php 健康提示(管理页面)

config.php 是 Git 忽略的,并需按服务器手动编辑,因此会逐渐偏离——而由于几乎每个常量在代码中都有回退值,这种偏离是静默的。管理页面顶部的提示横幅会报告实际错误,并且仅在存在错误时显示:版本升级后遗留的 PUSH_SCRIPT_VERSION、未配置任何警报传输、尾随结束标签在任何 header() 之前输出了一个字节、缓存目录不可写、常量缺失并静默回退到默认值。

设计为只读且无保存操作,原因与“通知”标签页相同:config.php 由 root 拥有且包含机密信息。文件内容从不传输——仅传输关于它的事实——并且不读取任何机密。

IP 过滤(管理标签页)

以上所有内容都是应用层面的:互联网上的任何人都仍然可以访问监控器并探测它,只有密码能够阻止他们。IP 过滤标签页生成的规则会在应用之前放置一个白名单,因此未知主机根本无法与其通信。这是纵深防御,而非基本认证或推送令牌的替代品——并且它仅生成供审查和粘贴的文本,从不写入 Web 服务器或防火墙配置。

两类来源,故意设计为不平等,因此受感染的受监控服务器无法访问管理页面:

类别谁可访问范围
push仅限推送模式的受监控实例/push-api.php,其他均不可
admin堡垒机 / VPN / 固定办公 IP所有

以基本/扩展模式轮询的实例不打开入站连接,也根本不会获得白名单条目。

地址来自两个来源,其差异很重要:受监控域的 DNS 记录是其入站地址,而其推送则从其出站地址发出。当两者不同时,只有出站地址有效。因此 push-api.php 记录每次推送的真实源地址(推送缓存中的 source_ip),并且该标签页将其加入白名单,同时报告不匹配。在服务器完成一次推送之前,它会回退到 DNS A+AAAA 记录并说明这一点。

三种输出:

  • nginx(推荐)——一个独立的 conf.d 文件(geo + map)加上虚拟主机中的单行 if ($ncsc_forbidden) { return 403; }。无需复制 fastcgi 块,静态文件也同时被覆盖(admin.html 即为一例),且 /.well-known/acme-challenge/ 保持开放,以免证书续期无声中断。
  • Apache 2.4 —— <LocationMatch> 配合负向前瞻,加上用于推送端点的 <Location>,使两个部分不会重叠,且不依赖于 Apache 的合并顺序。一条规则的所有地址放在一行 Require ip 上:<RequireAll> 内的多行会被 AND 运算,无人能同时满足。
  • ufw——本质粗糙(数据包过滤器看到的是端口,而非 URL),因此无法表达推送/管理的拆分。仅用作外层。

当未提供任何管理地址时,生成器拒绝输出任何内容;当操作员自身的地址未被覆盖时发出警告;当请求通过代理到达时也发出警告(geo 和 Require ip 都读取传输对端,因此在代理后面所有客户端看起来都一样)。生成的 ufw 片段将 SSH 规则放在首位,保持 80 端口开放用于 HTTP-01 验证,并明确指出 IPv6 陷阱:与 nginx(拒绝未列出的 v6 地址)不同,ufw 除非设置了 IPV6=yes,否则根本不会过滤 v6——否则双栈主机将通过 IPv6 完全开放。

已知限制,已在页面本身标明:一旦规则应用,此标签页将无法发现新内容。被拒绝的推送在到达 PHP 之前就被 Web 服务器拒绝,因此记录的地址仍然是最后一个通过的地址——并且看起来仍然是已验证的。这导致两个后果:添加推送服务器意味着重新生成并重新应用规则,否则其首次推送将被拒绝;如果实例的地址发生变化,新地址只能在 Web 服务器访问日志中读取(grep 'push-api.php' access.log | grep ' 403 ')。因此,该标签页显示每个观察到的地址的最后发现日期,并在其超过一个完整的错过推送周期时标记——与 push_stale 警报使用相同的阈值,该警报从另一端覆盖了相同的盲区。

区分过滤问题与其他问题:对推送端点执行一次裸 GET 即可清晰地区分各层,无副作用且无需令牌——从相关机器上运行此命令,因为被判断的是该机器的出站地址:```bash curl -sS -o /dev/null -w '%{http_code}\n' https://your-monitor/push-api.php

root@kitploit:~
| Answer | 含义 |
|---|---|
| `403` | 被IP过滤拦截 |
| `401` | 过滤通过,Basic auth 正在响应——问题在其他地方 |
| `405` | 请求已到达应用(GET 在此不是可接受的方法) |
| nothing / timeout | 不是过滤问题:过滤器有响应,它不会静默 |

重新运行 `-u user:password` 以解决对 `403` 的疑问:如果状态码未改变,则确实是过滤。已在 nginx 和 Apache 上验证(包括启用 `Require valid-user` 的情况),过滤器在身份验证*之前*响应——而来自应用本身的 `403` 始终在响应体中携带 JSON。

代码片段逻辑位于 `lib/hardening-rules.php`,该文件是纯逻辑并由 `tests/run.php` 覆盖:此处代码片段是产出物,错误的片段要么锁住操作员,要么留下漏洞。nginx 和 Apache 的输出均已通过行为验证(真实服务器、真实源地址,包括来自 `push` 类的路径遍历尝试)。

### 自动化分析(CI `security` 阶段)

依赖扫描(`npm/pnpm audit`、Snyk Open Source、Dependabot)在此处无操作:没有 `package.json` 和 `composer.json`——无可扫描的内容。风险存在于自定义代码(约 15k 行 PHP,约 6k 行 JS)以及在受监控实例上**以 root 身份**运行的 shell 脚本(`tools/*.sh`)。流水线针对这些方面:

| Job | Tool | Blocking | Scope |
|---|---|---|---|
| `secrets_scan` | gitleaks | 是 | 已提交的机密(工作树) |
| `sast_semgrep` | semgrep (`p/php`, `p/javascript`, `p/owasp-top-ten`) | 是 | SSRF、缺少授权/CSRF、XSS |
| `shellcheck` | shellcheck (`--severity=warning`) | 是 | `tools/*.sh` — 客户端主机上的 root |
| `dockerfile_misconfig` | trivy misconfig | 是 | `deploy/docker/` |
| `container_cve` | trivy image | 否(`allow_failure`) | `deploy/docker` 构建的镜像,加上 `nginx:alpine` |
| `ui_tests` | node (no deps) | 是 | 转义 `lib/ui-common.js` 的不变条件(过去的两次 XSS 回归) |
| `phpmailer_freshness` | GitHub API | 否(`allow_failure`) | 供应商固定版本与上游发布版本 |
| `deploy_selfcheck` | nc-selfcheck.sh | 是 | 已交付的 nginx 规则集(拒绝规则 + 安全头)在一次性容器中启动 |

所有阻塞性作业均具有**零发现基线**,因此任何新警报都是真实信号。两个有意的决策,记录在 `.gitlab-ci.yml` 内联注释中:

- **`php.lang.security.injection.echoed-request` 已从 semgrep 中排除**:它会将每个 `echo json_encode()` 标记为 XSS,而这正是此处每个 API 端点合法执行的操作(JSON 响应,而非 HTML)。它首次运行时占了全部 10 个发现中的 10 个,全部为误报。保留它会让每个人都忽略该作业。
- **两个 `allow_failure` 作业报告上游事实**(`nginx:alpine` 中的 CVE,或修复尚未到达 Alpine 分支的 CVE,新的 PHPMailer 发布),合并请求无法修复这些。红色但可容忍是准确的信号——"是时候重建/刷新供应商依赖了"——而不是阻止无关工作的理由。`phpmailer_freshness` 将不可达或受限的 GitHub API 报告为*跳过*,绝不报告为"过时"。
- **`container_cve` 扫描它构建的镜像,而非 `FROM` 标签。** Dockerfile 使用 `apk --no-cache upgrade` 加固基础镜像(官方 PHP 镜像落后于 Alpine 仓库——它随附 c-ares 1.34.6-r0,而 1.34.8-r0(修复 CVE-2026-33630)已经发布)。因此,扫描基础标签会报告已发布镜像不再具有的 CVE:一个永久橙色的、无人阅读的作业。

白名单故意狭窄:`.gitleaks.toml` 仅豁免**字面**占位符字符串,绝不豁免整个文档文件(允许读取 `README.md` 会在真实机密被粘贴进去的那一天使扫描失效)——因此文档中的新示例令牌必须添加在那里。`.trivyignore` 包含一个条目 `DS-0002`,在文件中已说明:php-fpm 主进程必须以 root 身份启动,才能将其工作进程降级为 `www-data`(uid 82)。

### 部署后验证(`nc-selfcheck.sh`)

CI 可以锁定*已交付的*配置(上面的 `deploy_selfcheck` 作业在容器中启动 nginx 规则集并探测它),但无法验证您实际部署到的服务器——不同的主机、Basic-auth 凭据、文件系统权限。`tools/nc-selfcheck.sh` 弥补了这一差距。它是一个独立的、只读的 bash 脚本(与 `nc-audit.sh` 相同模式),您可以在每次部署后运行:```bash
# Black-box, no credentials: confirms Basic auth is enforced (401) and that
# sensitive files are blocked (cache/, servers.*, .git, config.php source).
bash tools/nc-selfcheck.sh https://monitoring.example.com

# + security headers behind Basic auth:
bash tools/nc-selfcheck.sh -u user:pass https://monitoring.example.com

# + filesystem checks (run ON the host): servers.json / config.php / CSRF-secret
# permissions, and a stray closing "?>" in config.php.
bash tools/nc-selfcheck.sh --webroot /var/www/ncstatuscheck https://monitoring.example.com

它在发现任何严重问题时(源代码泄露、未阻止的秘密文件、全局可读的令牌存储、缺少基本认证)会返回非零退出码,因此可以用来控制发布流程——将其作为后置步骤接入你的同步/部署脚本中。WARN/INFO 级别永远不会导致运行失败。

🧪 测试与开发

开发模式```php

// In config.php define('ENV', 'dev');

root@kitploit:~
在开发模式下,会显示额外信息(PHP 版本、Web 服务器)。

### 服务器测试
使用管理界面通过 URL 添加服务器。该服务器将在下次数据刷新时被轮询。

### 调试日志
检查 `cache/` 中的日志文件:
- `monitor.log` — 通用应用程序日志
- `cron.log` — 完整收集脚本日志(`cron-update.php`)
- `ping.log` — 轻量级在线/离线探测日志(`cron-ping.php`)
- `alerts.log` — 主动告警分发(Webhook/邮件),从不记录 Webhook 密钥或 SMTP 凭据

### 测试套件```bash
php tests/run.php   # plain-PHP assertions, no framework — exit 0 = all green

覆盖纯业务逻辑(版本/应用规则、警告、正常运行状态机与可用性、警报去重/重新武装状态机、邮件构建器)。

🤝 贡献

报告错误

新建一个 issue,包含:

  • 问题的详细描述
  • 复现步骤
  • 错误日志(如有)
  • 您的环境配置

提出改进建议

  1. 新建 issue 讨论您的想法
  2. Fork 本仓库
  3. 为您的功能创建分支
  4. 实现功能并附带文档
  5. 提交合并请求

📝 许可证

本项目采用 GNU AGPL v3 许可证。

👥 致谢

NcStatusCheck 由 ézéo 开发,这是一家专注于开源解决方案的数字合作社。

贡献者

  • ézéo 团队 — 初始开发与维护

需要帮助? 查看问题页面或联系 ézéo 团队。

下载工具
部分字段
Nextcloud 系统版本、调试模式、本地/分布式内存缓存、文件锁定、磁盘空间
PHP版本、memory_limit、upload_max_filesize、max_execution_time、FPM、OPcache
Web 服务器名称 + 版本、HTTP 协议
数据库类型、版本、大小
缓存Redis、APCu 命中率
活跃用户最近5分钟、1小时、24小时、7天
latest_ezeo_coop
<slug>.conf
/etc/cron.d/ncstatuscheck-<slug>
targets-<slug>.conf
ncstatuscheck-push-<slug>.log
…-<slug>.<md5>.last

Nextcloud 在 Docker 中运行(官方镜像、compose、AIO):完全支持——脚本安装在主机上(root cron + Docker daemon 权限), 绝不安装在容器内部,occ 通过 docker exec 执行: OCC_CMD=docker exec -u www-data <container> php occ(AIO 容器:nextcloud-aio-nextcloud)。 管理员脚本生成器有一个安装类型预设,可以预填充此项。绝不要添加 -t(在 cron 下没有 TTY);保留 -u www-data(官方镜像拒绝以 root 身份运行 occ)。

批量部署/更新:由于核心是一个单一相同的文件,跨多台服务器更新逻辑 = 替换那个文件(↑ 标记表示服务器运行旧版本)。参见 deploy/ansible/ 获取可直接使用的 playbook(或简单的 scp 循环)。监控器保持被动——它永远不会向集群发送代码;信任锚是你自己的 SSH 访问,而不是监控器。

从 v4 之前的版本迁移(单体每个实例脚本):在安装核心+配置之前删除旧的 /usr/local/bin/ncstatuscheck-push-<slug>.sh 和 /etc/cron.d/ncstatuscheck-<slug> (targets-<slug>.conf 原样重用), 否则会重复推送。

  • 推送目标报告:每个实例声明其推送到哪些监控器(仅 URL,不含令牌);详情页面显示这些信息,并在集合发生变化时触发警报——否则 targets.conf 中多出一行会悄悄将每次推送复制给第三方
  • 推送载荷清理:应用 ID 使用字符白名单;自由格式的 Docker 字段(name、image、version、status)在接收时去除 <>"'& 字符,并在渲染时进行转义
  • 出站连接的 SSL/TLS 验证——始终开启,包括 SMTP 警报传输
  • 有界远程响应(2 MB):受监控服务器完全控制其响应内容,且该方向无需身份验证。若无边界,持续传输数据的服务器会耗尽 PHP 内存——这是 try/catch 无法捕获的致命错误,将导致采集循环中途终止,进而丢失整个集群的所有警报
  • 演示模式匿名化覆盖范围超出 URL:容器名称、镜像引用中的私有仓库主机以及 cURL 错误消息中引用的主机名均被擦除,涵盖仪表板和详情页面