Сервер налаштовують один раз, а живе він далі сам. За місяць частина пакунків чекає на оновлення, сертифікат підійшов до тритижневого строку, після встановлення чогось стороннього в конфігурації SSH з’явився зайвий рядок, а джейл, який має стежити за входами, зупинився, і про це ніхто не дізнався. Ніщо з цього не кричить — усе просто тихо перестає бути правдою.

Нижче — дванадцять речей, які має сенс перевіряти регулярно, з командами. Обхід займає хвилин п’ятнадцять. Порядок — від того, через що заходять, до того, що ламається саме.

SSH: п’ять рядків

Дивитися треба не на файл, а на підсумкову конфігурацію: вона збирається з /etc/ssh/sshd_config, усього каталогу sshd_config.d і типових значень збірки.

sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'

Що ми хочемо побачити: permitrootlogin no, passwordauthentication no, permitemptypasswords no, maxauthtries у межах 3–4 і x11forwarding no. Перші три — це двері, останні дві — їхні завіси: обмеження спроб на з’єднання і непотрібне на сервері прокидання графіки.

Два застереження, на яких легко втратити доступ. Перше: не вимикайте парольний вхід і вхід під root, доки не переконалися, що ключ працює — в окремій сесії, не закриваючи поточну. Якщо ви просто зараз заходите під root за паролем, ці два рядки замкнуть саме вас.

Друге: порядок файлів. OpenSSH бере те значення параметра, яке зустріне першим, а файли з sshd_config.d читаються за абеткою. На хмарних образах там зазвичай лежить 50-cloud-init.conf, і він переб’є ваш файл з назвою на кшталт 90-hardening.conf. Свої налаштування кладуть під меншим номером — 00- або 10-. Перевіряти результат усе одно за sshd -T, а не за тим, що написано у файлі.

Фаєрвол: одна перевірка

sudo ufw status verbose

Тут важливо пам’ятати, що вивід показує наміри, а не результат. Правило може стояти в списку й не закривати нічого: сам UFW вимкнено, порт слухає служба, опублікована Docker (він пише свої правила в iptables нижче UFW), або до сервера трафік просто доходить іншим шляхом. Тому корисно звіряти список правил з тим, що реально слухає назовні:

sudo ss -tulpn | grep -v '127.0.0.1\|::1'

fail2ban: дві перевірки

Мало того, що служба запущена, — потрібен ще робочий джейл для SSH:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Найчастіша прикрість тут — мовчазний джейл. На Debian 12 і свіжих Ubuntu системного журналу у вигляді файла /var/log/auth.log може не бути взагалі: rsyslog не встановлено, записи живуть лише в journald. Джейл зі стандартним logpath у цьому разі запускається, показує статус «активний» і не банить нікого ніколи. Лікується переведенням на журнал systemd:

printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban

Ознака, за якою це ловиться без копання в конфігах: у fail2ban-client status sshd рядки «Currently failed» і «Total failed» стоять на нулі, хоча в журналі невдалі входи є.

Оновлення: три перевірки

Окремо — скільки пакунків чекає взагалі, скільки з них стосуються безпеки і чи не просить система перезавантаження після оновлення ядра:

sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo 'потрібне перезавантаження'

Третя перевірка — чи увімкнені автоматичні оновлення безпеки, щоб перші дві не перетворювалися на щомісячний ритуал:

systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades

Файл має містити одиниці в обох рядках. Якщо пакунка немає: sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades.

Сертифікати: одна перевірка

Строк життя сертифіката Let's Encrypt — дев’яносто днів, і оновлення зазвичай працює саме рівно до того дня, коли перестає. Дивитися треба не в панель реєстратора, а на те, що сервер реально віддає:

echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run

Перша команда показує дату завершення в того сертифіката, який віддається за цим іменем; друга перевіряє, що оновлення пройде, не чекаючи справжнього строку. Корисно пройтися всіма іменами, які обслуговує сервер, а не лише головним доменом: забувають зазвичай про піддомен, доданий пізніше.

Диск: одна перевірка

df -h
df -i

Дві команди, бо місце й записи про файли закінчуються незалежно. Друга на більшості серверів упирається в стелю раніше за першу — мільйони дрібних файлів у сесіях PHP або в кеші застосунку дають IUse% 100 за вільних гігабайтів. Докладний розбір обох випадків у нас є окремо.

Що з цим переліком не так

Перелік правильний, але в нього є властивість: він вимагає, щоб хтось про нього пам’ятав. П’ятнадцять хвилин раз на тиждень — це небагато, поки сервер один і поки є привід. За два спокійні місяці обхід пропускається, а дізнатися про те, що джейл зупинився, виходить уже з чужих логів.

Тому ми зібрали рівно ці дванадцять перевірок в окрему безкоштовну панель — Arcivéo FREE. Вона ставиться однією командою, працює на вашому сервері, дані нікуди не йдуть, реєстрація не потрібна. Збирач запускається за кроном кожні п’ять хвилин і складає в локальну базу те саме: входи по SSH і відхилені підключення, стан UFW і fail2ban, очікувані оновлення безпеки, строки сертифікатів, місце на диску. Історія — сім днів, інтерфейс 34 мовами. Ціна нульова, зокрема й на робочому сервері: ліцензія дозволяє ставити панель на свої машини, включно з машинами компанії, і не дозволяє перепродавати її чи піднімати як послугу для чужих серверів.

Стек у безкоштовної версії скромний: вона ставить і вмикає UFW та fail2ban, а далі показує стан. ModSecurity, Suricata, AIDE та решти модулів там немає, це вже платна. Але щоб перестати тримати тижневий обхід у голові, вистачає й її. Як виглядають ті самі дані на повній панелі — на сторінках демо нижче.