Це посібник зі встановлення, налаштування та обслуговування Arcivéo Monitor. Розділи згруповано: загальний огляд, розгортання панелі, підключення інструментів безпеки, вбудовані модулі та діагностика. Команди можна копіювати кнопкою праворуч.
Встановлення панелі — на окремих покрокових сторінках. Оберіть спосіб:
Arcivéo Monitor — панель безпеки сервера. Збирає дані від встановлених інструментів (Fail2ban, UFW, Lynis, ModSecurity, AIDE, ClamAV, Auditd, CrowdSec, Suricata, Falco та ін.) і відображає їх у єдиному інтерфейсі з дашбордом, картою атак і детальними сторінками для кожного інструмента.
Монітор не є активним засобом захисту — він не блокує атаки самостійно. Його завдання — агрегувати інформацію від уже працюючих інструментів і подати її у зручному вигляді.
Монітор працює лише локально — його потрібно встановити на тому самому сервері, який він моніторить. Жодного SSH чи віддаленого API немає.
Усі команди (fail2ban-client, ufw status, ipset list тощо) панель виконує від імені користувача вебсервера (зазвичай www-data, на хостинг-панелях — обліковий запис сайту) з вузьким набором прав sudo — лише на конкретні утиліти, без загального root-доступу. Результати парсяться та відображаються у браузері.
Оцінка починається з максимуму та знижується за кожну виявлену проблему:
PermitRootLogin yes) — −20Підсумок: 80+ = Захищено, 60–79 = Увага, <60 = Під загрозою.
WebAuthn — стандарт автентифікації без пароля через апаратний ключ. Підтримує YubiKey, Touch ID, Face ID, Windows Hello, Passkey.
Після входу за паролем система запитує підтвердження через зареєстрований ключ. Навіть якщо пароль витече — без фізичного ключа чи біометрії увійти неможливо.
Для налаштування відкрийте Ключі WebAuthn у бічному меню та натисніть «Зареєструвати ключ». Зареєструйте одразу два ключі: якщо єдиний ключ загубиться або зламається, вхід у панель за ним буде неможливий.
Панель може надсилати звіт безпеки в Telegram і на пошту (за кнопкою та за розкладом). Налаштовується в розділі «Налаштування».
Telegram. Потрібні токен бота та chat id:
@BotFather → /newbot → отримайте токен виду 123456:ABC....@userinfobot або відкрийте https://api.telegram.org/bot<TOKEN>/getUpdates і знайдіть "chat":{"id":...}.Email. Два способи на вибір у «Налаштування» → Email:
re_...) та підтверджений домен відправника.Статус звіту: «УВАГА» або «ОК». Заголовок стає «УВАГА» лише за реальної проблеми чи дії, що очікує: знайдено загрозу ClamAV, зміни файлів в AIDE, критичні події Falco (Emergency/Alert/Critical за останні 24 год), впалий сервіс у Monit, потрібне перезавантаження, спливає SSL (≤14 днів) або чекають security-оновлення. Фоновий шум — SSH-перебори ботів, забанені fail2ban IP, алерти Suricata, попередження Lynis та вже відбиті запити ModSecurity — статус не піднімає, тож такі цифри у звіті самі по собі не означають «УВАГА».
Детальні модулі моніторингу (Lynis, UFW, ModSecurity, карта атак, AIDE, ClamAV та ін.) відкриваються за наявності чинної ліцензії. Без неї дашборд, налаштування та акаунт працюють, а модулі показують картку «Потрібна ліцензія».
Після придбання в кабінеті у вас є код активації вигляду ARCIVEO-XXXX-XXXX-XXXX-XXXX. Його потрібно «активувати» на домен вашої панелі — це перетворить код на підписаний ліцензійний файл (блок [license]), який ви вставляєте в панель.
Як активувати (3 кроки):
my.arciveo.com → розділ «Ліцензії» / «Активація ліцензії» — скопіюйте код ARCIVEO-….monitor.example.com). Натисніть активувати — система згенерує ліцензійний файл, прив'язаний до цього домену, і покаже його в полі з кнопкою «Копіювати».Панель перевіряє ключ криптографічно: підпис, прив'язку до домену та термін дії.
APP_URL у config.php і введіть лише ім'я хоста — без https:// і без префікса www. Активація одноразова: код перетворюється на ліцензію для введеного домену і повторно не активується — за помилки в домені ключ не підійде вашій панелі, а код буде витрачено. Тому вводьте домен уважно.
Усі основні параметри панелі задано в одному файлі config.php у корені (поряд із текою public/) звичайними константами define(). Файл створюється під час встановлення; правити його вручну потрібно рідко — переважно при зміні домену, перенесенні чи підключенні до іншої бази. Після будь-якої правки перезапустіть PHP-FPM (інакше через OPcache зміни не застосуються).
Підставте свої значення у підсвічені місця; решту залиште як є:
База даних. Реквізити підключення до MySQL/MariaDB:
DB_HOST — хост СУБД, майже завжди localhost;DB_NAME — ім'я бази даних панелі;DB_USER — користувач БД (доступ лише до своєї бази);DB_PASS — пароль цього користувача;DB_CHARSET — кодування з'єднання, залиште utf8mb4.Застосунок.
APP_URL — повна адреса панелі (напр. https://monitor.example.com). Має збігатися з доменом, на який активовано ліцензію — інакше ключ буде відхилено (див. розділ «Ліцензія»);TIMEZONE — часовий пояс PHP: впливає лише на те, як панель показує дати й час. На час запуску cron-завдань не впливає — там діє пояс системи (див. «Усі cron-завдання»).Час сесії. SESSION_LIFETIME — таймаут простою сесії в секундах (ковзний: оновлюється при активності). Типово 28800 = 8 годин; після цього часу бездіяльності панель попросить увійти знову. Наприклад, 3600 = 1 година, 86400 = доба.
Журналювання помилок. Помилки ніколи не показуються відвідувачам, а записуються у logs/php_errors.log — їх видно на сторінці «Логи застосунку». Ці рядки (display_errors=0, log_errors=1, шлях error_log) зазвичай змінювати не потрібно — налаштування задано прямо у файлі й не залежать від php.ini.
public/), а в цієї панелі вебкорінь (DocumentRoot) — саме корінь панелі, не public/. Сам по собі файл не «витікає»: у кореневому .htaccess для нього стоїть явна заборона (Require all denied) — сервер повертає 403. Навіть без цього правила вихідник не витік би: це PHP — сервер його виконує, а не віддає текстом. Про всяк випадок: не викладайте його в публічні репозиторії й не передавайте у підтримку з реальним паролем. Права на файл — 640.
UFW (Uncomplicated Firewall) — простий інтерфейс до nftables/iptables. Закриває всі вхідні порти, крім явно дозволених. Сторінка «Брандмауер UFW» показує стан і правила.
ufw enable обов'язково дозвольте SSH (ufw allow OpenSSH), інакше втратите доступ до сервера.
deny, не вважається доступним ззовні.
Skipping adding existing rule — це не помилка. UFW так повідомляє, що точно таке правило вже є, і повторно його не додає. Під час повторного запуску автоналаштування (воно ідемпотентне) це штатне повідомлення — реагувати не потрібно.
Автоматично блокує IP після перевищення кількості невдалих спроб входу. Аналізує логи SSH, nginx, Apache та інших сервісів.
Базове встановлення — вище. Тут — робоча конфігурація, що дає десятки активних jail та тисячі блокувань: загальні налаштування, ключові jail і автобан шкідливих IP зі списку ipsum.
Файл /etc/fail2ban/jail.local — загальні налаштування та найважливіші jail:
ignoreip обов’язково впишіть свій IP та довірені мережі, інакше можна забанити самого себе. Після правок: sudo fail2ban-client reload.
Автозавантаження блок-листа ipsum — до root-крону (sudo crontab -e): level 1 (100+ тисяч IP) вантажиться в набір ipsum, який відсікається на файрволі (докладніше — у розділі «Блок-лист IPset»):
ipsum — саме його читає дашборд (картка «IPset ipsum»). Рівні: levels/1.txt — максимальне охоплення, levels/3.txt — точніше (3+ джерела).
Чому «Монітор безпеки» поділено на дві зони. Захист працює на двох рівнях, і дашборд їх не змішує:
sshd, apache-*, nginx-* тощо) та злісні рецидивісти (jail recidive — ті, кого вже банили кілька разів). Це IP, які реально до вас ломилися — вони на карті атак і «Часовій шкалі».ipset ipsum, що відсікається на файрволі правилом DROP. Ці адреси здебільшого вашого сервера й не торкалися — їх ріжуть заздалегідь; лічильник «IPset ipsum» показує, скільки відсічено превентивно.Різниця проста: реактив — «ці атакували й отримали бан», превентив — «цих заблокували ще до спроби». Раніше в recidive штучно заганявся list-3 ipsum (звідси старий поділ «спискові recidive»); тепер recidive — лише справжні рецидивісти, а превентив цілком на файрволі.
ipsum — публічний список шкідливих IP, що оновлюється щодня. Монітор показує кількість завантажених адрес на дашборді та карті атак і враховує її в Оцінці безпеки (−10, якщо набір не завантажено).
Мінімальний варіант без fail2ban — окремий набір ipsum з блокуванням через iptables:
@reboot. Заразом команда create … -exist задає ліміт maxelem 300000 (за замовчуванням 65536 — level 1 не вміщується, буде «Hash is full»):
ipsum і, якщо файрволом керує інсталятор (свіжий VPS — профілі «Повна»/«Полегшена»), підключає набір до UFW правилом DROP — трафік із цих IP реально блокується. Правило стоїть після ESTABLISHED,RELATED, тому поточні з'єднання (зокрема ваш SSH) не розриваються — ріжуться лише нові підключення зі списку. Набір відновлюється під час завантаження сервісу ipsum-load.service до файрвола (інакше UFW не піднявся б) та оновлюється кроном о 04:00. На вже налаштованому сервері (панель, власний файрвол) інсталятор у файрвол не втручається — там ipsum залишається списком для дашборда й карти атак, а правило DROP за бажанням додається вручну (мінімальний варіант з iptables … --match-set ipsum … -j DROP — вище). При автовстановленні вручну робити нічого не потрібно.
Сучасна заміна Fail2ban з колективним threat intelligence: блокування від спільноти плюс власні правила. Потребує окремого bouncer для застосування блокувань до фаєрвола.
systemctl is-active crowdsec). Запустити: sudo systemctl enable --now crowdsec; у разі збою дивіться sudo journalctl -u crowdsec -n 30. Те саме правило для будь-якого сервісу зі статусом «Не запущено» (Suricata, Falco, Monit, MySQL).
stream halted / блокування не застосовуються. Це осиротілий api-ключ: bouncer було видалено з cscli bouncers list, але його старий ключ залишився в /etc/crowdsec/bouncers/*.yaml. Перереєструйте bouncer і пропишіть свіжий ключ:
AIDE (Advanced Intrusion Detection Environment) створює знімок файлової системи й під час кожної перевірки повідомляє про зміни в /etc, /bin, /usr. Після встановлення обов'язкова ініціалізація бази (aideinit).
aideinit термінал 5–15 хвилин стоїть на рядку Running aide --init... — це нормально (хешування всієї ФС, навантаження на диск). Не переривайте Ctrl+C. Якщо процес «висить», але нічого не пише — можливо, він чекає на відповідь на прихований запит Overwrite existing aide.db.new [Yn]? (натисніть Y). Перевірити активність з іншої сесії: pgrep -af aide.
aideinit: «21_aide_spamassassin … printf: invalid number» (return code 20) — відомий баг конфіг-сніпета AIDE в Ubuntu 22.04. База не створюється. Винесіть зламаний сніпет і повторіть:
aideinit не запускався, або (Ubuntu 24.04) каталог /var/lib/aide створено в режимі 700 і недоступний для www-data — лікується командою sudo chmod 755 /var/lib/aide (див. блок вище). «Перевірок не було» = база є, але перевірка ще не виконувалась — це не помилка. Результати монітор читає з /var/log/aide/aide.log.
/etc/cron.daily/aide на нових Ubuntu/Debian може не писати /var/log/aide/aide.log в потрібному вигляді (і aide.wrapper у них уже немає). Надійніше додати власний крон з явним --config — він пише лог від root у режимі 644, і монітор читає його без додаткових груп:
chmod 755 /var/lib/aide і крон перевірки о 02:00 — вручну нічого не потрібно.
sudo aideinit && sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db.
Антивірусний сканер для Linux. Особливо корисний для перевірки /var/www на PHP-шели та шкідливий код.
enable --now? Три типові причини:
1. У конфізі залишився рядок Example — clamd відмовляється стартувати, доки він там є:
2. Не завантажено базу сигнатур — clamd не стартує без неї:
3. Просто завантажується — clamd вантажить ~8 млн сигнатур у пам'ять 30–60 с. Зачекайте й перевірте: systemctl is-active clamav-daemon (статус activating → ще вантажить).
sudo journalctl -u clamav-daemon -n 30 --no-pager.
clamd лише тримає сигнатури в пам'яті, сам він нічого не сканує за розкладом. Панель показує результати планового сканування, тому потрібен крон, який сканує та пише лог. Автовстановлення додає обгортку /usr/local/bin/clamav-scan.sh і крон о 01:30 — після першого запуску заповняться «Файлів перевірено» та «Останнє сканування». Запустити одразу, не чекаючи розкладу: sudo /usr/local/bin/clamav-scan.sh.
Linux Malware Detect (LMD) — сканер шкідливого ПЗ для веб-загроз: PHP-шели, веб-бекдори, завантажувачі. Використовує рушій ClamAV і доповнює його власними сигнатурами.
maldet --report.
update-rc.d: error: unable to read /etc/init.d/maldet — він безпечний. maldet не використовує init.d, оновлення сигнатур і сканування запускаються через /etc/cron.daily/maldet. Якщо нижче видно installation completed — все встановилося.
apt, а в /usr/local/maldetect, і за увімкненого open_basedir його наявність перевіряється через shell — див. розділ «Сторінка порожня, хоча дані на сервері є».
Мережева система виявлення вторгнень: аналізує трафік на рівні пакетів і знає тисячі сигнатур атак. Доповнює ModSecurity (той працює на рівні HTTP, Suricata — на рівні TCP/IP).
/var/log/suricata/eve.json під root у режимі 750 на каталог, і вебсервер (www-data) не може його прочитати. Відкрийте каталог на прохід — файли всередині залишаються захищеними:
Перехоплює системні виклики через eBPF/kernel module і виявляє аномалії в реальному часі: shell із nginx, читання /etc/passwd вебпроцесом, запис у /bin тощо.
journalctl -u falco (без sudo — через групу systemd-journal). Переконайтеся, що www-data є в цій групі — див. «Налаштування sudo» (п.2) на сторінці ручного встановлення.
/etc/passwd, запис у системні каталоги). Нуль критичних за добу на спокійному сервері — здоровий стан.
journalctl потребує прав на журнал; щоб панель бачила події стабільно, автовстановлення вмикає у Falco file_output → /var/log/falco/falco.log і службі ставить UMask=0022 (лог читається вебсервером). Вручну на новому встановленні це налаштовувати не потрібно.
ModSecurity — вебфаєрвол (WAF) для Apache або Nginx. Блокує атаки на рівні застосунку: SQL-ін'єкції, XSS, обхід шляхів, сканери.
IncludeOptional /etc/modsecurity/*.conf, а пакет кладе лише modsecurity.conf-recommended — під маску *.conf він не потрапляє. Якщо не скопіювати його в modsecurity.conf, SecRuleEngine залишається Off: модуль завантажено, правила CRS завантажено, але трафік не перевіряється й аудит-лог не створюється. Проміжний режим DetectionOnly лише записує події в лог, не блокуючи запити — панель показує його жовтим.
Доступ панелі до аудит-логу. Лог /var/log/apache2/modsec_audit.log належить root (права 640), вебкористувач його не прочитає. Панель бере дані через обгортку — створіть її:
SecRuleEngine без відступу: рядки з відступом розташовані всередині блоків <LocationMatch>/<Directory> (наприклад, вимкнення WAF для phpMyAdmin) і глобального режиму не визначають.www-data, у HestiaCP пул сайту працює від власника сайту (наприклад, admin) — перевірте grep -E '^user' /etc/php/*/fpm/pool.d/monitor.example.com.conf.X-Forwarded-For. У статистику потрапляють лише транзакції зі спрацьованим правилом: директива SecAuditLogRelevantStatus пише в аудит-лог будь-які відповіді 4xx/5xx, тому туди потрапляють і звичайні 403/500 — подіями WAF панель їх не вважає.---RULES--- потрібен розділу «Усі активні правила» — панель показує не лише спрацьовані, а взагалі всі завантажені правила CRS + кастомні. Три шляхи в циклі for f in … — типові місця для CRS-правил і локальних доповнень; якщо у вас інше розташування (пакет ставить файли у свій каталог, або кастомні правила лежать не в /etc/modsecurity/custom-rules.conf), знайдіть справжні шляхи командою sudo grep -rl 'IncludeOptional\|^Include ' /etc/apache2/mods-enabled/security2.conf /etc/apache2/conf-enabled/*.conf 2>/dev/null і підставте їх у список. Якщо обгортка стара (без цієї секції) — розділ просто покаже попередження «недоступно», решта сторінки працює як раніше.
Auditd (Linux Audit Daemon) фіксує системні виклики на рівні ядра: входи та виходи, sudo-команди, невдалі спроби автентифікації, зміни файлів. Монітор показує входи, невдалі спроби та sudo-команди за сьогодні.
ausearch (/usr/sbin/ausearch) і за потреби з /var/log/audit/audit.log командою tail. Обидва мають бути в sudoers.
Стежить за сервісами (nginx, php-fpm, mysql тощо) і перезапускає їх у разі падіння. Може надсилати сповіщення на email.
monit status. У /etc/monit/monitrc має бути увімкнений HTTP-інтерфейс (блок set httpd з allow localhost), інакше monit status поверне помилку.
monitrc рядок set httpd закоментовано (за замовчуванням він іде як # set httpd port 2812 …). Розкоментуйте блок і дозвольте localhost. (2) Сам собою увімкнений httpd нічого не відстежує — Monit рахує лише те, що описано check-стансами; без них список порожній навіть за робочого інтерфейсу. Мінімальний робочий конфіг:
conf.d з httpd на 2812 і набором перевірок — на новій установці налаштовувати вручну не потрібно.
PSAD аналізує журнал iptables і виявляє сканування портів та мережеві атаки, присвоюючи кожному джерелу рівень загрози (1–5). Доповнює fail2ban і Suricata.
psad --Status (потрібен у sudoers). Без логування iptables сторінка буде порожньою — це нормально, поки не було сканувань.
Mandatory Access Control обмежує, до яких файлів і ресурсів може звертатися програма, навіть якщо її зламали. В Ubuntu/Debian за замовчуванням використовується AppArmor (зазвичай уже встановлений і активний).
aa-status (потрібен у sudoers). Показує кількість профілів у режимі enforce/complain і процеси без профілю.
«Профілів завантажено» більше, ніж enforce + complain — це нормально. У AppArmor 4.x (Ubuntu 24.04 і новіше) з’явився режим unconfined: профіль завантажено в ядро, але він нічого не обмежує. Ubuntu так позначає десятки профілів для програм, що використовують user namespaces (браузери, torrent-клієнти тощо). Коли такі профілі є, картка «Профілів завантажено» стає бурштиновою і показує їхню кількість — наприклад unconfined: 90 при 120 завантажених і 26 в enforce. Реально захищають лише профілі в enforce; на Ubuntu 22.04 (AppArmor 3.x) цього режиму немає і цифри завжди збігаються.
unconfined, варто лише свідомо: їх вимкнено не помилково, а тому що інакше ламається робота самих програм. Профілі в complain — інша річ: там правила вже написані й лише не застосовуються.
debsums перевіряє, чи файли встановлених пакетів збігаються з контрольними сумами з репозиторію — виявляє підмінені системні бінарники (доповнює AIDE). Повна перевірка триває 1–2 хвилини, тому запускається за cron, а панель читає результат із data/debsums/debsums.log і сама розкладає за категоріями (важливі лише бінарники та бібліотеки).
Завдання — у root-крон (sudo crontab -e). Готова обгортка debsums-scan.sh кладеться в /usr/local/bin/ (chmod +x; див. зведення cron-завдань) і сама пише звіт у data/debsums/ панелі.
Обгортка debsums-scan.sh сама знаходить data/ панелі — шлях прописувати не потрібно.
/etc/ (конфіги) та /usr/share/ (ресурси) на сервері зазвичай нормальні — панель позначає їх окремим кольором. Тривожними є зміни бінарників і бібліотек (/bin, /sbin, /usr/lib тощо) — картка «Бінарники / бібліотеки» показує саме їх.
Lynis запускається вручну або через cron. Звіт має зберігатися в папку data/lynis/ проєкту — монітор читає файл lynis-report.dat.
lynis-scan.sh у фоні прямо з панелі (не чекаючи cron): показує «Сканування…» і після завершення сама оновлює звіт. Для цього вебкористувачу потрібен рядок sudoers на запуск скрипта — інсталятор додає його автоматично у /etc/sudoers.d/monitor. Якщо панель встановлювалася вручну/раніше, допишіть його тим самим користувачем, що вже вказаний у файлі:
Logwatch має зберігати щоденні звіти в папку data/logwatch/ проєкту у форматі .txt. Монітор показує останній звіт та архів.
Мережевий монітор не потребує встановлення — це вбудована сторінка панелі. Вона показує мережевий стан сервера з локальних джерел:
/proc/net/dev;ip;ss;journalctl -k.Перші три джерела працюють без sudo, тому інтерфейси, трафік, з'єднання та порти видно одразу. Блок «Події ядра» використовує journalctl -k — він читається через групу systemd-journal («Налаштування sudo», п.2), sudo не потрібен. Перевірити, що все доступне вебкористувачу:
UFW BLOCK сюди не потрапляють — вони на сторінках «Брандмауер UFW» та «Карта атак». Порожній блок із зеленою галкою = за добу мережевих збоїв не було.
Вбудована сторінка показує три речі:
df); шкала червоніє при ≥90%;lsblk), лише реальні (loop/snap приховані);smartctl).Місце та список пристроїв працюють одразу, без налаштування. Для SMART потрібен пакет smartmontools. Веб-процес не має прямого доступу до дискових пристроїв, тому SMART знімається за cron у файл data/disk/smart.txt, а панель його читає.
Завдання — у root-крон (sudo crontab -e). Готова обгортка smart-scan.sh кладеться в /usr/local/bin/ (chmod +x; див. зведення cron-завдань) і сама пише в data/disk/ панелі.
Обгортка smart-scan.sh сама знаходить data/ панелі — шлях прописувати не потрібно. Всередині lsblk -e7,11 виключає loop/cdrom.
Сторінка показує історію навантаження сервера за останні 24 години — Load Average, завантаженість CPU та очікування I/O, RAM/Swap, мережевий трафік (приймання/передавання), дисковий I/O (читання/запис), заповнення диска та inodes, відкриті файлові дескриптори і MySQL-з’єднання, а також поточну кількість TCP-з’єднань і процесів.
Дані збирає cron/collect_metrics.php — раз на 5 хвилин записує один «сирий» знімок лічильників (/proc/loadavg, /proc/meminfo, /proc/stat, /proc/net/dev, /proc/diskstats, df/df -i, /proc/sys/fs/file-nr, SHOW GLOBAL STATUS LIKE 'Threads_connected') у таблицю БД system_metrics; відсотки та швидкості сторінка обчислює сама за різницею між сусідніми знімками (заповнення диска/inodes/дескрипторів/MySQL-з’єднання — миттєві значення, без перерахунку). Sudo не потрібне — джерела читаються без прав root. Точки, старші за 24 години, видаляються автоматично під час кожного запису.
Обгортка collect-metrics-all.sh (див. зведення cron-завдань) сама знаходить усі встановлені на сервері інстанси панелі та запускає cron/collect_metrics.php кожного від імені власника сайту.
Сповіщення про навантаження (розділ «Налаштування» → «Сповіщення про навантаження») — коли перевищено поріг CPU/RAM/диска/inodes, панель надсилає сповіщення в Telegram/Email (ті самі канали, що й щоденний звіт — окремо вмикати їх для сповіщень не потрібно), і ще одне — коли метрика повернулася до норми. Повторно під час утримання порогу не спамить: наступне сповіщення надійде лише після циклу «відновилося → знову перевищило».
collect_metrics.php під час кожного запуску (раз на 5 хвилин) — окремий cron не потрібен. Стан «уже сповістили / ще ні» зберігається у data/alerts_state.json, пороги — у налаштуваннях панелі.
Сторінка «Карта атак» визначає країну за IP командою geoiplookup. Без пакета GeoIP країни не визначатимуться і точки на карті не з’являться:
/usr/share/GeoIP/GeoIP.dat доступна для читання всім, результати кешуються в tmp/geoip_cache.json. Сама карта (Leaflet + плитки OpenStreetMap) завантажується в браузері — потрібен інтернет на комп’ютері, де відкрито панель.
Дві вбудовані картки дашборда, що показують не «увімк./вимк.» інструмента, а реальну захищеність сервера. Встановлення не потребують, читаються локально без sudo.
Зовнішня експозиція — скільки сервісів слухають усі інтерфейси (0.0.0.0/[::]) і доступні ззовні. Підсвічує червоним, якщо назовні стирчать СУБД чи кеш (MySQL, PostgreSQL, Redis, MongoDB, Memcached, Elasticsearch) — це пряма діра (−10 до Оцінки безпеки). Джерело: ss -tuln.
127.0.0.1 (bind-address у конфізі MySQL/PostgreSQL, bind 127.0.0.1 у Redis) або закрийте порт у UFW.
127.0.0.1 (loopback), видно лише самому серверу — ззовні на нього не потрапити, навіть якщо порт «відкритий». Тому Postfix на порту 25, прив’язаний до loopback, безпечний: автоналаштування ставить inet_interfaces = loopback-only (плюс нейтральний smtpd_banner — закриває зауваження Lynis MAIL-8818 про розкриття версії). Картка «Зовнішня експозиція» рахує назовні лише те, що слухає 0.0.0.0/[::]; loopback-сервіси туди не потрапляють.
/etc/postfix/main.cf задайте smtpd_banner = $myhostname ESMTP (без версії та ОС) і inet_interfaces = loopback-only, потім sudo systemctl restart postfix.
Оновлення безпеки — скільки security-патчів чекають установлення й чи потрібне перезавантаження після оновлення ядра (−5 до Оцінки безпеки за наявності патчів). Джерело: /usr/lib/update-notifier/apt-check, файл /var/run/reboot-required. Детальний список — на сторінці «Оновлення безпеки».
update-notifier-common). Якщо apt-check відсутній — монітор рахує патчі через apt-get -s upgrade.
Автооновлення безпеки (unattended-upgrades) — на сторінці «Оновлення безпеки» окрема картка показує, чи ввімкнено автоматичне встановлення security-патчів і коли воно запускалося востаннє. Sudo не потрібен — статус читається через apt-config dump.
Резервна копія — головна страховка: втрата даних гірша за будь-який злам. Потрібні дві речі — резервна копія сервера/сайтів та окремо резервна копія БД панелі (там користувачі, ключі WebAuthn, налаштування, ліцензія).
Варіант A — HestiaCP: вкладка Backup у користувача → кнопка створення резервної копії (або за розкладом у налаштуваннях сервера). Копія включає сайти та їхні БД.
Варіант B — вручну (cron): дамп БД + архів каталогу data/ панелі:
Оновлення до нової версії. Спершу зробіть резервну копію. Потім перезалийте файли коду, зберігши свої дані:
public/, includes/, assets/, cron/, database/, а також кореневі .htaccess (фронт-контролер — маршрутизацію не можна лишати від старої версії), manifest.json, sw.js;config.php (дані БД), data/ (звіти), logs/, tmp/ (сесії та кеш).SSH_FX_PERMISSION_DENIED — Permission denied. Файли панелі належать www-data (так їх виставили під час встановлення), а SFTP-клієнт підключається під вашим власним користувачем, у якого немає права запису. Віддавати www-data всю панель «щоб працювало» — саме те, що призводить до цієї помилки; нижче три способи, будь-який розв'язує проблему.
data/ (звіти), tmp/ (сесії та кеш), logs/; вони лишаються за www-data. Решта — код, і вебсерверу він потрібен лише на читання, яке дає група www-data з правами 644. Побічний виграш: за вразливості в PHP файли панелі вже не переписати. На хостинг-панелях (HestiaCP і подібні) варіант A не потрібен: там файли сайту й так належать акаунту, під яким ви заходите через SFTP, а вебсервер читає їх за групою.
chmod по файлах скидає ACL-маску, і доступ мовчки зникає. Якщо після «наведення ладу в правах» заливання знову впирається в Permission denied — повторіть обидві команди setfacl.
2 у варіанті C — це setgid: файли, завантажені через SFTP, лишаються в групі www-data, інакше панель не зможе їх перезаписати. Після варіанта C перепідключіться у FileZilla — нова група застосовується лише при новому вході. Перевірка: id deploy (має з'явитися група www-data) і ls -ld /path/to/monitor (drwxrwsr-x — літера s означає, що setgid встановлено).
Перенесення на інший сервер:
config.php, data/.mysqldump на старому → імпорт на новому; виправте дані БД у config.php.adm, cron-завдання.Якщо ви не можете увійти — усе виправляється безпосередньо в БД із сервера. Відкрийте БД (ім'я — з config.php):
Втрачено ключ WebAuthn (не проходить другий фактор) — вимкніть 2FA, увійдіть за паролем, зареєструйте новий ключ:
Забули пароль — задайте новий хеш (згенеруйте його на сервері та підставте):
Заблокували себе IP-фільтром — вимкніть обмеження:
sudo mysql на сервері або phpMyAdmin / розділ БД у панелі хостингу. Після відновлення знову ввімкніть WebAuthn та IP-фільтр.
Зведення завдань — у root-cron сервера (додаються через sudo crontab -e). Залиште лише рядки тих інструментів, які використовуєте; підправте шляхи під свій сервер.
sudo crontab -l і що cron-служба активна.
TIMEZONE з config.php. Константа TIMEZONE впливає лише на PHP (як панель показує дати), але cron-демон запускає завдання за системним часом ОС. Якщо пояс сервера не збігається з вашим, звіт «08:00» надійде не в той час. Приклад: сервер стоїть в іншому поясі (Europe/Berlin, UTC+2), а ви — у Києві (UTC+3) → звіт «08:00» надійде о 09:00 за вашим часом. Перевірте й за потреби приведіть пояс системи до свого:
0 8 * * * спрацює о 08:00 за місцевим часом. Інакше зсувати довелося б сам cron, але під час переходу на зимовий/літній час зсув знову розійдеться — тому правильніше налаштувати пояс системи.
crontab.txt) лежать у теці system/ поруч із проєктом, поза public_html. Це не частина сайту — у вебкорінь їх завантажувати не потрібно; розмістіть на сервері за системними шляхами (як у crontab вище):
lynis-scan.sh → /usr/local/bin/ (chmod +x) — запускає lynis audit system, на час скану ставить прапорець /tmp/lynis-running і копіює lynis-report.dat у data/lynis/ панелі;logwatch_daily.sh → /usr/local/bin/ (chmod +x) — формує щоденний звіт Logwatch (sshd, fail2ban, sudo, postfix) у data/logwatch/;smart-scan.sh → /usr/local/bin/ (chmod +x) — знімає стан дисків (smartctl) у data/disk/;debsums-scan.sh → /usr/local/bin/ (chmod +x) — перевіряє цілісність пакетів (debsums) у data/debsums/;clamav-scan.sh → /usr/local/bin/ (chmod +x) — антивірусний скан ClamAV за небезпечними шляхами (web, home, temp); пише зведення у /var/log/clamav/scan.log, звідки його читає сторінка ClamAV (рядок 01:30 у crontab вище);load-ipsum.sh → /usr/local/bin/ (chmod +x) — оновлює ipset-набір ipsum (level 1) на місці, не розриваючи чинних правил файрвола (рядок 04:00 у crontab вище);daily-report-all.sh → /usr/local/bin/ (chmod +x) — запускає звіт cron/daily_report.php панелі (рядок 08:00 у crontab вище);daily_report.php — уже входить до панелі (cron/daily_report.php), запускається через daily-report-all.sh, окремо ставити не потрібно;collect-metrics-all.sh → /usr/local/bin/ (chmod +x) — запускає cron/collect_metrics.php панелі (сторінка «Продуктивність», рядок */5 у crontab вище); collect_metrics.php уже входить до панелі, окремо ставити не потрібно;crontab.txt (system/cron/) — зразок завдань; потрібні рядки впишіть через sudo crontab -e./usr/local/bin/. Напряму з FileZilla туди не записати — каталог належить root, і SFTP-клієнт отримає SSH_FX_PERMISSION_DENIED. Порядок такий: спершу залити файл у /tmp (туди пишуть усі), потім перенести його на місце однією командою:
/tmp у корені сервера — не /var/tmp і не tmp/ усередині самої панелі (останній належить www-data і закритий від вашого користувача). У дереві FileZilla /tmp — гілка верхнього рівня, поруч із var, а не всередині неї.
/usr/local/bin/, лог — /var/log/arciveo-cron.log) — вручну нічого робити не потрібно.
/home/*/web/*/public_html та /var/www/*, і кладуть звіти в їхні data/. Якщо панель лежить за іншим шляхом — додайте його в рядок for app in … всередині скриптів, інакше звіти Lynis/SMART/debsums/Logwatch у панель не потраплять.
logs/cron.log першим створює root-cron — він належатиме root, і вкладка «Журнал cron» у панелі не зможе його ні прочитати, ні очистити. Створіть файл заздалегідь від імені вебкористувача (власник каталогу сайту; в HestiaCP це акаунт, напр. admin) — тоді root-cron лише дописуватиме, не змінюючи власника:
stat -c %U /path/to/monitor.
sudo crontab -e), інакше воно виконуватиметься двічі.
sudo crontab (це була б пряма ескалація до root будь-ким, хто отримає доступ до сесії панелі), а вузький скрипт із двома командами (list/set), що чіпає лише свій блок між службовими коментарями. Установіть один раз:
www-data — перевірте, під ким працює пул PHP-FPM сайту (ps -o user= -C php-fpm), і підставте його в рядок sudoers.
public/crontab_monitor.php завантажено через FTP/SFTP під іншим системним користувачем (наприклад, root), ніж решта файлів сайту, вебсервер не зможе його прочитати. Звірте власника й права із сусіднім файлом і приведіть у відповідність:
Монітор визначає наявність інструментів через dpkg-query — базу пакетів APT. Якщо інструмент установлено не через apt (вручну, зі snap або з вихідних кодів), dpkg його не бачить.
Помилка 500 — перевірте логи PHP, nginx та самого монітора:
www-data, а під обліковим записом користувача (наприклад admin — власник каталогу сайту). Усі sudo-правила та членство у групах (adm, systemd-journal) потрібно прописувати на цього користувача, інакше модулі покажуть «Не активний / 0» за працюючих сервісів. Дізнатися реального користувача PHP: ps -o user= -C php-fpm | sort -u або власник каталогу сайту stat -c '%U' /path/to/monitor. Далі в усіх командах нижче підставляйте його замість www-data. Автовстановлення визначає веб-користувача саме та прописує sudoers на нього.
Дані не відображаються — майже завжди незадані sudo-права. Перевірте конкретну команду від імені веб-користувача (замініть www-data на свого). Прапорець -n = без пароля, як у PHP — якщо просить пароль, отже правила в sudoers немає:
sudo aa-status у терміналі показує профілі, а сторінка «AppArmor» — «Неактивний»). Причина: у веб-користувача немає sudo-права на команду цього модуля. Перевірте її зі списку вище: якщо просить пароль — додайте відсутній рядок до /etc/sudoers.d/monitor («Налаштування sudo»). Часті «нові» команди: /usr/sbin/aa-status (MAC), /usr/sbin/psad --Status (PSAD).
apache2ctl, ausearch, aa-status чи ss, або веб-користувач не в групах adm/systemd-journal (звідти читаються логи fail2ban/auth/modsec і journalctl — Falco та події ядра).
Симптом: на сервері дані є (через shell видно), а сторінка показує «немає даних» або хибний статус — наприклад AIDE пише «Не ініціалізована», хоча базу створено.
Причина — open_basedir: багато панелей і хостингів обмежують пул PHP-FPM каталогом домену, тому PHP-функції file_exists(), file_get_contents(), filemtime() за системними шляхами (/var/lib/aide, /var/log, /proc…) блокуються. Монітор обходить це, читаючи такі шляхи штатними системними командами (cat, test, stat).
open_basedir. Правильне рішення — читання системними командами (уже зроблено для AIDE та Мережевого монітора). Розширювати open_basedir на /var, /proc не потрібно і менш безпечно.
Монітор перевіряє сертифікати, підключаючись до доменів напряму через порт 443. Якщо домен недоступний із самого сервера або порт закритий фаєрволом — перевірка не пройде.
/etc/nginx/sites-enabled/, /etc/nginx/conf.d/) та Apache (/etc/apache2/sites-enabled/) плюс поточний хост із HTTP_HOST.
Монітор під'єднується до MySQL під користувачем із config.php, який має доступ лише до власної бази. MySQL показує в information_schema тільки бази з привілеями — тому решта не видно.
Щоб монітор бачив усі БД, надайте цьому користувачу право лише на читання (один раз від root; підставте ім'я користувача з config.php):
sudo mysql панель не використовує: список баз береться через її власне PDO-під'єднання.
PostgreSQL потребує доступу на рівні користувача postgres, якого веб-користувач панелі не має. Відкривати з PHP широкий sudo psql небезпечно — натомість панель викликає вузьку обгортку без параметрів, яка лише виводить версію, кількість з'єднань і список баз з розмірами. Створіть її:
monitor-pgstat із sudoers (крок 13 ручного встановлення) і сам скрипт не створюйте: картка PostgreSQL просто залишиться неактивною.
Панель показує, що відбувається; нижче — що робити в типових ситуаціях. Загальний принцип: не панікувати, звірити з легітимною активністю (ваші дії, оновлення, резервні копії) і реагувати за серйозністю.
ignoreip./etc, поза /usr/share) — потенційно підміна. Звірте пакет: debsums PACKAGE_NAME, за сумніву перевстановіть його (apt install --reinstall).127.0.0.1 або закрийте порт в UFW. Це справжня діра.certbot renew або налаштування в панелі).sudo apt update && sudo apt upgrade; після оновлення ядра перезавантажте сервер.