Первые 15 минут на новом VPS: закрываем SSH до того, как его найдут боты

Только что поднятый VPS чист, как белый лист. Но это не мешает ему сразу попасть в поле зрения ботов.
Я поднял чистый Debian 12, ничего на нём не настраивал и просто оставил открытым журнал SSH на час. Сервер нигде не публиковался, домен к нему не привязывался, ссылку я никому не отправлял.
За первый час прилетело:
- 389 попыток подбора пароля;
- 92 попытки входа под root;
- 7 IP-адресов, с которых шёл перебор;
- 282 попытки от одного особенно упорного адреса;
- 1 успешный вход — мой.
В логах это выглядело примерно так:
05:12:20 sshd: Failed password for root from 45.8.119.168
05:23:05 sshd: Failed password for invalid user demo from 91.92.40.36
05:25:52 sshd: Failed password for invalid user ubuntu from 91.92.40.36
05:55:15 sshd: Failed password for invalid user claude from 91.92.40.36
06:01:25 sshd: Failed password for invalid user docker from 176.65.139.218
...
06:10:38 sshd: Accepted password for djops from 203.0.113.10
Боты перебирали ожидаемые логины: root, admin, user, ubuntu, deploy, oracle, postgres.
Рядом попадались более свежие цели: n8n, jenkins, docker, claude.
И им всё равно, кто вы и что у вас на сервере. Они не знают, что это будущий блог, staging для приложения или однодневный проект.
Они просто идут по диапазонам IP и проверяют, где SSH отвечает на пароль.
Особенно неприятная строка в этом логе — Accepted password for djops
И это мой вход и от тоже был по паролю.
То есть я пользовался тем же механизмом, который боты пытались подобрать.
Разница только в том, что мой пароль боты ЕЩЕ не угадали.
Как сделать так, чтобы подбирать было нечего расскажу пошагово.
От кого защищаемся
Чаще всего это массовые сканеры, ботнеты и автоматические переборщики. Они круглосуточно прочёсывают IPv4, ищут открытый SSH, проверяют стандартные логины, пробуют пароли из словарей и идут дальше.
Против такой автоматики не нужна паранойя. Достаточно перестать быть лёгкой добычей.
Нужно сделать так, чтобы сервер перестал быть лёгкой целью.
Минимальный набор:
- Работать не под root, а под обычным пользователем с sudo.
- Настроить вход по SSH-ключу.
- Отключить вход по паролю.
- Отключить вход под root по SSH.
- По желанию — поставить fail2ban, чтобы убрать шум из логов.
Шаг 1. Проверяем пользователя и sudo
Многие провайдеры до сих пор выдают VPS в формате: вот IP, вот пароль от root, удачи.
Работать так каждый день неудобно и небезопасно.
Root может всё. Ошибка в команде, кривой скрипт с форума, неудачный rm -rf — и система честно выполнит то, что вы попросили. Без вопросов.
Обычный пользователь с правом sudo добавляет паузу. Чтобы сделать что-то опасное, нужно явно написать sudo и подтвердить действие паролем. Иногда этой секунды хватает, чтобы заметить, что команда выглядит подозрительно.
Есть и вторая причина: root — самая очевидная цель.
В моём часовом эксперименте почти четверть попыток шла именно под root. Логин известен заранее, угадывать его не надо.
Если на VPS уже создан обычный пользователь с sudo, новый заводить не нужно. Например, в Serverum VPS можно использовать пользователя (масло масленное), который создаётся при выдаче сервера. Здесь важно не название пользователя, а две проверки:
whoamiУбедитесь, что вы не root.
Затем проверьте sudo:
sudo whoamiОжидаемый ответ:
rootЕсли сервер выдали только с root-доступом, создайте отдельного пользователя:
useradd -m -s /bin/bash djops
usermod -aG sudo djops
passwd djopsПосле этого откройте новую SSH-сессию уже под новым пользователем и проверьте:
sudo whoamiЕсли в ответ прилетел root, всё нормально.
Важное правило: не закрывайте текущую рабочую сессию, пока не проверили новый способ доступа.
Это страховочный трос. Он спасет от ситуации, когда вы защитили сервер настолько хорошо, что сами больше не можете войти.
Шаг 2. Меняем выданный пароль
Даже если через несколько минут мы отключим вход по паролю, пароль всё равно лучше заменить.
Почему: начальный пароль пришел по почте, попал в историю сообщений, мог сохраниться в менеджере задач, оказаться в переписке или просто слишком долго лежать не там. Это не значит, что он скомпрометирован. Это значит, что вы его не полностью контролируете.
Меняем:
passwdПридумайте нормальный длинный пароль. Не для того, чтобы жить с ним вечно, а чтобы закрыть временное окно до перехода на ключи.
Шаг 3. Генерируем SSH-ключ на своей машине
Все 389 попыток из эксперимента — был перебор пароля.
Пока вход по паролю разрешён, у бота, теоретически, есть шанс. Если у вас нормальный пароль, то он мал, но не нулевой.
Вход по SSH-ключу этот шанс убирает: подбирать нечего.
Ключевая пара состоит из двух частей:
- приватный ключ — остаётся у вас;
- публичный ключ — кладётся на сервер.
Пару нужно генерировать на своём компьютере, а не на VPS.
Если сделать ключ на сервере, приватный ключ окажется на машине, которую мы как раз защищаем. Потом его придётся тащить обратно к себе.
Приватный ключ не должен путешествовать!
На локальной машине выполните:
ssh-keygen -t ed25519 -C "djops@archpc"ed25519 — современный вариант для SSH-ключей: короткий, быстрый, достаточно стойкий для обычных серверных задач.
ssh-keygen спросит, куда сохранить ключ. Обычно можно оставить путь по умолчанию:
~/.ssh/id_ed25519Затем утилита предложит passphrase. Не пропускайте её.
Passphrase шифрует приватный ключ на диске. Если ноутбук потеряется или кто-то получит доступ к файлу ключа, сам по себе файл не даст ему войти на сервер. Вводить passphrase при каждом подключении обычно не придётся: для этого есть ssh-agent.
На выходе появятся два файла:
id_ed25519 # приватный ключ, никому не отдаём
id_ed25519.pub # публичный ключ, его кладём на серверШаг 4. Добавляем SSH-ключ для входа на сервер
Есть три способа.
1. Через панель при создании сервера
Если провайдер позволяет добавить SSH-ключ при создании VPS, используйте этот вариант. Сервер сразу создастся с настроенным входом по ключу для нужного пользователя, и вам не придётся сначала заходить по паролю, чтобы вручную добавлять ключ.
Для Serverum это удобный сценарий для новых серверов: создаёте VPS, добавляете публичный ключ и дальше заходите без пароля. Нужно только заранее сгенерировать ключ на своей машине.
2. Через ssh-copy-id
Если сервер уже создан и вход паролю пока разрешён:
ssh-copy-id djops@203.0.113.10Утилита зайдёт по паролю, создаст каталог ~/.ssh, выставит права и добавит публичный ключ в authorized_keys.
После этого пробуем войти:
ssh djops@203.0.113.10Если сервер пустил без пароля пользователя, ключ работает.
3. Руками
Если ssh-copy-id недоступен, можно сделать всё вручную.
На сервере под нужным пользователем:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keysВставьте содержимое публичного ключа из файла id_ed25519.pub, сохраните и выставьте права:
chmod 600 ~/.ssh/authorized_keysПроверьте владельца файлов:
ls -la ~/.sshКаталог .ssh и файл authorized_keys должны принадлежать тому пользователю, под которым вы заходите.
Типовые права:
drwx------ .ssh
-rw------- authorized_keys
Если SSH не принимает ключ, чаще всего проблема не в самом ключе, а в том, куда и как его добавили. Проверьте, что ключ лежит у нужного пользователя, файл называется authorized_keys, права на .ssh и authorized_keys не слишком широкие, а сами файлы принадлежат тому пользователю, под которым вы заходите.
Шаг 5. Проверяем вход по ключу во втором терминале
Перед тем как отключать парольный вход, обязательно проверьте, что вход по ключу уже работает.
Текущую SSH-сессию не закрывайте. Откройте второй терминал и попробуйте подключиться ещё раз:
ssh djops@203.0.113.10Если сервер пустил без запроса пароля пользователя — ключ настроен правильно.
Если подключиться не получилось, на этом этапе останавливаемся. Сначала разбираемся с ключами, правами и пользователем. Пароль пока не отключаем, иначе можно закрыть себе единственный рабочий способ входа.
Старую сессию держим открытой до тех пор, пока новый вход по ключу не проверен.
Шаг 6. Отключаем пароль и root-логин
Теперь ключ работает. Можно выключать то, что боты пытаются подобрать.
Откройте конфиг SSH:
sudo nano /etc/ssh/sshd_configНайдите или добавьте параметры:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yesЧто это даёт:
- PasswordAuthentication no — запрещает вход по паролю;
- PermitRootLogin no — запрещает SSH-вход под root;
- PubkeyAuthentication yes — явно разрешает вход по публичному ключу.
Перед применением проверьте синтаксис:
sudo sshd -tЕсли команда ничего не вывела, конфиг валиден.
Теперь примените изменения:
sudo systemctl reload sshНа некоторых системах сервис может называться sshd. Тогда команда будет такой:
sudo systemctl reload sshdШаг 7. Проверяем, что пароль больше не работает
Старую сессию всё ещё не закрываем.
В новом терминале сначала проверяем обычный вход по ключу
ssh djops@203.0.113.10Пускает? Отлично.
Теперь специально заставим SSH попробовать пароль и не использовать ключ:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password djops@203.0.113.10Ожидаемый результат:
Permission denied (publickey).Это значит, что сервер больше не принимает пароль. Даже если бот угадает логин и будет стучаться всю ночь, ему нечего подбирать.
Root тоже проверять можно:
ssh root@203.0.113.10Ожидаемый результат — отказ.
После этих проверок можно закрывать старую сессию.
А если всё сломалось?
Такое тоже может быть.
Не потому что вы плохой админ, а потому что SSH не прощает мелких ошибок: не тот пользователь, не тот ключ, лишний пробел, права 777 на .ssh, опечатка в конфиге.
Если вы ещё не закрыли старую сессию — хорошо. Откатите изменения и проверьте всё заново.
Если закрыли и теперь не можете войти ни по ключу, ни по паролю, нужен доступ в обход SSH.
Обычно это веб-консоль в панели провайдера: аналог монитора и клавиатуры, подключённых к серверу. Через неё можно попасть в систему и поправить конфиг.
В Serverum такая консоль доступна из карточки VPS/VDS. Это страховка на случай, если SSH сломан, сеть настроена криво или firewall оказался слишком усердным.
Шаг 8. fail2ban — по желанию
После отключения пароля fail2ban уже не является главным защитным механизмом для SSH.
Это важно понимать.
Если вход только по ключу, бот не может подобрать пароль. Он может продолжать стучаться, но практического шанса войти через пароль у него нет.
У fail2ban остаются две полезные задачи:
- Уменьшить шум в логах.
- Снизить паразитную нагрузку от настойчивых сканеров.
Установка:
sudo apt update
sudo apt install fail2banНе редактируйте jail.conf: его может перезаписать обновление пакета. Создайте свой файл:
sudo nano /etc/fail2ban/jail.localМинимальная настройка для SSH:
[sshd]
enabled = true
backend = systemd
maxretry = 3
findtime = 10m
bantime = 1hЗдесь:
- maxretry = 3 — бан после трёх неудачных попыток;
- findtime = 10m — считаем попытки за последние 10 минут;
- bantime = 1h — баним на час;
- backend = systemd — читаем события из systemd-журнала.
Перезапускаем:
sudo systemctl restart fail2banПроверяем статус:
sudo fail2ban-client status sshdПример результата:
Status for the jail: sshd
|- Filter
| |- Currently failed: 6
| |- Total failed: 273
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 8
|- Total banned: 8
`- Banned IP list: 176.65.139.218 91.92.40.36Когда fail2ban банит адрес, снаружи это обычно выглядит как таймаут. Сервер не спорит с ботом, не объясняет ему причину отказа, не пишет вежливое письмо. Он просто перестаёт отвечать.
В логах вместо сотен строк перебора появляется что-то вроде:
fail2ban.actions [sshd] Ban 91.92.40.36Не усложняем на старте
В гайдах по защите VPS часто советуют сразу сменить SSH-порт с 22 на что-нибудь вроде 2222.
Это может уменьшить шум от самых простых ботов.
Но это не полноценная защита.
Сканеры умеют искать SSH на нестандартных портах, а вам добавляется лишняя настройка, которую нужно помнить, документировать и не сломать.
То же самое с port knocking и похожими трюками. В некоторых инфраструктурах они уместны, но для базовой защиты нового VPS это лишняя сложность.
Наша модель угроз проще: массовые боты, которые ищут лёгкие цели.
Против них лучше работает база:
- вход по ключу;
- запрет пароля;
- запрет root-логина;
- аккуратная проверка доступа;
- обновления системы;
- резервная консоль на случай ошибки.
Мини-чеклист, что сделать в первые 15 минут на VPS:
# 1. Проверить пользователя
whoami
sudo whoami
# 2. Сменить выданный пароль
passwd
# 3. На своей машине создать SSH-ключ
ssh-keygen -t ed25519 -C "djops@laptop"
# 4. Скопировать ключ на сервер
ssh-copy-id djops@203.0.113.10
# 5. Проверить вход по ключу во втором терминале
ssh djops@203.0.113.10
# 6. Настроить SSH
sudo nano /etc/ssh/sshd_config
# В sshd_config:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
# Проверить и применить:
sudo sshd -t
sudo systemctl reload ssh
# Проверить, что пароль отключён:
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password djops@203.0.113.10
# Ожидаемый ответ:
Permission denied (publickey).
# 7. Опционально:
sudo apt update
sudo apt install fail2ban
# В /etc/fail2ban/jail.local
[sshd]
enabled = true
backend = systemd
maxretry = 3
findtime = 10m
bantime = 1h
sudo systemctl restart fail2ban
sudo fail2ban-client status sshdВывод
Новый VPS быстро попадает в поле зрения сканеров. Даже если IP нигде не публиковали, домен не привязывали и на сервере ещё ничего нет.
Поэтому первые настройки лучше сделать сразу: добавить SSH-ключ, закрыть вход по паролю, запретить root и проверить доступ.
Попытки в логах после этого никуда не исчезнут. Но подбирать уже нечего: вход по паролю не работает, root закрыт, вход только по ключу.
В Serverum такой сценарий занимает несколько минут: подняли VPS, добавили ключ, проверили вход — и дальше спокойно настраиваете проект.