Мониторинг домашнего сервера: письма о дисках, месте и упавших службах
Сервер сам пишет на почту, если диск начинает умирать, место кончается или не выполнился ночной бэкап. msmtp, smartd, таймер systemd и OnFailure — проверено на чистом Debian 12.
Бэкап, который тихо перестал делаться полгода назад, хуже, чем никакого: вы спокойны, а защиты нет. Диск, который начал сыпаться, место, которое кончилось, служба, которая упала ночью, — сервер обо всём этом знает. Нужно только научить его рассказывать.
Это последняя, четвёртая часть цикла «Домашний сервер без боли». Настроим уведомления на почту: о проблемах с дисками, о нехватке места и о любой упавшей службе.
Что получим и что нужно заранее
Результат: сервер сам пишет вам письмо, если диск начинает умирать, если место на разделе кончается и если не выполнилась важная служба, например ночной бэкап из третьей части.
Нужно: Debian 13 или 12 после первых частей цикла и почтовый ящик, от имени которого сервер будет отправлять письма. Лучше завести для этого отдельный ящик. У большинства почтовых сервисов для таких программ нужен пароль приложения — он создаётся в настройках безопасности почты отдельно от основного пароля. Команды проверены на чистых Debian 12 и 13; работа с дисками — по документации smartmontools, в контейнере реальных дисков нет.
Шаг 1. Научим сервер отправлять почту
Ставить полноценный почтовый сервер ради уведомлений не нужно. Хватит msmtp — маленькой программы, которая передаёт письмо в ваш почтовый сервис как обычный почтовый клиент.
sudo apt install msmtp msmtp-mta
Пакет msmtp-mta делает msmtp системной командой sendmail — через неё письма отправляют smartd и другие программы.
sudo tee /etc/msmtprc >/dev/null <<'EOF'
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog LOG_MAIL
account server
host smtp.yandex.ru
port 465
tls_starttls off
from server@example.ru
user server@example.ru
passwordeval "cat /etc/msmtp-password"
account default : server
EOF
sudo chmod 600 /etc/msmtprc
Настройки отправки. Пример — для Яндекс Почты; у другого сервиса будут свои host и port, их пишут в справке почты в разделе про почтовые программы. Адрес server@example.ru замените на свой ящик.
sudo sh -c 'printf "%s" "ПАРОЛЬ_ПРИЛОЖЕНИЯ" > /etc/msmtp-password'
sudo chmod 600 /etc/msmtp-password
Пароль приложения — в отдельный файл, закрытый от всех, кроме root.
printf 'Subject: Проверка\n\nСервер умеет писать письма.\n' | sudo msmtp you@example.ru
Отправляем тестовое письмо на ваш основной адрес. Если пришло — канал работает.
Шаг 2. Команда «сообщить владельцу»
Чтобы не повторять настройки почты в каждом скрипте, заведём одну команду, которой будут пользоваться все остальные.
sudo tee /usr/local/sbin/notify >/dev/null <<'EOF'
#!/bin/sh
# notify "тема" — текст письма берётся со стандартного ввода
TO=you@example.ru
{ printf 'Subject: [%s] %s\n\n' "$(hostname)" "$1"; cat; } | /usr/bin/msmtp "$TO"
EOF
sudo chmod 755 /usr/local/sbin/notify
Скрипт ставит в тему имя сервера — когда машин станет несколько, сразу будет видно, от какой письмо.
echo "Проверка команды notify" | sudo notify "тест"
Должно прийти письмо с темой [имя-сервера] тест.
Шаг 3. Здоровье дисков
Диски умеют сами следить за своим состоянием — это называется SMART. Программа smartd из пакета smartmontools регулярно опрашивает диски и пишет письмо, если что-то не так: растёт число повреждённых участков, диск перегревается, не прошёл самопроверку.
sudo apt install smartmontools bsd-mailx
Ставим smartmontools — служба smartd запускается сама — и bsd-mailx. Что тут происходит: smartd отправляет письма командой mail, а msmtp из первого шага даёт только sendmail. Пакет bsd-mailx добавляет mail, которая передаёт письмо в sendmail, то есть в msmtp. Без него smartd не сможет отправить ни одного письма.
sudo sed -i 's/^DEVICESCAN.*/DEVICESCAN -a -n standby,q -s (S\/..\/..\/.\/02|L\/..\/..\/6\/03) -W 4,45,55 -m you@example.ru -M test/' /etc/smartd.conf
sudo systemctl restart smartd
Что тут происходит, по частям строки:
DEVICESCAN -a— следить за всеми дисками по всем показателям;-n standby,q— не будить уснувшие диски ради проверки;-s (S/../.././02|L/../../6/03)— короткая самопроверка каждый день в 2 часа ночи, длинная — по субботам в 3;-W 4,45,55— сообщать о скачке температуры на 4 градуса, отмечать в журнале 45 °C, писать письмо при 55 °C;-m адрес— куда писать,-M test— один раз отправить тестовое письмо при запуске.
После перезапуска придёт тестовое письмо от smartd. Получили — уберите из строки -M test и перезапустите службу ещё раз, иначе тест будет приходить при каждом старте.
Шаг 4. Место на дисках
sudo tee /usr/local/sbin/check-disk-space >/dev/null <<'EOF'
#!/bin/sh
# Сообщить, если какой-то раздел заполнен больше чем на LIMIT процентов
LIMIT=90
FULL=$(df -h --output=pcent,target -x tmpfs -x devtmpfs -x overlay | awk -v l="$LIMIT" 'NR>1 && int($1)>l')
[ -n "$FULL" ] && echo "$FULL" | /usr/local/sbin/notify "заканчивается место"
exit 0
EOF
sudo chmod 755 /usr/local/sbin/check-disk-space
Скрипт проверяет все разделы, кроме временных и служебных, и пишет письмо, если какой-то заполнен больше чем на 90 %.
sudo tee /etc/systemd/system/check-disk-space.service >/dev/null <<'EOF'
[Unit]
Description=Проверка свободного места
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/check-disk-space
EOF
sudo tee /etc/systemd/system/check-disk-space.timer >/dev/null <<'EOF'
[Unit]
Description=Проверка свободного места каждый час
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now check-disk-space.timer
Служба и таймер, как в третьей части цикла: проверка раз в час.
Шаг 5. Любая упавшая служба
У systemd есть удобная настройка OnFailure: если служба завершилась с ошибкой, запустить другую. Сделаем одну службу-уведомитель и подключим её к важным службам.
sudo tee /etc/systemd/system/notify-failure@.service >/dev/null <<'EOF'
[Unit]
Description=Письмо о сбое %i
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'journalctl -u "%i" -n 30 --no-pager | /usr/local/sbin/notify "сбой: %i"'
EOF
sudo systemctl daemon-reload
Это шаблон: %i подставится именем упавшей службы, а в письмо попадут последние 30 строк её журнала — обычно там видна причина.
sudo systemctl edit restic-backup.service
Открываем дополнение к службе бэкапа из третьей части и вписываем:
[Unit]
OnFailure=notify-failure@%n.service
Теперь если ночной бэкап не выполнится, утром вас будет ждать письмо с причиной. Так же подключайте любые другие важные службы.
Шаг 6. Кто сообщит, если упадёт сам сервер
У всей этой схемы есть слепое пятно: если сервер выключился, сгорел блок питания или пропал интернет, он ничего не напишет. Есть два простых решения.
Первое — «всё хорошо» каждый день. Пусть бэкап после успешного выполнения присылает короткое письмо. Тогда тревожным сигналом станет не письмо, а его отсутствие: утро без привычной сводки — повод проверить сервер.
Второе — проверка снаружи. Вторая машина или внешний сервис мониторинга раз в несколько минут стучится в ваш сервер и пишет вам, если он не отвечает. Это надёжнее, но требует второй точки.
Если что-то пошло не так
- Письма не уходят, в журнале «authentication failed». Скорее всего, указан основной пароль, а нужен пароль приложения. Журнал отправки:
sudo journalctl -t msmtp -n 20. - «TLS handshake failed» или зависание. Перепутаны порт и способ шифрования: для порта 465 нужно
tls_starttls off, для порта 587 —tls_starttls on. - Письма уходят, но не приходят. Загляните в «Спам» и добавьте адрес сервера в контакты.
- smartd не видит диски. Посмотрите
sudo smartctl --scan: диски за некоторыми RAID-контроллерами и USB-переходниками требуют указать тип устройства вручную — подробности вman smartd.conf.
Вот и весь цикл. Сервер приведён в порядок, сервисы живут в контейнерах, данные сохраняются каждую ночь, а о проблемах вы узнаёте из почты, а не из того, что всё вдруг перестало работать. Осталось главное — раз в несколько месяцев проверять, что из бэкапа действительно можно восстановиться.
Это четвёртая, заключительная часть цикла «Домашний сервер без боли». Предыдущая — «Автоматический бэкап: restic и таймер systemd». Все части цикла — на странице цикла.