Безопасность домашнего сервера: личный опыт
У меня был момент прозрения. Сижу я ночью, проверяю почту — а там письмо от Hetzner. «Ваш сервер скомпрометирован». Я сначала подумал — да ну, бред. Зашёл по SSH, а там… майнер. Кто-то запустил Monero на моём VPS, и он жрал CPU на 100% уже сутки.
Я даже не заметил.
Вот тогда я сел и пересмотрел своё отношение к безопасности. Раньше думал: «домашний сервер, кому я нужен». Скажу сразу — это самое опасное заблуждение. Умные люди давно автоматизировали взлом, и твой сервер ищут не по имени, а по портам. Сканеры прочёсывают интернет 24/7. Если у тебя открыт SSH на стандартном порту — ты уже в зоне риска.
Первое, что я сделал — поменял порт SSH. 22-й порт атакуют постоянно. В логах fail2ban у меня были тысячи попыток входа в сутки. Просто перенёс на 2222 — и количество атак упало на 90%. Не панацея, но первый шаг очевидный.
Дальше — ключи вместо пароля. Парольная аутентификация — зло. Я сгенерировал ed25519-ключ, скопировал на сервер, и отключил `PasswordAuthentication no` в sshd_config. После этого даже если кто-то угадает пароль — не зайдёт. А ключ без файла-пароля (passphrase) не имеет смысла — я добавил и его.
Кстати про fail2ban. Это must have. Я настроил его не только для SSH, но и для nginx, и для WordPress (через лог wp-login). После того как поставил — количество брутфорс-атак в логах упало с тысяч до нуля. Ну, до бана этих тысяч. Конфиг простой:
[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 86400
Сутки бана. Три попытки. Жёстко, но работает.
Теперь про то, что я упустил в самом начале. Обновления. Долгое время у меня была схема «работает — не трогай». И это нормально, пока не выходит уязвимость в OpenSSL или в той же nginx. Теперь у меня стоит `unattended-upgrades` для критических патчей, и раз в неделю я захожу и вручную обновляю пакеты. Да, это скучно. Да, я тоже ленюсь. Но майнер на сервере — ещё более скучно.
Раз уж заговорили про веб — ставьте заглушку на неиспользуемые домены. Я на своём nginx настроил default server, который возвращает 444 (закрыть соединение без ответа) для всех запросов, которые не подходят ни под один server_name. Потому что сканеры тупо долбятся по IP, а ты даже не знаешь. А у тебя там может phpMyAdmin висеть с дефолтным паролем.
Да, кстати, удалите phpMyAdmin. Или хотя бы повесьте на него HTTP Basic Auth и ограничьте доступ по IP. Я свой удалил и пользуюсь командной строкой — удобнее, быстрее и без дыр.
Firewall. Я долго откладывал настройку, потому что «и так всё норм». Потом сел и настроил ufw. Разрешил только SSH, HTTP, HTTPS и WireGuard. И порт моего игрового сервера. Всё остальное — дроп. Раз — и список атак в fail2ban сократился ещё вдвое. Потому что если порт закрыт — в него даже не ломятся.
WireGuard — отдельная песня. Я сделал VPN-доступ к админским интерфейсам. Теперь phpMyAdmin (я его не удалил, а перенёс), Grafana, Portainer — всё доступно только через WireGuard. Снаружи эти порты даже не открыты. Хочешь зайти в админку — сначала подними VPN. Спокойно? Спокойно.
Ещё я перестал использовать root для повседневной работы. Создал отдельного пользователя `deploy`, дал ему sudo на конкретные команды. Root login через SSH вообще отключил в sshd_config — `PermitRootLogin no`. Если кто-то подберёт пароль от рута (а его нет, я его даже не знаю) — не зайдёт.
Логи. Я их не смотрел годами, пока не случился майнер. Теперь у меня всё стекается в Grafana через Loki — watching. Docker-логи, nginx, auth.log, syslog — всё в одной панели. Но хотя бы раз в неделю глазами пробегаться по `/var/log/auth.log` — святое. Там сразу видно, ломятся к тебе или нет.
И последнее — бекапы. Безопасность — это не только про взлом. Диск тоже может сдохнуть. Или ты сам что-то сломаешь обновлением. У меня бекапы на отдельный диск, ежедневно, с хранением за неделю. Восстановление проверял — работает.
Сейчас мой сервер стоит в интернете уже полгода. За это время было несколько попыток брутфорса (fail2ban отбил), один сканер нашёл старый тестовый поддомен (я его удалил), и ничего не сломалось. Я сплю спокойно не потому что думаю «кому я нужен», а потому что знаю — доступ к серверу есть только у меня, через ключ и VPN, а всё остальное закрыто.
Сделай хотя бы половину из этого — и будешь в порядке. Серьёзно, майнер на сервере — это не смешно.