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 — это инструмент мониторинга, который позволяет отслеживать работоспособность нескольких серверов Nextcloud из единого веб-интерфейса. Он анализирует версии Nextcloud и PHP и предоставляет рекомендации по обновлению.

Интерфейс NcStatusCheck Интерфейс NcStatusCheck - 2

🎯 Возможности

Мониторинг

  • Автоматизированное наблюдение за несколькими экземплярами Nextcloud
  • Три режима сбора данных для каждого сервера: Basic (только версия NC), Extended (полные данные через API serverinfo) и Push (данные, отправляемые удаленным экземпляром)
  • Анализ версий Nextcloud и PHP
  • Обнаружение веб-сервера (nginx, Apache) и HTTP-протоколов
  • Отслеживание состояния вкл/выкл (мини-uptime): текущая доступность + время последнего изменения состояния, отображается как красный значок "offline" только при недоступности. Ограниченный журнал переходов также используется для расчета доступности за 30 дней и списка недавних инцидентов на странице сведений
  • Предупреждение об истечении SSL-сертификата: считывается из существующего HTTPS-зонда (без дополнительного запроса), значок появляется, когда срок действия сертификата скоро истекает (< 15 дн. / < 7 дн.)
  • Аудит установленных приложений: сверяет occ app:list с магазином приложений Nextcloud для выявления приложений, требующих проверки — блокирующих (блокирующие обновление, несовместимые, тестовые приложения в продакшене) плюс информационные сигналы зрелости/турбулентности (недавно опубликованные, до версии 1.0, сборки alpha/beta/rc, всплеск релизов, свежевыпущенная версия)
  • Общепарковые блоки наблюдения: блок «Приложения для наблюдения» (📦) и двойной блок «Контейнеры для наблюдения» (🐳) агрегируют каждое отмеченное приложение / образ Docker во всех экземплярах в одну запись, с фильтрами по типу для каждой группы и всплывающим списком затронутых экземпляров и их версий
  • Упреждающие оповещения (webhook и/или электронная почта): срабатывают при подтвержденном изменении состояния вкл/выкл (офлайн, обслуживание, восстановление), чтобы вы получали уведомления без открытой панели управления — Slack / Mattermost / Google Chat / Discord / raw JSON (ALERT_WEBHOOK_URL), и/или дайджест по электронной почте за пакет (ALERT_EMAIL_TO), отправленный через прямую SMTP-отправку на ваш почтовый сервер (встроенный PHPMailer; при отсутствии настроенного SMTP-ретранслятора использует локальный MTA). Также охватывает медленные сигналы (ALERT_CHECKS): истечение SSL-сертификата (уровневый), уязвимая/устаревшая версия Nextcloud, устаревший Push-зонд, критический отчет аудита, блокирующая находка приложения — одно оповещение на каждое новое условие, без спама напоминаниями
  • Задержка устаревания обновления: экземпляр помечается как устаревший только через несколько дней после выхода патча (nc_update_grace_days), чтобы не гоняться за вышедшим в тот же день ошибочным релизом
  • Столбец состояния с принципом «тишина = всё в порядке»: отображает значки (⚠️ предупреждения, 📦 приложения, 🔄 Docker, 🔒 SSL, 🔴 офлайн, 🚧 обслуживание) только при наличии чего-то для отчета
  • Система кэширования для данных сервера и официальных версий

Страница сведений

  • Полный обзор конфигурации каждого сервера Nextcloud (PHP, OPcache, Redis, база данных…) для серверов Extended/Push
  • Базовая страница сведений для серверов без зонда: показывает версию, веб-сервер, HTTP-протокол и подсказку об обновлении
  • Процент доступности за 30 дней и список недавних инцидентов (начало, конец, продолжительность, причина), рассчитанные на основе ограниченного журнала переходов вкл/выкл — честная метка «измерено за N дней», пока журнал моложе окна
  • Правила предупреждений о конфигурации с индикаторами ⚠️, каждое из которых можно подтвердить (причина + необязательный срок действия)
  • Раздел отчета аудита сервера, когда экземпляр отправляет свой ежемесячный отчет nc-audit.sh
  • Доступен по клику на любое имя сервера или индикатор состояния

Интерфейс

  • Централизованная панель управления с обзором состояния (сводные карточки отображают количество офлайн-серверов / истекающих сертификатов / приложений для проверки только при ненулевых значениях)
  • Расширенные фильтры по статусу Nextcloud, статусу PHP, общему статусу, запущенному образу Docker и текстовому поиску
  • Официальные версии автоматически загружаются из источников Nextcloud
  • График выпуска с датами предстоящих версий
  • Интерфейс на FR / EN / DE (переключатель языка в правом верхнем углу)

Администрирование

  • Интерфейс администратора для настройки правил версий
  • Сводная таблица режимов зондов вверху: наглядно поясняет три метода сбора (Basic, Extended, Push)
  • Управление серверами через веб-интерфейс в виде карточек: две отдельные зоны для зондов (serverinfo / push), маскированные токены с возможностью раскрытия, inline-удаление
  • Кнопка «Настроить зонды» для каждого сервера для переключения зон токенов, состояние сохраняется в localStorage
  • Поиск серверов в реальном времени с поиском без учета акцентов
  • Генератор Push-скрипта: генерирует готовый к использованию bash-скрипт cron (chmod 700) для удаленного экземпляра Nextcloud, автоматически обновляется при изменении опций
  • Кнопка «Триггер Push» на панели управления: отправляет push-запрос на все настроенные push-серверы (видна, только если есть хотя бы один push-сервер, время охлаждения 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:~
## 🔌 Режимы сбора

Режимы не являются взаимоисключающими — сервер может одновременно находиться в режимах Extended и Push.

| Режим | Значок | Источник | Собираемые данные |
|------|-------|--------|----------------|
| **Basic** | *(нет)* | `/status.php` + HTTP-заголовки | Версия Nextcloud (PHP/веб-сервер, если раскрыты) |
| **Extended** | `⚡ Extended` (фиолетовый → оранжевый при ошибке/устаревании) | `/ocs/v2.php/apps/serverinfo/api/v1/info` с `NC-Token` | Версия NC, PHP, веб-сервер, OPcache, Redis, БД, активные пользователи… |
| **Push** | `📡 Push` (синий → оранжевый при ошибке/устаревании) | POST на `push-api.php` | Данные, отправленные удаленным экземпляром NC через cron-скрипт |

**NC-Token** для serverinfo доступен в **Nextcloud Настройки → Администрирование → Система**.

**Push-токен** генерируется из интерфейса администрирования; администратор предоставляет готовый bash-скрипт cron (`chmod 700`) для развертывания на контролируемом экземпляре.

Данные режима Extended предоставляются приложением [nextcloud/serverinfo](https://github.com/nextcloud/serverinfo), которое должно быть установлено и включено на контролируемом экземпляре.

**Поведение при ошибке**: если Extended API недоступен (ошибка соединения, неверный токен, приложение не установлено), NcStatusCheck автоматически переключается на `/status.php`, чтобы получить хотя бы версию Nextcloud.

**Порог устаревания Push**: push-сервер считается устаревшим, если данные не поступали в течение `auto_push_interval + 30 минут`. Интервал push по умолчанию — 12 часов.

### Столбцы таблицы на главной панели

На главной панели отображаются 5 столбцов: **Сервер** | **Версия NC** | **PHP** | **Проверки** | **Состояние**

Столбец **Проверки** показывает активные режимы сбора для каждого сервера:
- Значок `⚡ Extended` (фиолетовый, становится оранжевым при ошибке соединения или устаревших данных)
- Значок `📡 Push` (синий, становится оранжевым, когда данные не получены в течение порога)
- Оба значка могут появляться одновременно, если активны оба режима
- Нет значка = только режим Basic

### Столбец состояния

Столбец состояния показывает информацию только когда есть что-то требующее внимания:

| Индикатор | Значок | Значение |
|-----------|-------|---------|
| Офлайн | `🔴 Offline` | Экземпляр недоступен (HTTP-проверка не удалась), с указанием "офлайн X" |
| Активные предупреждения | `⚠️ N` | N проблем с конфигурацией |
| Аудит приложений | `📦 N` | N установленных приложений для проверки (блокирующих обновление/несовместимых) |
| Истечение SSL | `🔒 N дн` | Сертификат скоро истекает — оранжевый `< 15 дн`, красный `< 7 дн` или истек |
| Обновления Docker | `🔄 M` | M доступных обновлений контейнеров |
| Всё в порядке | *(пусто)* | Нечего сообщать |
| Нет данных | `?` | Режим Basic без push-данных |

#### Up/down & срок действия SSL

NcStatusCheck хранит **минимальное** состояние up/down для каждого сервера (только текущее состояние + дата последнего изменения — нет временных рядов, нет страницы истории). "Up" означает, что исходящий HTTPS-запрос достиг экземпляра; красный значок **Offline** появляется только при недоступности. Во время того же HTTPS-запроса бесплатно считывается **срок действия SSL-сертификата** (`CURLOPT_CERTINFO`) и отображается, когда он приближается к истечению. Оба параметра полностью видны на странице детализации. *Примечание: эти исходящие проверки не применяются к экземплярам только с Push, с которыми монитор никогда не связывается.*

#### Аудит приложений (`📦`)

Когда Push-сервер сообщает свои установленные приложения (`occ app:list`, push-скрипт v3+), NcStatusCheck сверяет их с каталогом приложений Nextcloud и помечает приложения, заслуживающие проверки. **Только сигнализация** — инструмент никогда ничего не отключает; он выявляет кандидатов (не может знать, используется ли приложение на самом деле). Используются только **фактические, бинарные** сигналы. Значок `📦 N` подсчитывает блокирующие находки (нет совместимой версии для текущей версии NC, нет версии для NC N+1 → блокирует обновление, или тестовое/разработочное приложение оставлено включенным в production). Информационные находки (приложение устарело на экземпляре, заброшено upstream, несовместимо с PHP) отображаются только на странице детализации. Находки можно отключать через тот же механизм подтверждения, что и предупреждения.

### `servers.json` format```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+) для любых приложений, доступных из интернета.
  • Веб-сервер nginx или Apache с поддержкой HTTPS
  • Сетевой доступ к серверам Nextcloud для мониторинга

Конфигурация веб-сервера (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` выше (root: блокирует `*.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. Добавление серверов

Серверы управляются непосредственно через интерфейс администратора (кнопка ⚙️ Admin). Вы также можете создать 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 работают от имени своего собственного пользователя (`www-data` в Debian/Ubuntu, `nginx`/`apache` в семействе RHEL — настройте ниже) — если вы клонировали репозиторий от имени своего пользователя, этот пользователь почти наверняка не будет `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 еще не существует (вы позволяете интерфейсу администратора создать его вместо ручного шага выше), то указанный выше chmod 600 просто не на что воздействовать — это нормально: ServersStore::save() сам меняет права файла на 0600 при каждой записи, поэтому servers.json, (пере)созданный через интерфейс администратора, никогда не остается доступным для чтения группой/всеми с информацией о сервере/токенами push внутри.

  1. HTTP-аутентификация```bash htpasswd -c /etc/nginx/.htpasswd admin
root@kitploit:~
6. **Запланированные задачи (опционально)**

Два дополняющих друг друга cron’а — установите оба **в одном вызове `crontab -`**:
`crontab -` устанавливает полностью новый crontab из stdin, он не добавляет, поэтому
запуск его дважды (по одному разу на каждую строку) оставляет только *вторую* задачу — первая
бесшумно исчезает, без ошибок. Это также сохраняет всё, что уже есть в вашем
crontab (сначала передав `crontab -l` через pipe) вместо его очистки:```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), поэтому может часто выполняться без нагрузки. Экземпляр помечается как down только после UPTIME_FAIL_THRESHOLD последовательных неудачных проверок (по умолчанию 2 → ~10 мин при 5-минутном интервале); восстановление до up происходит немедленно. Полный cron-update.php остаётся без изменений для всего остального.

Docker (альтернатива bare-metal)

Вместо шагов 1–6 выше, NcStatusCheck также может работать как небольшой стек docker compose (PHP-FPM + nginx + контейнер cron) — репозиторий монтируется как есть, без шага сборки или Composer, так что он точно повторяет bare-metal раскладку, только контейнеризован. Обслуживает только обычный HTTP (порт 8080 по умолчанию) — поставьте свой собственный обратный прокси с завершением TLS перед ним.

Полная настройка — конфигурация, подводные камни с правами (uid 82, предварительное создание servers.json), HTTP Basic Auth, cron, обновления и резервное копирование — полностью описана в deploy/docker/README.md. Начните оттуда; этот раздел намеренно является лишь указателем, чтобы не синхронизировать две копии одних и тех же шагов.

📋 Использование

Основной интерфейс

  • Перейдите на https://monitoring.your-domain.com
  • Просмотрите панель мониторинга со статусом всех ваших серверов
  • Используйте фильтры для сужения по статусу или поиску
  • Проверьте официальные версии и график выпуска

Администрирование

  • Откройте интерфейс администрирования через кнопку "⚙️ Admin"
  • Таблица сводки режимов зондирования в верхней части страницы объясняет различия между методами сбора Basic, Extended и Push
  • Управление серверами: каждый сервер отображается в виде карточки с двумя сворачиваемыми зонами зондирования:
    • Зона Serverinfo: настройка токена чтения (NC → NcStatusCheck pull)
    • Зона Push: генерация push-токена и загрузка готового к использованию cron-скрипта для удаленного экземпляра
  • Конфигурация Nextcloud: установка минимальных безопасных версий для каждой ветки (эффекты наведения на строки)
  • Конфигурация PHP: установка рекомендуемых/поддерживаемых статусов для каждой версии

Страница деталей

Доступна по клику на любое имя сервера или его индикатор здоровья.

Для серверов Basic (без зондирования Extended или Push) упрощенная страница показывает доступные данные (версия NC, веб-сервер, HTTP протокол) с уведомлением и предложением включить зондирование.

Для серверов Extended / Push полная страница деталей отображает отдельные разделы:

API

NcStatusCheck предоставляет несколько REST-эндпоинтов:

Основной API (api.php)

  • GET ?action=get_data — Получить данные (кэш или обновление)
  • POST ?action=refresh_data — Принудительное обновление всех серверов

Push API (push-api.php)

  • POST с заголовком push_token — Получить push-данные от удаленного экземпляра NC
  • POST ?action=request_push_all — Запросить немедленный push от всех настроенных push-серверов (устанавливает флаг триггера, который обрабатывается удаленным cron-скриптом)

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]. Ядро отказывается использовать конфиг, доступный для записи группе или всем (защита от внедрения кода).

Он многоцелевой (fan-out): данные собираются один раз и отправляются каждому монитору, перечисленному в /etc/ncstatuscheck/targets-<slug>.conf (одна строка url|push_token[|http_user|http_pass] на монитор). Администратор каждого монитора выдает идемпотентную команду для его регистрации.

Несколько экземпляров Nextcloud на одном хосте: пути для каждого экземпляра получают суффикс , полученный из отслеживаемого URL (например, → ): , , , , состояние . Только ядро является общим, поэтому расположенные на одном хосте экземпляры никогда не конфликтуют.

Detail API (detail-api.php)

  • GET ?server=<url> — Полные данные serverinfo + вычисленные предупреждения для сервера Extended/Push

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 для разового / ежемесячного аудита настройки веб-сервера + PHP + базы данных, сверяясь с физическими ресурсами машины (RAM, CPU, тип диска). Ориентирован на предложение управляемого наблюдения: клиент устанавливает его, монитор только получает отчеты — не требуется доступ к машине/сети. Скрипт только читает конфигурацию (без изменений), выводит цветной отчет и сохраняет копию в /tmp.

Что проверяется: производительность сервера (RAM/CPU/SSD-HDD, swappiness, определение общего хостинга) · Nextcloud (версии, cron, кэш, работа Redis, тип БД, журналы) · PHP/PHP-FPM (реальный обслуживающий SAPI, работа OPcache, память нескольких пулов) · Apache (память рабочих процессов с учетом MPM) · Nginx · PostgreSQL · MariaDB · гигиена безопасности (fail2ban или CrowdSec + bouncer + список блокировки сообщества; ожидающие обновления / перезагрузка / службы на устаревших библиотеках) · согласование бюджета 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, остальное покрывает БД + веб + ОС — уменьшайте на серверах с тяжелой БД) является долей PHP, распределяется между пулами 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:~
**Report push-back** (опционально, использует инфраструктуру Push): `nc-audit.sh --push /etc/ncstatuscheck/<slug>.conf` запускает аудит и отправляет отчёт POST-запросом монитору(ам), который(ые) сохраняет(ют) его и показывает(ют) на странице сведений о сервере (раздел «🩺 Аудит сервера»). Обычно ежемесячный cron. Веб-страница (админ, бета) по адресу `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-аутентификация Basic, дополненная проверкой аутентификации на уровне приложения для каждой административной конечной точки (защита в глубину)
  • Защита от CSRF: HMAC-токен автоматически внедряется в каждый мутирующий запрос (lib/csrf-client.js + csrf_require())
  • Защита от SSRF для каждого URL, предоставленного оператором (циклические адреса, RFC1918, link-local отклоняются; только HTTPS-редиректы; проверка IP после подключения)
  • Обязательное использование HTTPS с сертификатами Let's Encrypt
  • Защита файлов данных и журналов: правила nginx (см. выше) зеркалируются поставляемыми файлами .htaccess для Apache; servers.json автоматически получает права 0600 (внутри токены)
  • Заголовки безопасности (CSP, X-Frame-Options, nosniff, Referrer-Policy) на каждой странице, обслуживаемой PHP
  • Строгая проверка URL всех входных данных
  • Клиентские сценарии, выполняемые от root: конфигурация экземпляра загружается от root, а файл целей определяет, куда отправляются собранные данные — оба отклоняются, если они не являются ни групповыми/общедоступными для записи, ни принадлежащими третьей стороне
  • Изоляция между отслеживаемыми экземплярами: push принимается только тогда, когда URL в теле соответствует записи И проходит для токена записи, поэтому скомпрометированный отслеживаемый сервер не может ни прочитать, ни перезаписать данные другого сервера. / защищены административной аутентификацией + CSRF. Проверено сквозное тестирование в сценарии скомпрометированного клиента

Рекомендации

  • Используйте надёжные пароли для HTTP-аутентификации
  • Ограничьте доступ известными адресами — вкладка IP-фильтрации администратора генерирует правила автоматически (см. ниже)
  • Отслеживайте журналы на предмет попыток вторжения
  • Поддерживайте PHP и системные зависимости в актуальном состоянии

Баннер состояния config.php (админ)

config.php находится в .gitignore и редактируется вручную на каждом сервере, поэтому он расходится — молча, поскольку почти каждая константа имеет запасной вариант в коде. Баннер в верхней части административной страницы сообщает, что именно не так, и только когда что-то не так: PUSH_SCRIPT_VERSION, оставшаяся после обновления, отсутствие настроенного транспорта оповещений, закрывающий тег в конце, который выдаёт байт до любого header(), недоступный для записи каталог кэша, отсутствующие константы, молча использующие значения по умолчанию.

Только для чтения по замыслу и без действия сохранения, по той же причине, что и вкладка «Уведомления»: config.php принадлежит root и содержит секреты. Содержимое файла никогда не передаётся — только факты о нём — и ни один секрет не считывается.

Фильтрация по IP (вкладка админа)

Всё вышеперечисленное находится на уровне приложения: любой пользователь интернета всё ещё может достичь монитора и прощупать его, и только пароль останавливает их. Вкладка фильтрации по IP генерирует правила, которые помещают белый список перед приложением, так что неизвестные хосты вообще не могут с ним взаимодействовать. Это защита в глубину, а не замена базовой аутентификации или токенов push — и она всегда создаёт только текст для просмотра и вставки, она никогда не записывает конфигурацию веб-сервера или межсетевого экрана.

Два класса источников, намеренно неравных, чтобы скомпрометированный отслеживаемый сервер не мог получить доступ к админке:

КлассКтоИмеет доступ к
pushотслеживаемые экземпляры только в режиме Push/push-api.php, ничего больше
adminбастион / VPN / фиксированный офисный IPвсё

Экземпляры, опрашиваемые в режимах Basic/Extended, не открывают входящих соединений и не получают вообще никакой записи в белом списке.

Адреса берутся из двух источников, и разница важна: DNS-запись отслеживаемого домена — это его входной адрес, в то время как его push отправляется с его выходного. Если они различаются, работает только второй. Поэтому push-api.php записывает реальный исходный адрес каждого push (source_ip в кэше push), и вкладка включает его в белый список, сообщая о несоответствии. Пока сервер не отправил push хотя бы один раз, используется запасной вариант DNS A+AAAA с соответствующим уведомлением.

Три варианта вывода:

  • nginx (рекомендуется) — отдельный файл в conf.d (geo + map) плюс одна строка if ($ncsc_forbidden) { return 403; } в vhost. Нет необходимости дублировать блок fastcgi, статические файлы также охвачены (admin.html — один из них), а /.well-known/acme-challenge/ остаётся открытым, чтобы продление сертификата не нарушило работу беззвучно.
  • Apache 2.4 — <LocationMatch> с отрицательным просмотром вперёд плюс <Location> для конечной точки push, чтобы два раздела не пересекались, и ничто не зависело от порядка слияния Apache. Все адреса одного правила помещаются на одну строку Require ip: несколько строк внутри <RequireAll> работают как И, что никто не может выполнить.
  • ufw — грубый по своей природе (фильтр пакетов видит порты, а не URL), поэтому не может выразить разделение push/админ. Используйте его только как внешний слой.

Генератор отказывается выдавать что-либо, когда не указан ни один административный адрес, предупреждает, когда собственный адрес оператора не охвачен, и предупреждает, когда запрос прошёл через прокси (как geo, так и Require ip читают транспортный одноранговый узел, поэтому за прокси все клиенты выглядят одинаково). Сгенерированный фрагмент ufw помещает правило SSH первым, оставляет порт 80 открытым для проверки HTTP-01 и разъясняет ловушку IPv6: в отличие от nginx, который отклоняет незарегистрированный адрес IPv6, ufw не фильтрует IPv6 вообще, если не установлено IPV6=yes — хост с двойным стеклом в противном случае был бы полностью открыт через IPv6.

Известное ограничение, отображаемое на самой странице: после применения правил эта вкладка не обнаруживает ничего нового. Отклонённый push отвергается веб-сервером до того, как достигнет PHP, поэтому записанный адрес остаётся последним, который прошёл — и всё ещё выглядит проверенным. Два последствия: добавление Push-сервера означает повторную генерацию и повторное применение правил, иначе его первый push будет отклонён; а если адрес экземпляра меняется, новый можно прочитать только в журнале доступа веб-сервера (grep 'push-api.php' access.log | grep ' 403 '). Поэтому вкладка показывает дату последнего наблюдения каждого адреса и помечает его, если оно старше полного цикла пропущенных push — тот же порог, что и для предупреждения push_stale, которое покрывает ту же слепую зону с другой стороны.

Отличие проблемы фильтрации от любой другой: простой GET на конечной точке push чисто разделяет слои, без побочных эффектов и без необходимости токена — запускайте его с самой заинтересованной машины, так как оценивается именно её исходящий адрес:```bash curl -sS -o /dev/null -w '%{http_code}\n' https://your-monitor/push-api.php

root@kitploit:~
| Answer | Meaning |
|---|---|
| `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) и в shell-скриптах, которые выполняются **от root** на отслеживаемых экземплярах (`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 (без зависимостей) | да | инварианты экранирования `lib/ui-common.js` (обе прошлые регрессии XSS) |
| `phpmailer_freshness` | GitHub API | нет (`allow_failure`) | зафиксированная версия в поставке по сравнению с upstream-релизом |
| `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` сообщают факты из upstream** (CVE в `nginx:alpine` или та, исправление которой ещё не дошло до ветки Alpine, новый релиз PHPMailer), которые не может исправить merge request. Красный, но терпимый — это точный сигнал — «пора пересобрать/обновить поставку» — а не причина блокировать независящую работу. `phpmailer_freshness` сообщает о недоступном или ограниченном по частоте GitHub API как *пропуск* (skip), а не как «устарел».
- **`container_cve` сканирует образ, который он собирает, а не тег `FROM`.** Dockerfile укрепляет базовый образ с помощью `apk --no-cache upgrade` (официальный PHP-образ отстаёт от репозиториев Alpine — он поставлял c-ares 1.34.6-r0, в то время как 1.34.8-r0, исправляющий CVE-2026-33630, уже был опубликован). Сканирование тега base приводило бы к сообщению об уязвимостях, которых у поставляемого образа уже нет: вечно оранжевое задание, которое никто не читает.

Белые списки намеренно узкие: `.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` закрывает этот пробел. Это автономный, read-only 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

Он завершается с ненулевым кодом при любом критическом обнаружении (утечка исходного кода, незаблокированный секретный файл, общедоступное хранилище токенов, отсутствие Basic auth), поэтому может служить шлюзом для развёртывания — встройте его в свой скрипт синхронизации/развёртывания как пост-шаг. WARN/INFO никогда не приводят к сбою.

🧪 Тестирование и разработка

Режим разработки```php

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

root@kitploit:~
В режиме разработки отображается дополнительная информация (версия PHP, веб-сервер).

### Тестирование сервера
Используйте интерфейс администратора, чтобы добавить сервер по URL. Сервер будет опрашиваться при следующем обновлении данных.

### Журналы отладки
Проверьте файлы журналов в `cache/`:
- `monitor.log` — Общие журналы приложения
- `cron.log` — Полные журналы скрипта сбора (`cron-update.php`)
- `ping.log` — Легковесные журналы зондирования состояния (вверх/вниз) (`cron-ping.php`)
- `alerts.log` — Упреждающая отправка оповещений (вебхук/email), никогда не регистрирует секреты вебхуков или учетные данные SMTP

### Набор тестов```bash
php tests/run.php   # plain-PHP assertions, no framework — exit 0 = all green

Охватывает чистую бизнес-логику (правила версий/приложений, предупреждения, автомат состояния времени работы и доступности, автомат состояния дедупликации/перевооружения оповещений, построители писем).

🤝 Участие

Сообщение об ошибке

Откройте новый issue с:

  • Детальным описанием проблемы
  • Шагами для воспроизведения
  • Логами ошибок, если доступны
  • Конфигурацией вашего окружения

Предложение улучшения

  1. Откройте issue, чтобы обсудить вашу идею
  2. Сделайте форк проекта
  3. Создайте ветку для вашей функции
  4. Реализуйте с документацией
  5. Отправьте merge request

📝 Лицензия

Этот проект распространяется под лицензией GNU AGPL v3.

👥 Авторы

NcStatusCheck разработан ézéo, цифровым кооперативом, специализирующимся на решениях с открытым исходным кодом.

Участники

  • команда ézéo — первоначальная разработка и поддержка

Нужна помощь? Посмотрите issues или свяжитесь с командой ézéo.

Скачать инструмент
РазделПоля
Система NextcloudВерсия, режим отладки, локальный/распределенный memcache, блокировка файлов, дисковое пространство
PHPВерсия, memory_limit, upload_max_filesize, max_execution_time, FPM, OPcache
Веб-серверИмя + версия, HTTP протокол
База данныхТип, версия, размер
КэшRedis, частота попаданий APCu
Активные пользователиПоследние 5 мин, 1 час, 24 часа, 7 дней
<slug>
latest.ezeo.coop
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), никогда внутрь контейнера, и occ выполняется через docker exec: OCC_CMD=docker exec -u www-data <container> php occ (контейнер AIO: nextcloud-aio-nextcloud). Генератор скрипта администратора имеет предустановку типа установки, которая автоматически заполняет это. Никогда не добавляйте -t (нет TTY под cron); сохраняйте -u www-data (официальный образ отказывается выполнять occ от root).

Развёртывание/обновление на парке серверов: поскольку ядро представляет собой один идентичный файл, обновление логики на многих серверах = замена этого одного файла (маркер ↑ помечает серверы, работающие на старой версии). Смотрите deploy/ansible/ для готового плейбука (или простой цикл scp). Монитор остаётся пассивным — он никогда не отправляет код на серверы; точкой доверия является ваш собственный SSH-доступ, а не монитор.

Миграция с установки до v4 (монолитный скрипт для каждого экземпляра): удалите старые /usr/local/bin/ncstatuscheck-push-<slug>.sh и /etc/cron.d/ncstatuscheck-<slug> перед установкой ядра + конфига (targets-<slug>.conf используется как есть), иначе будет двойная отправка.

hash_equals()
этой
request_push
request_push_all
  • Отчетность о целях push: каждый экземпляр объявляет, на какие мониторы он отправляет данные (только URL, никогда не токены); страница с подробной информацией показывает их, и срабатывает предупреждение, когда набор изменяется — дополнительная строка в targets.conf беззвучно копирует каждый push третьей стороне
  • Очистка полезной нагрузки push: идентификаторы приложений проверяются по белому списку символов; свободные поля Docker (имя, образ, версия, статус) очищаются от <>"'& при приёме, в дополнение к экранированию при рендеринге
  • Проверка SSL/TLS для исходящих соединений — никогда не отключается, включая транспорт оповещений SMTP
  • Ограниченные удалённые ответы (2 МБ): отслеживаемый сервер полностью контролирует, что он отвечает, и в этом направлении ничто не аутентифицируется. Без ограничения сервер, который просто передаёт данные, исчерпает память PHP — фатальная ошибка, которую не перехватит ни один try/catch, и которая остановит сбор данных в середине цикла, а с ним и все оповещения для всего парка
  • Анонимизация в демо-режиме охватывает больше, чем URL: имена контейнеров, частные адреса реестров в ссылках на образы и имя хоста, указанное в сообщениях об ошибках cURL, все очищаются как на панели управления, так и на странице с подробной информацией