Сервер настраивают один раз, а живёт он дальше сам. Через месяц часть пакетов ждёт обновления, сертификат подошёл к трёхнедельному сроку, после установки чего-то постороннего в конфиге 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 и остальных модулей в ней нет, это уже платная. Но чтобы перестать держать недельный обход в голове, хватает и её. Как выглядят те же данные на полной панели — на страницах демо ниже.