VPS-сервер не защищён по умолчанию: базовый уровень безопасности
Безопасность нового VPS: настройка SSH, firewall, Fail2Ban и обновлений сразу после запуска сервера.
Новый VPS привлекает ботов быстрее, чем кажется: безопасность сервера на старте низка. Провайдер берёт на себя изоляцию на уровне гипервизора и сетевую связность. Всё, что выше ОС, остаётся зоной ответственности клиента.
Что провайдер защищает, а что – нет
Хостинг-провайдер отвечает за физическую инфраструктуру, гипервизор и сетевую изоляцию между машинами. Операционная система, открытые порты, учётные записи и конфигурации сервисов остаются зоной ответственности администратора.
После выдачи машины проверьте стартовые настройки доступа: на части образов всё ещё может быть открыт root-доступ по паролю, SSH часто принимает соединения на стандартном порту 22, а пакеты могут требовать обновления. У многих современных провайдеров вход по паролю или под root уже отключён по умолчанию, но это нельзя считать универсальным правилом. Автоматические сканеры добираются до нового сервера в течение нескольких минут после получения публичного IP.
Baseline: минимум для нового VPS
Настройка VPS начинается не с деплоя приложения. Базовый харденинг нового сервера занимает 15–30 минут и снижает риск типовых атак: брутфорса SSH, сканирования открытых портов и эксплуатации устаревших пакетов.
Создайте непривилегированного пользователя с sudo и настройте аутентификацию по SSH-ключу. Root-логин по паролю отключите в /etc/ssh/sshd_config директивой PermitRootLogin no. Смена стандартного порта SSH снижает шум от автоматических сканеров.
Firewall и fail2ban
Настройте ufw или iptables: разрешите только нужные порты, остальное заблокируйте. Утилита fail2ban автоматически банит IP после серии неудачных попыток входа и хорошо дополняет правила firewall.
Автообновления и мониторинг логов
Включите unattended-upgrades для автоматической установки обновлений безопасности. Периодический просмотр /var/log/auth.log и вывода journalctl помогает заметить подозрительную активность до того, как она перерастёт в инцидент.
Чек-лист baseline-настроек
• Создан непривилегированный пользователь с sudo
• Root-логин по паролю отключён
• SSH-аутентификация переведена на ключи
• При необходимости изменён стандартный порт SSH
• ufw или iptables настроен, лишние порты закрыты
• fail2ban установлен и активен
• unattended-upgrades включен
Baseline не заменяет полноценный аудит конфигурации, но снижает риск типовых атак. Примените чек-лист сразу после получения доступа к серверу. В блоге Aeza выходят материалы по серверной безопасности, следите за новыми разборами.
Fail2Ban на VPS: как проверить, что блокировки работают
Fail2Ban запущен, jail sshd есть в списке, а попытки входа всё равно появляются в журнале. С разных адресов они могут приходить и при работающей защите, так как Fail2Ban считает ошибки для каждого адреса отдельно. Сам по себе статус службы не значит, что она блокирует подключения. Программа должна получить запись о неудачном входе, распознать её и передать адрес в сетевой экран. Проверять эту цепочку будем на VPS с Ubuntu 24.04. Установку и базовую настройку мы показывали в первой части, а здесь ищем звено, на котором защита перестала работать.
Перед проверкой оставьте открытым рабочий сеанс SSH. Если у провайдера есть консоль в панели, убедитесь, что вы можете через неё войти. Оба пути понадобятся, если правка настроек или тестовый бан закроют доступ.
Журнал SSH
Начните с самого сервера. На Ubuntu журнал службы SSH можно посмотреть так:
sudo journalctl -u ssh.service --since "30 minutes ago" --no-pager
Ищите строки об отказах входа, например с Failed password или Invalid user, и адрес, с которого пришло подключение. Если таких строк за выбранное время нет, работу Fail2Ban по журналу пока не проверить: попыток просто не было. Можно повторить проверку после обычной неудачной попытки входа с другого устройства. Не включайте вход по паролю специально ради теста, если он уже отключён.
Запишите адрес клиента из журнала. Он понадобится позже: Fail2Ban считает ошибки и блокирует адрес, который видит SSH. Если вы подключаетесь через промежуточный сервер или общий офисный шлюз, в журнале может оказаться адрес этого узла.
Источник событий Fail2Ban
Теперь проверьте jail sshd и источник событий, который он читает:
sudo fail2ban-client status sshd
В разделе Filter ищите список файлов или Journal matches. Первый вариант означает чтение файлов журнала, второй указывает на systemd journal. Статус без ошибок ещё не подтверждает, что выбранный источник содержит нужные SSH-события.
Что делать, если jail читает не тот журнал?
Если jail читает файлы, узнайте их имена. Для чтения journal посмотрите условие отбора записей:
sudo fail2ban-client get sshd logpath
sudo fail2ban-client get sshd journalmatch
Сравните результат с тем, где вы увидели отказ входа. Если SSH пишет в journal, а jail следит за отсутствующим или неиспользуемым файлом, в уже существующей секции [sshd] файла /etc/fail2ban/jail.local можно указать:
[sshd]
backend = systemd
Строку backend добавляют в существующую секцию, вторую секцию [sshd] создавать не нужно. После правки проверьте конфигурацию и перезапустите службу:
sudo fail2ban-client -t
sudo systemctl restart fail2ban
Если служба сообщает, что не может использовать backend systemd, проверьте наличие пакета python3-systemd. Для чтения journal Fail2Ban нужна библиотека Python для systemd, и без неё одной правки конфигурации недостаточно.
Проверка фильтра
Даже при правильном источнике событий jail может не засчитывать конкретные строки журнала. Для штатного фильтра SSH проверьте совпадения:
sudo fail2ban-regex systemd-journal sshd
Команда читает записи journal и показывает, сколько строк подошло под фильтр sshd. Для сервера, где jail читает файл /var/log/auth.log, укажите вместо systemd-journal этот путь. Проверять нужно тот источник, которым пользуется работающий jail.
Почему фильтр не находит ошибки входа?
Если совпадений нет, сначала убедитесь, что в выбранном источнике есть свежие отказы SSH. Затем сравните сами строки отказов с тем, что ожидает фильтр: после обновления OpenSSH формат записей может измениться, и тогда понадобится более свежий фильтр. Повышать maxretry здесь бессмысленно. Положительное число совпадений тоже требует внимания: команда может найти старые записи. Оно подтверждает работу фильтра на прочитанном журнале, но само по себе ничего не говорит о новых попытках и блокировке подключений.
Пороги и исключения
Когда фильтр распознаёт ошибки, проверьте пороги и исключения, которые действуют сейчас
sudo fail2ban-client get sshd findtime
sudo fail2ban-client get sshd maxretry
sudo fail2ban-client get sshd ignoreip
Fail2Ban блокирует адрес, если за интервал findtime накопилось maxretry подходящих событий. Пять ошибок от пяти разных адресов не складываются в один бан. Если нужный адрес указан в ignoreip, jail его пропустит. Сверяйте исключения с адресом в журнале SSH, особенно после смены сети или провайдера.
Адрес для ignoreip смотрите в журнале SSH либо узнавайте на устройстве, с которого вы входите. Если отправить запрос к сервису определения IP с самого VPS, он покажет внешний адрес сервера. При часто меняющемся адресе постоянное исключение для администратора может оказаться бесполезным. Тогда главным запасным путём остаётся консоль провайдера.
Текущие счётчики и заблокированные адреса снова видны в статусе jail:
sudo fail2ban-client status sshd
Currently failed показывает, сколько адресов сейчас числится с неудачными попытками: они ещё не набрали порог для бана, а их ошибки не вышли за пределы findtime. Общее число учтённых ошибок видно в строке Total failed. После бана или окончания этого интервала значение может стать нулевым. Поэтому один ноль в статусе не значит, что журнал не читается. Сопоставляйте счётчик со временем ошибок и адресами в журнале
Проверка блокировки
Бан в статусе Fail2Ban показывает только решение программы заблокировать адрес. Применил ли его сетевой экран, видно по отказу нового SSH-подключения. Сначала узнайте, какое действие назначено jail:
sudo fail2ban-client get sshd actions
Действие должно соответствовать сетевому экрану, который работает на VPS. По умолчанию, как правило, указано iptables-multiport. В этом случае Fail2Ban держит свои правила в отдельной цепочке f2b-sshd:
sudo iptables -L f2b-sshd -n
Если в списке стоит действие для nftables, его правила можно посмотреть так:
sudo nft list ruleset
Для других действий проверяйте соответствующий сетевой экран. При этом правила в системе не всегда удобно оценивать на глаз, поэтому практичнее проверить новое соединение с отдельного клиента.
Как проверить бан с другого устройства?
Для контрольной проверки нужен клиент из другой сети, например с мобильным интернетом. Второй ноутбук в том же Wi-Fi обычно выходит в интернет с того же публичного адреса, что и основной. До бана убедитесь, что тестовый клиент входит по SSH, а его IP отсутствует в ignoreip.
Оставьте основной доступ к серверу и консоль провайдера. Узнайте внешний IP на тестовом устройстве, а затем на сервере временно заблокируйте именно его. Ниже указан адрес из диапазона для примеров. Перед выполнением замените его на адрес тестового клиента.
sudo fail2ban-client set sshd banip 198.51.100.25
Проверьте, что адрес появился в статусе sshd, и попробуйте открыть с тестового устройства новое SSH-соединение. Уже открытый сеанс может сохраниться. Если вы заблокировали IPv4-адрес, убедитесь, что клиент не подключается к серверу по IPv6. Сразу после этого снимите бан:
sudo fail2ban-client set sshd unbanip 198.51.100.25
Ручной бан проверяет сетевой экран и путь к SSH, но обходит журнал, фильтр и порог. Если он сработал, а автоматических банов всё ещё нет, возвращайтесь к предыдущим шагам. Если статус показывает бан, но новое соединение с того же адреса проходит, проверьте выбранное действие, адрес клиента и порт SSH. При изменённом порте действие может блокировать только стандартный порт 22.
После проверки
Исправляйте первый сбой в цепочке: сначала запись в журнале SSH, затем источник событий и фильтр, после них пороги и действие блокировки. Так легче понять, почему защиты нет, и не менять сразу несколько параметров наугад. Вход по SSH-ключу оставьте в любом случае: Fail2Ban ограничивает повторяющиеся попытки с адреса, но не спасает от слабого пароля или украденного ключа.
Настройка VPS Ubuntu и Debian: порты, пакеты, окружение
Настройка VPS Ubuntu и Debian проверяется простой перезагрузкой. Сайт открылся на новом сервере, а после перезагрузки перестал отвечать, ведь веб-сервер не был добавлен в автозапуск. Проверка после каждого шага настройки помогает обнаружить такую ошибку до того, как сервер понадобится в работе.
Статья рассчитана на новый VPS с Ubuntu 24.04 LTS или Debian 13. На нём будет работать веб-сервер Nginx. Нужен чистый образ без панели управления, Docker и своих сетевых правил.
Какие пакеты установить в первую очередь на Ubuntu или Debian VPS?
Для первоначальной настройки хватит SSH-сервера, sudo для работы администратора, ca-certificates для проверки сертификатов и curl для проверки веб-сервиса. Сетевой экран UFW пригодится, если правила доступа ещё не настроены другим инструментом. Состав образа у провайдеров различается, поэтому часть этих пакетов может уже стоять.
Как выбрать образ под свою задачу
До заказа VPS стоит проверить в документации приложения, какие выпуски ОС и архитектуры оно поддерживает. Готовые программы для amd64 и arm64 различаются, поэтому нужен вариант под процессор вашего сервера.
Ubuntu 24.04 LTS получает стандартные обновления безопасности до мая 2029 года. Условия для отдельных пакетов зависят от раздела репозитория. У Debian 13 полная поддержка заявлена до августа 2028 года. Затем часть пакетов и архитектур продолжит получать исправления безопасности до июня 2030 года. Сроки опубликованы на страницах Ubuntu и Debian. В апреле 2026 года вышла Ubuntu 26.04 LTS со стандартной поддержкой до мая 2031, и если собираетесь выбирать её, для нового сервера стоит проверить, поддерживает ли её ваше приложение. Пример ниже собран на 24.04, потому что под неё чаще готовы сторонние репозитории.
Как установить Ubuntu на VPS, решает панель провайдера, так как новый сервер создаётся из готового образа. Переустановка может удалить данные работающего сервера, поэтому мы берём пустой VPS. После первого входа две команды покажут ОС и архитектуру:
cat /etc/os-release
dpkg --print-architecture
Название образа, версия ОС, архитектура и дата создания пригодятся при восстановлении.
Доступ по SSH и права администратора
Настройка VPS сервера на Ubuntu начинается с доступа: без рабочего SSH остальные шаги проверить нечем. SSH даёт доступ к командной строке сервера. Имя пользователя и адрес выдаёт провайдер. В примерах ниже USER и SERVER_IP нужно заменить своими значениями. Команда для подключения выполняется на вашем компьютере, а остальные команды – на VPS, если не указано иное:
ssh USER@SERVER_IP
Если SSH использует нестандартный порт, к команде нужен параметр -p с его номером. При первом входе клиент покажет отпечаток ключа сервера. Его нужно сверить через панель провайдера или аварийную консоль. Если отпечатка в панели нет, консольная команда ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub покажет отпечаток ключа Ed25519. В клиенте для сравнения должен быть выбран тот же тип ключа.
Для установки пакетов обычному пользователю нужны права администратора. Команда sudo -l покажет разрешённые действия. На новом VPS у администратора обычно есть разрешение ALL на запуск любых команд. Если провайдер выдал только root, отдельного администратора можно создать с помощью этих команд:
apt update
apt install sudo
adduser admin
usermod -aG sudo admin
Если SSH-ключей ещё нет, создайте пару на своём компьютере: ssh-keygen -t ed25519. Закрытый ключ остаётся у вас. Открытый ключ из файла с расширением .pub нужно добавить в ~/.ssh/authorized_keys выбранного пользователя на VPS. Знак ~ означает его домашний каталог. При доступном входе по паролю утилита ssh-copy-id USER@SERVER_IP перенесёт ключ с компьютера автоматически. Если её нет, ключ можно добавить вручную через консоль. У каталога ~/.ssh должны быть права 700, у файла – 600, владельцем должен быть выбранный пользователь.
Для проверки входа по ключу откройте на компьютере новый терминал:
ssh -S none -o PreferredAuthentications=publickey USER@SERVER_IP
Эта команда создаёт отдельное соединение и проверяет именно ключ. Если при входе спросят парольную фразу, это фраза от самого ключа, а не пароль пользователя на сервере. После входа sudo -l должен показать прежние права. Старый сеанс пока оставьте открытым, а аварийная консоль поможет исправить ошибку, если SSH станет недоступен.
Откуда система получает пакеты
APT устанавливает программы из репозиториев – источников пакетов для выбранной ОС. Их адреса обычно уже есть в образе. Файл с настройками в Ubuntu 24.04 можно прочитать так:
cat /etc/apt/sources.list.d/ubuntu.sources
В Debian 13 часто используется файл debian.sources:
cat /etc/apt/sources.list.d/debian.sources
Если файла нет, команда ls /etc/apt/sources.list.d/ покажет другие имена. Образ провайдера также может хранить источники в старом формате /etc/apt/sources.list.
В записях Ubuntu 24.04 ожидается кодовое имя noble, у Debian 13 – trixie. Суффикс -security обозначает обновления безопасности. Замена кодового имени подключит пакеты другого релиза и может нарушить работу системы при обновлении.
После проверки источников обновление выполняется одинаково в обеих системах:
sudo apt update
sudo apt upgrade
Первая обновляет сведения о пакетах, вторая устанавливает доступные обновления. После успешного apt update команда apt-cache policy покажет источники и их приоритеты. Если APT сообщает об ошибке подписи или недоступном источнике, сначала нужно устранить её. Проверку подписей отключать нельзя, без неё APT не проверит подлинность пакетов.
Для примера хватит штатных репозиториев. Адрес стороннего источника и его ключ берите только из документации того, кто его выпускает, и только в разделе для вашей ОС. PPA собирают под конкретный выпуск Ubuntu: на Debian такие пакеты могут не встать или потянуть за собой чужие зависимости, хотя APT в обеих системах одинаковый.
Какие программы нужны для начала
Для нашей страницы не нужны ни графическая оболочка, ни база данных. Перед установкой Nginx добавим три вспомогательных пакета:
sudo apt install ca-certificates curl ufw
dpkg-query -W ca-certificates curl ufw
Пакет ca-certificates содержит доверенные корневые сертификаты, они нужны программам для проверки HTTPS-соединений. curl поможет отправить запрос к сайту из терминала. UFW управляет сетевыми правилами, его настройкой займёмся до установки Nginx, поскольку пакет веб-сервера может сразу запустить службу.
Вторая команда выводит версии пакетов. Её результат пригодится для сравнения после обновления.
Утилиты вроде htop для просмотра процессов можно добавить позже. Здесь нужна команда ss, а если её нет, поможет sudo apt install iproute2.
Какие порты открыть
Чтобы сервис был доступен извне, программа должна принимать соединения на нужном порту, а сетевой экран – пропускать их. Разрешение в UFW само по себе ничего не запускает. Команда sudo ss -lntp показывает программы, которые ждут TCP-соединений, и адреса, на которых они доступны.
Адрес 127.0.0.1 означает доступ только внутри VPS, 0.0.0.0 – все локальные IPv4-адреса, [::] – все локальные IPv6-адреса. У SSH нужно проверить номер порта. Ниже используется стандартный 22, если у вас другой, замените его до выполнения команд.
Как открыть порт и не выставить лишние сервисы наружу?
Понять, как открыть порт на VPS сервере Ubuntu, помогает разделение на два слоя: программа должна принимать соединения, а сетевой экран – пропускать их. Поэтому в экране оставляют разрешения только для используемых портов, а остальные входящие запрещают по умолчанию. Исключение – отдельный сетевой экран провайдера, там доступ нужно разрешить ещё раз.
Перед включением правил разрешите текущий порт SSH и подготовьте аварийную консоль. В примере UFW будет единственным инструментом управления правилами внутри VPS. На сервер с уже настроенными nftables, Docker или панелью управления этот набор команд без проверки переносить нельзя. Порядок для чистой машины:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw enable
sudo ufw status verbose
Порт 80 предназначен для тестовой страницы по HTTP. Статус UFW должен быть active, а в списке разрешений – порты SSH и HTTP. При включённом IPv6 нужны и соответствующие правила с пометкой v6. Настройка VPS Debian на этом шаге не отличается: UFW ставится из тех же репозиториев, и команды совпадают. Подробнее о правилах – в руководстве UFW.
Теперь повторите проверочный вход с параметром -S none. Старый сеанс продолжит работать, даже если правило закрыло порт, поэтому проверять нужно новым подключением. Сайт проверим после запуска Nginx.
Время, язык и файлы приложения
Если часы сервера спешат или отстают, программы могут отвергать действующие сертификаты. При разных часовых поясах на серверах труднее сопоставлять события в журналах. Время и синхронизацию покажет timedatectl status, имя машины – hostnamectl status.
Единый часовой пояс UTC задаётся командой sudo timedatectl set-timezone UTC. Она меняет часовой пояс, не настраивая синхронизацию. Если синхронизации нет, нужно проверить службу времени образа: например, systemd-timesyncd или chrony.
Локаль задаёт язык сообщений, формат дат и чисел. Команда locale покажет её настройки, locale -a – доступные варианты. Рабочую C.UTF-8 можно оставить.
Команда export меняет окружение только текущей оболочки, а системная служба под управлением systemd стартует со своим набором переменных. Задают его директивами Environment и EnvironmentFile в юните службы. Пароли и токены в командную строку не вписывают, так как строка запуска видна в выводе ps любому пользователю системы и оседает в истории оболочки. Секреты выносят в отдельный файл, который читает приложение или сам юнит через EnvironmentFile, с правами 600 и владельцем – учётной записью приложения.
Какие шаги настройки отличаются в Ubuntu и Debian?
1. Источники пакетов: у релизов разные кодовые имена и адреса репозиториев; чужие записи APT переносить нельзя.
2. Версии программ: нужный пакет или способ его настройки может отличаться, поэтому инструкция должна соответствовать выбранному выпуску.
3. Состав образа: начальная учётная запись, наличие sudo, служба времени и сетевые настройки зависят также от провайдера.
Запуск Nginx и проверка перезагрузки
Пакет Nginx содержит готовую службу. Системный менеджер systemd запустит её сейчас и при следующей загрузке VPS:
sudo apt install nginx
dpkg-query -W nginx
sudo nginx -t
sudo systemctl enable --now nginx
Команда nginx -t проверяет конфигурацию. При ошибке запускать следующие команды рано: в сообщении обычно указаны файл и строка, требующие внимания. Ключ --now запускает службу сразу, enable включает её автозапуск.
В стандартной конфигурации пакета файлы сайта лежат в /var/www/html. Этот путь указан в параметре root файла /etc/nginx/sites-enabled/default. Перед созданием страницы его стоит сверить. При другом каталоге сайта путь в командах ниже нужно заменить. Мы добавим отдельный файл с коротким текстом:
printf 'vps-ok\n' | sudo tee /var/www/html/health.txt
sudo chown root:root /var/www/html/health.txt
sudo chmod 644 /var/www/html/health.txt
curl --fail --show-error http://127.0.0.1/health.txt
для статической страницы, рабочим процессам Nginx не требуется право менять её. Ожидаемый ответ на запрос – vps-ok.
Теперь можно перезапустить Nginx и посмотреть, вернулся ли он к работе:
sudo systemctl restart nginx
systemctl status nginx --no-pager
sudo journalctl -u nginx -n 30 --no-pager
Статус active (running) подтверждает, что служба работает. Журнал помогает найти ошибки запуска. Ошибки обработки запросов ищите в /var/log/nginx/error.log. После перезапуска нужен тот же запрос curl. Затем команда sudo reboot перезагрузит VPS и разорвёт SSH-сеанс. После загрузки должны снова работать вход по SSH и запрос к странице, ожидаемый статус Nginx – active (running).
Обновления и короткая проверка сайта
Если локальный запрос вернул vps-ok, Nginx отдаёт файл. Проверка с вашего компьютера покажет, доступен ли он через интернет. В команде нужен внешний IPv4-адрес сервера:
curl --fail --show-error --max-time 10 http://SERVER_IP/health.txt
Ожидается тот же текст vps-ok. Если снаружи ответа нет, стоит проверить адрес, порт в ss, правила UFW и сетевой экран провайдера, если он есть. Для доступа по IPv6 нужна отдельная проверка, так как запрос по IPv4 его не проверяет.
Эта тестовая страница работает по HTTP без шифрования. Перед публикацией сайта с авторизацией или личными данными нужны домен, сертификат и настройка HTTPS. После этого нужен доступ к порту 443 и запрос по имени сайта с проверкой сертификата.
Обновления лучше назначать на время, когда допустим короткий перезапуск. До обновления сохраняйте /etc/nginx и файлы сайта вне VPS. В копию стоит включить настройки UFW, список репозиториев и версии из dpkg-query -W. Секретные файлы в такой копии тоже требуют защиты. Базу данных, если она есть, копируют её собственными средствами резервного копирования.
После обновления повторяется уже знакомая проверка: nginx -t, состояние службы, новое соединение по SSH и запрос к странице с компьютера. Время запуска автоматических обновлений покажет systemctl list-timers --all. Настройки установленного unattended-upgrades находятся в /etc/apt/apt.conf.d/. История операций APT хранится в /var/log/apt/history.log. Пришедшие обновления ядра могут потребовать перезагрузки, это стоит учитывать на сервере с работающими приложениями.
В инструкции восстановления стоит указать версию образа, источники пакетов и расположение копий конфигурации. Рядом запишите, как подключиться к серверу после восстановления: пользователь, адрес, порт и место хранения ключа. Сам закрытый ключ должен оставаться в защищённом хранилище.
Пробное восстановление на отдельном VPS покажет, хватает ли сохранённых файлов и записей. После перезагрузки должны работать SSH и страница сайта, а правила сетевого экрана – совпадать с исходными. Успешный результат подтвердит, что настройку можно повторить.
Хорошая настройка VPS Ubuntu – та, которую можно повторить на чистом образе и проверить тем же smoke test после обновления. Если после переустановки из того же образа сервер отвечает на SSH, тестовая страница отдаёт условный vps-ok, а правила сетевого экрана совпадают с записанными, окружение воспроизводимо. Всё, что нельзя повторить по своей же инструкции, при следующем сбое придётся собирать заново и по памяти.
Как разблокировать LUKS-корень Альт Linux по SSH
Не так давно наткнулся на статью Red Hat про разблокировку LUKS-шифрования по SSH. Суть там простая: сервер с зашифрованным корнем перезагружается, замирает в initramfs и ждёт парольную фразу на консоли, за которой никто не сидит. Решение у редхатовцев выглядит довольно простым: поставить пакет dracut-sshd, включить модуль NetworkManager в initramfs, дописать параметры ядра. Несколько команд, и застрявшая машина открывается по SSH с вашего дивана.
И стало мне интересно: а как та же задача решается, если у меня на серваках крутится не RHEL, а Альт? Копировать редхатовский рецепт вслепую смысла нет: у Альта собственная система сборки initramfs и свои механизмы ранней загрузки. Тем любопытнее посмотреть, как всё устроено здесь.
TL;DR. Сделать можно. Проверил это на живой виртуалке. Рецепт в итоге вышел на удивление прямолинейный, но с двумя-тремя особенностями, о которых лучше узнать из статьи.
Постановка задачи, или зачем шифровать то, что стоит в шкафу
Сначала два слова о проблеме, чтобы не тащить за собой тех, кто уже в теме. LUKS — это формат шифрования блочных устройств в Linux: корневая файловая система лежит внутри зашифрованного контейнера, и пока контейнер не открыт, ранней загрузке нечего монтировать. Разумная практика для сервера, который стоит где-нибудь в чужом дата-центре: вынули диски — получили криптографический мусор вместо базы клиентов.
Обратная сторона фичи: при каждой перезагрузке кто-то обязан вручную ввести фразу. Клавиатура, монитор, поездка в дата-центр (или BMC-консоль, если повезло с железом). Сервер перезагрузился ночью после обновления, и всё: он ждёт вас. Физически.
Идея разблокировки по сети существует столько же, сколько удалённые серверы: положить в initramfs сетевой стек и маленький SSH-сервер, подключиться к машине, пока она стоит на паузе, и вручить ей парольную фразу издалека. Red Hat делает это средствами dracut, своего генератора initramfs, и честно хвастается, что весь рецепт — пакет, строчка конфига и пара параметров ядра (на RHEL пакет тянется из EPEL, на Fedora он в основных репозиториях).
А теперь посмотрим, что для этого есть у альтоводов.
Альт не Рльех: make-initrd против dracut
В ALT Linux свой генератор initramfs, называется make-initrd. Это самостоятельная разработка, которую Альт использует с незапамятных времён. Устроен он концептуально иначе: образ собирается из «фич» (features), каждая фича — набор скриптов и файлов в /usr/share/make-initrd/features/. Нужна сеть в initramfs — есть фича network. Нужен SSH — есть фича dropbear. Нужен LUKS — есть фича luks.
Поддержка LUKS в make-initrd вынесена в отдельный пакет make-initrd-luks. При установке с шифрованием установщик сам ставит этот пакет, сам включает фичу luks в /etc/initrd.mk и сам записывает /etc/crypttab, а make-initrd исправно кладёт этот crypttab в образ.
Если пакета нет, указание отсутствующей фичи не вызывает ошибки — такое поведение задокументировано. Образ соберётся, но внутри не окажется ни cryptsetup, ни обработчика шифрованных разделов. Поэтому после установки пакета и каждой пересборки стоит внимательно смотреть на строку Used features: среди использованных фич должна быть luks.
Стенд: поднимаем сервак, который не жалко
Чтобы не экспериментировать на боевых машинах, я поднял в своём Proxmox виртуалку с Альт Сервер 11.1. В итоговой разметке получились отдельный /boot без шифрования (grub и initramfs должны читаться до ввода пароля), отдельный swap и корень внутри LUKS2-контейнера с aes-xts. Проще говоря, типовой сервер, только с шифрованием из коробки.
Первая же загрузка такой машины выглядит так. В initramfs работает событийная кухня: udev обнаруживает устройства, а демон ueventd передаёт их обработчикам. Обработчик 085-luks видит LUKS-раздел, заглядывает в скопированный в образ /etc/crypttab, не находит файла-ключа и запрашивает парольную фразу на консоли:
udev: session=5: @85-luks: Trying to ask the user for a password.
Enter passphrase for /dev/sda3:
И стоит. Загрузка дальше не идёт, потому что корень физически недоступен. Вот эту сцену мы и будем лечить.
Рецепт
Шаг первый — пакеты. Как я уже говорил, на системе, изначально установленной с LUKS-корнем, make-initrd-luks уже стоит, а фича luks уже включена в /etc/initrd.mk. Остаётся поставить dropbear — маленький SSH-сервер (сама фича dropbear уже есть в базовом пакете make-initrd, но бинарник надо откуда-то взять) — и sysklogd: фича dropbear требует фичу syslog, а syslog без бинарников klogd/syslogd в образ не собирается:
$ apt-get install dropbear sysklogd
Теперь важная строчка в /etc/crypttab. Установщик пишет туда запись с именем вида luks-; мы дописываем опцию headless в четвёртую колонку:
luks-ВАШ-UUID UUID=ВАШ-UUID none luks,headless
Этот флаг разбирает штатный обработчик 085-luks. Без headless он занимает консоль и запускает собственный cryptsetup, а потом наш второй cryptsetup по SSH начинает с ним толкаться локтями. С headless обработчик не спрашивает фразу на консоли и освобождает дорогу удалённой разблокировке. Цена очевидна: обычного запроса фразы на локальной консоли в этой загрузке тоже не будет, поэтому резервный вариант загрузки следует проверить заранее.
Шаг второй — отдельный ключ для разблокировки. Заводим его заранее и не смешиваем с основным:
$ ssh-keygen -t ed25519 -f ~/.ssh/unlock_key -N ''
$ scp ~/.ssh/unlock_key.pub user@сервер:/tmp/unlock_key.pub
$ ssh user@сервер "sudo -S sh -c 'mkdir -p /root/.ssh; cat /tmp/unlock_key.pub >> /root/.ssh/authorized_keys; chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys'; rm /tmp/unlock_key.pub"
Шаг третий — конфиг /etc/initrd.mk. Эти строки добавляются к существующему файлу, не заменяют его. Строку про luks добавлять не нужно: на установке с шифрованием она там уже есть (если вы шифровали корень уже после установки — добавьте и её, вместе с пакетом make-initrd-luks):
FEATURES += network syslog dropbear
PUT_FILES += /etc/passwd /etc/shells /root/.ssh/authorized_keys
PUT_FILES += /etc/dropbear/dropbear_rsa_host_key /etc/dropbear/dropbear_ecdsa_host_key
Про сеть вопросов быть не должно, как и про /etc/passwd с /etc/shells по идее тоже. SSH-серверу нужно знать, под кем пускать.
Шаг четвёртый — host-ключи dropbear. Без них dropbear сгенерирует новые при каждой загрузке, и ваш ssh будет каждый раз истерить про смену ключа хоста:
mkdir -p /etc/dropbear
dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key
Шаг пятый — маленькая самодельная служба, без которой не будет интерактивного входа. В штатном образе make-initrd нет каталога /dev/pts, поэтому dropbear не может выдать PTY, и ssh -t отваливается с «PTY allocation request failed». Забавно, что rc-скрипт фичи dropbear уже пытается смонтировать devpts, но монтировать некуда: каталога-то нет. Лечится одним скриптом.
Свои каталоги для админских настроек make-initrd пока не завёз, но у него есть переменная PUT_DIRS: каталоги из неё копируются в образ целиком, вместе с деревом. Создаём нашу службу в /etc:
mkdir -p /etc/make-initrd/devpts/etc/rc.d/init.d
Файл /etc/make-initrd/devpts/etc/rc.d/init.d/devpts:
#!/bin/bash
### BEGIN INIT INFO
# Provides: devpts
# Required-Start: cmdline
# Default-Start: 3 4 5
### END INIT INFO
[ "$1" = start ] || exit 0
. /.initrd/initenv
. /etc/init.d/functions
mount_devpts()
{
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts -o mode=0620
}
action_shell 'Mounting devpts:' mount_devpts
Не забудьте chmod +x и допишите в /etc/initrd.mk строку:
PUT_DIRS += /etc/make-initrd/devpts
Шаг шестой — сеть и таймер. Фича network настраивается параметром ядра ip=dhcp. И сразу же, той же строкой, добавьте rootdelay=600 (может пригодится): оба параметра — в переменную GRUB_CMDLINE_LINUX_DEFAULT файла /etc/sysconfig/grub2.
Шаг седьмой — пересборка всего, что зависит от конфигов:
make-initrd
update-grub
В выводе make-initrd появится строка Used features — проверьте глазами, что там есть luks, network, syslog и dropbear. Дальше можно перезагружаться и смотреть.
Момент истины
Перезагружаемся и ждём какое-то время: в initramfs поднимаются сеть (DHCP) и dropbear. Подключаемся самым обычным образом:
ssh -t -o HostKeyAlias=server-initramfs -i ~/.ssh/unlock_key root@сервер
Благодаря службе из пятого шага получаем живое приглашение (initramfs)$ — полноценный интерактивный сеанс. Открываем контейнер:
cryptsetup open /dev/disk/by-uuid/ВАШ-LUKS-UUID ИМЯ-ИЗ-CRYPTTAB
UUID — из второй колонки crypttab, имя (у установщика оно вида luks-) — из первой. cryptsetup сам спросит парольную фразу и отключит эхо; по пути ввод шифрует SSH. Оговорка для параноиков: root на клиенте или в initramfs остаётся доверенной стороной, и от уже подменённого initramfs это не спасает.
Дальше всё происходит само: обработчики прогоняют fsck, монтируют корень, прощаются с dropbear — и наша SSH-сессия обрывается, а система грузится как ни в чём не бывало.
А теперь про rootdelay=600, который может пригодиться. По умолчанию initramfs ждёт корень 180 секунд. Не успели разблокировать — загрузка валится в аварийную оболочку, и дёшево это не лечится: rootdelayd намертво захватывает консольную блокировку, остальные обработчики виснут на ней же, и даже правильно введённая после дедлайна фраза уже ничего не оживит — только перезагрузка и новая попытка. Заодно по консоли в этом состоянии сыплются сообщения «085-luks: unable to activate LUKS (rc=1)» — при headless это нормальный шум, обработчик лишь рапортует, что спрашивать фразу ему запретили. В принципе 180 секунд вполне достаточно чтобы успеть ввести парольную фразу, но для надёжности интервал проще увеличить до rootdelay=600 (на общее время загрузки это всё равно не повлияет).
Проверяем после загрузки: findmnt -n -o SOURCE / отдаёт /dev/mapper/luks-ВАШ-UUID, cryptsetup status показывает активный LUKS2. Сервер поднялся, что не может не радовать.
Про безопасность, без неё никак
Список оговорок, идущий в комплекте с любым рецептом «SSH в раннюю загрузку».
Ваш публичный ключ и host-ключи лежат в initramfs, который лежит в /boot, который не шифруется. Кто-то с физическим доступом к диску получит и ключ, и возможность подменить загрузочную среду. От угрозы «диск вынули и унесли» это спасает; от угрозы «диск подменили и подслушивают фразу» — нет, тут нужны другие механизмы, от Secure Boot до выноса /boot на съёмном носителе.
Отдельный ключ для разблокировки — не волшебная защита: запись в authorized_keys без принудительной команды даёт полноценный root в среде initramfs. Ограничение через forced command в dropbear я на стенде не проверял, поэтому вслух обещать не буду.
В known_hosts у машины появится два разных ключа: initramfs-dropbear и системный openssh. Два SSH-сервера — два ключа, всё честно. ssh при встрече второго устроит сцену про man-in-the-middle — не поддавайтесь: у ранней загрузки свой HostKeyAlias (в командах выше он уже прописан), а отпечаток при первом знакомстве сверяем по консоли. Строгую проверку не выключаем: лучше один раз посмотреть отпечаток глазами, чем потом гадать, кто это у нас там разблокировал сервер.
Заключение
Соберём в одну кучу. Два пакета, три штатные фичи, один самодельный скрипт с открытку, словечко headless в crypttab, rootdelay в параметрах ядра, отдельный ключ, вшитые passwd с shells и host-ключи, пересборка образа с загрузчиком. После перезагрузки вас встречает ssh -t со знакомым запросом фразы, дальше сервер справляется сам. Ручной работы вышло примерно как у редхатовцев; разница в том, что их последнюю милю за них уже написал пакет, а свою мы бахнули сами. Всего-лишь несколько строчек, между прочим (честно говоря на старте я думал, что решение будет куда сложнее).
И напоследок. DHCP в ранней загрузке иногда капризничает, headless запрещает серверу спросить вас на консоли, а таймер тикает при любых раскладах. Так что это, конечно, удобно, но не должно быть единственным ключом от машины. Так что резервный доступ (IPMI, консоль хостера, второй интерфейс со статикой) должен жить отдельно, а всю связку сначала гоняем на сервере, до которого можно дотянуться рукой.
Чек-лист харденинга SSH: как настроить вход и проверить результат
Чек-лист харденинга SSH помогает убрать лишние способы входа на VPS. Харденингом называют настройку защиты сервера. Безопасная настройка sshd_config сводится к тому, чтобы оставить один проверенный способ входа и уметь вернуть доступ, если что-то пойдёт не так.
Примеры рассчитаны на Ubuntu 24.04 LTS с OpenSSH из репозитория ОС. Параметры для другой ОС и требования аудита лучше заранее уточнить.
Какие параметры sshd_config важнее всего для аудита?
Основные параметры: PermitRootLogin для входа под root, PasswordAuthentication и KbdInteractiveAuthentication для способов проверки пользователя, AllowUsers или AllowGroups для ограничения круга пользователей. При многофакторной аутентификации важен AuthenticationMethods, который задаёт обязательные способы подтверждения входа. Результат настройки проверяют реальными попытками разрешённого и запрещённого входа.
Что именно нужно защитить
Безопасная настройка sshd_config начинается со списка тех, кому нужен SSH: владельца VPS, коллег, программы резервного копирования.
Пароль могут подобрать, ключ могут украсть, а доступ бывшего сотрудника иногда остаётся действующим месяцами. Вход только по ключам исключает подбор пароля. Украденный ключ нужно отозвать, а лишние учётные записи закрыть. Второй фактор, например одноразовый код, снижает риск входа с украденным ключом. Отдельная угроза – потеря журналов: если записи о входах хранятся только на самом сервере, злоумышленник с правами root может их изменить, и восстановить картину будет нечем.
Ошибка в настройках может закрыть вход самому администратору. До изменений проверьте, что консоль провайдера даёт доступ к файлам с правами администратора. В команде при необходимости назначьте ответственного за эту проверку.
Какие настройки сервер действительно использует
В чек-лист аудита SSH внесите версии ОС и OpenSSH, исходные настройки. Их покажут команды на сервере:
cat /etc/os-release
sudo /usr/sbin/sshd -V
sudo /usr/sbin/sshd -T
В Ubuntu файл /etc/ssh/sshd_config подключает через Include файлы из /etc/ssh/sshd_config.d/. Обычно действует первое прочитанное значение, а порядок чтения определяется именами файлов. Поэтому правка в конце основного файла может не сработать. Подробности есть в документации Ubuntu.
Блоки Match задают исключения для пользователей и адресов. Параметр -C учитывает их для конкретного подключения:
sudo /usr/sbin/sshd -T \
-C user=admin,addr=198.51.100.10,host=client.example
sudo ss -ltnp
Подставьте своего пользователя, IP и имя клиента. Если Match содержит условия на адрес и порт сервера, укажите их через laddr и lport. Вывод -T показывает то, что записано в файлах на диске. Уже открытые сеансы продолжают работать по прежним настройкам, поэтому проверять изменения нужно новым подключением. Слушающие порты покажет команда ss, а её вывод стоит сверить с правилами межсетевого экрана на VPS и в панели провайдера.
Кому принадлежат учётные записи и ключи
Составьте список всех учётных записей, которые могут войти и выполнять команды. Отдельно отметьте тех, кто может выполнять команды от имени администратора через sudo. В authorized_keys хранятся разрешённые открытые ключи. У каждого должен быть известен владелец, потому что подпись рядом с ключом ещё не подтверждает его личность. Отключение входа по паролю SSH лучше делать только после того, как этот список собран.
Личные аккаунты помогают различать администраторов в журнале. Программе резервного копирования выделите отдельный ключ. Параметр command= в authorized_keys ограничивает его заданной командой, а restrict отключает дополнительные возможности, включая туннели. После настройки по справке OpenSSH убедитесь, что копирование работает.
При плановой замене ключа сначала проверьте новый, затем удалите старый со всех серверов. Удаление ключа не завершает открытые сеансы, поэтому при краже их придётся проверить отдельно.
Как отключить вход по паролю и не потерять доступ?
Сначала войдите по ключу под отдельным пользователем с sudo в новом SSH-сеансе и оставьте старое подключение открытым. До применения изменений проверьте конфигурацию, доступ через консоль провайдера и порядок отката. После применения повторите вход. Если используется многофакторная аутентификация, проверьте также работу второго фактора.
Какие способы входа оставить
Следующий пример разрешает вход только по ключам. Вместо admin укажите имя пользователя, под которым вы уже проверили вход и sudo:
# Вход только по ключу; без второго фактора через PAM
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers admin
В AllowUsers включите всех нужных пользователей и служебные аккаунты. Если удобнее управлять группой, вместо списка имён можно использовать AllowGroups. MFA и allowlist для SSH работают вместе: список ограничивает круг пользователей, второй фактор защищает от украденного ключа.
Параметр PermitRootLogin со значением no запрещает прямой вход под root. Значение prohibit-password сохраняет вход root по ключу.
Для ключа и одноразового кода через PAM, систему аутентификации Linux, нужны другие значения. Прежние значения замените следующими, а UsePAM добавьте, если его ещё нет:
UsePAM yes
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive:pam
Такая многофакторная аутентификация (MFA) работает лишь с заранее настроенным PAM-модулем. Сам keyboard-interactive может запрашивать обычный пароль. Поэтому одного PasswordAuthentication no недостаточно для запрета всех способов парольного входа.Как применить изменения и вернуться назад
До правок проверьте вход по ключу в новом соединении. На своём компьютере выполните команду со своим логином и адресом VPS:
ssh -o ControlPath=none -o PreferredAuthentications=publickey \
admin@SERVER
Команда создаёт новое соединение и допускает только вход по ключу. Для MFA через PAM укажите в PreferredAuthentications publickey,keyboard-interactive. В новом сеансе проверьте sudo. Старый оставьте открытым.
В этом примере меняется только новый файл /etc/ssh/sshd_config.d/00-local-access.conf. Это имя и имя с окончанием .disabled должны быть свободны. Сохраните вывод -T до правок. После них убедитесь, что нужные значения действуют для каждого условия Match.
Сначала выясните, как запущен SSH. Команда systemctl is-enabled ssh.socket покажет, включена ли активация через сокет. В Ubuntu она включена по умолчанию с версии 22.10. sshd не работает постоянно, а поднимается на каждое входящее соединение и читает конфигурацию заново, поэтому reload не нужен, достаточно открыть новый сеанс. Если сокет отключён и работает постоянная служба, изменения применяет reload:
systemctl is-enabled ssh.socket
sudo /usr/sbin/sshd -t && sudo systemctl reload ssh.service
Проверка -t при успехе ничего не печатает. При ошибке команда после && не выполнится. Запрет root login и остальные ограничения проверяют попытками входа: повторите вход по ключу, проверку sudo и попытки запрещённого входа.
Для отката в старом сеансе или консоли переименуйте файл, после этого он не попадает под маску *.conf.
sudo mv /etc/ssh/sshd_config.d/00-local-access.conf \
/etc/ssh/sshd_config.d/00-local-access.conf.disabled
sudo /usr/sbin/sshd -t
Этот откат относится только к новому файлу. PAM, межсетевой экран и порт меняйте отдельно, с собственными командами возврата. Старый сеанс закройте лишь после всех проверок.
Что делать с туннелями и алгоритмами
Безопасность SSH на VPS зависит и от возможностей после входа. Например, SSH-туннель передаёт трафик другой программы через зашифрованное соединение.
AllowTcpForwarding управляет TCP-туннелями. X11Forwarding разрешает вывод окон серверных программ на компьютер пользователя. AllowAgentForwarding даёт доступ через сервер к агенту с ключами на компьютере пользователя. Ненужные возможности стоит отключить. При этом пользователь с командной оболочкой может обойти запрет туннелей собственной программой пересылки трафика.
В поддерживаемой версии OpenSSH начните с настроек по умолчанию. Перед изменением списка шифров нужна проверка клиентов. Обновления лучше устанавливать регулярно.
MaxAuthTries ограничивает попытки входа в одном соединении. При слишком низком значении клиент может не успеть предложить подходящий ключ. ClientAliveInterval задаёт интервал проверки связи с клиентом. Пауза в наборе команд сама по себе не приводит к отключению.
Достаточно ли Fail2ban и нестандартного порта?
Нет, этих мер мало.
1. На другом порту обычно меньше автоматических попыток входа, но сканирование всё равно его найдёт.
2. Блокировка адресов за неудачные входы сдерживает перебор, однако украденный рабочий ключ пройдёт проверку с первой попытки.
3. Нужны контроль ключей и пользователей, ограничения доступа, обновления и журналы, а второй фактор выбирают с учётом рисков.
Как ограничить сеть и сохранить события входа
Межсетевой экран может принимать SSH только с адресов администраторов. Проверьте вход из разрешённой и посторонней сети, включая IPv6, если он используется.
Fail2ban временно блокирует адреса после серии неудачных входов. После установки убедитесь, что он читает журнал SSH и применяет блокировки. Тестовые попытки входа тоже могут привести к блокировке вашего IP.
Журнал должен содержать успешные входы, отказы и административные действия через sudo. Недавние записи в Ubuntu можно посмотреть так:
sudo journalctl -u ssh.service --since "30 minutes ago"
sudo journalctl SYSLOG_IDENTIFIER=sudo --since "30 minutes ago"
Злоумышленник с правами root может изменить локальный журнал. Копия на отдельном сервере поможет восстановить события. Убедитесь, что записи действительно туда попадают, время на обеих машинах синхронизировано по NTP, а журналы хранятся столько, сколько требует ваш аудит. Администраторам VPS не нужны права удаления этой копии.
Как подтвердить результат проверки
Отчёт содержит версии ОС и OpenSSH, список подключённых файлов, перечень пользователей и ключей, настройки до и после правок. К сравнению файлов до и после правок (diff) добавьте причины изменений. Приватные ключи и секреты второго фактора в отчёт входить не должны. Собранные файлы и результаты тестов и есть audit evidence, которое запросит аудитор.
В таблице ниже указаны ожидаемые результаты. Каждый сценарий нужно проверить на своём сервере:
Администратор из AllowUsers с верным ключом: вход и работа sudo
Тот же пользователь только с паролем: отказ во входе
Root с верным ключом: отказ во входе
Пользователь вне AllowUsers с верным ключом: отказ во входе
Подключение из запрещённой сети при настроенном межсетевом экране: блокировка межсетевым экраном
Возврат прежней конфигурации: новый вход по прежним правилам
Для проверки парольного входа выполните на своём компьютере:
ssh -o ControlPath=none -o PubkeyAuthentication=no \
-o PreferredAuthentications=password,keyboard-interactive \
admin@SERVER
Этот тест отключает ключи. Пользователя вне AllowUsers проверяйте с верным ключом, иначе причина отказа останется неясной. При MFA нужны попытки с верным, неверным и пропущенным кодом.
Рядом с результатом укажите дату, своё имя, адрес клиента и запись в журнале. Сетевую блокировку можно подтвердить ростом счётчика нужного правила межсетевого экрана. После обновлений и изменений в команде повторите проверку доступа.
Хороший результат выглядит просто: разрешённый пользователь входит, запрещённые сценарии получают отказ, а откат проверен заранее и не зависит от того, работает ли SSH. Чек-лист харденинга SSH храните вместе с инструкцией восстановления доступа. У каждого исключения должны быть причина, владелец и дата пересмотра. Так следующий администратор сможет отличить рабочую необходимость от забытой временной настройки.
Настройка VPS: первый запуск сервера от подключения до безопасности
Настройка VPS начинается со сверки: тот ли сервер выдали и кто, кроме вас, может на него войти. После первого входа нужно сверить параметры заказа, подтвердить SSH-отпечаток, создать отдельного администратора, ограничить входящие соединения и сохранить базовые метрики. Установка VPS по этой схеме рассчитана на образ Ubuntu 24.04 LTS с одним администратором. Панель или cloud-init могут менять эти шаги, поэтому некоторые пункты стоит проверять.
Что сделать сразу после получения доступа к VPS?
Для начала сверьте IP, регион, образ и ресурсы с заказом, затем найдите аварийную консоль и проверьте SSH-отпечаток. После входа создайте отдельного пользователя с sudo, подтвердите доступ по ключу во втором сеансе и только потом включайте firewall и запрещайте парольный вход. Для панели или готового образа сначала посмотрите уже открытые порты.
Что приходит после заказа VPS и что проверить до входа
В личном кабинете или письме указаны IPv4, логин, начальный пароль либо открытый ключ, а также IPv6, если он выдан. Сверьте с заказом регион, образ ОС, vCPU, RAM и диск. После загрузки проверьте их командами nproc, free -h, lsblk и cat /etc/os-release. С ошибкой в регионе или тарифе обратитесь в поддержку до размещения своих данных на сервер.
До первого SSH-входа найдите VNC или другую аварийную консоль, а также порядок запуска rescue mode. Это может понадобится, если ошибка в sshd_config или firewall закроет сетевой доступ. Инструкция Aéza по аварийному режиму показывает, где включается среда восстановления. Конечно, сама она не заменит резервную копию.
Пароль из письма нельзя считать постоянным секретом, так как он прошёл через почту и мог попасть в журнал уведомлений. Если после установки VPS доступен парольный вход, используйте его только для перехода на собственный ключ. Когда образ уже принимает заданный при заказе ключ, не включайте пароль ради удобства. Для нестандартного ISO также проверьте контрольную сумму или подпись.
Как подключиться к VPS и проверить отпечаток ключа
В Linux, macOS и Windows Terminal SSH-клиент вызывается одинаково. В примере данные замените на те, что в карточке сервера:
ssh root@203.0.113.42
При первом соединении OpenSSH показывает тип ключа хоста и SHA256-отпечаток.
The authenticity of host '203.0.113.42' can't be established.
ED25519 key fingerprint is SHA256:Wq6...K3A.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Не подтверждайте yes, пока не получите отпечаток другим путём. Откройте аварийную консоль и выполните ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub, затем сравните строку целиком.
После переустановки ключ хоста меняется. Если сервер не переустанавливали, предупреждение REMOTE HOST IDENTIFICATION HAS CHANGED требует остановки и проверки через консоль или поддержку. Команду ssh-keygen -R IP запускают только после подтверждения причины. На Windows запись хранится в %USERPROFILE%\.ssh\known_hosts, в Linux и macOS – в ~/.ssh/known_hosts.
Отдельный пользователь, sudo и вход по ключу
Сначала создайте учётную запись и каталог для ключа. Текущий сеанс пока не закрывайте:
sudo adduser operator
sudo usermod -aG sudo operator
sudo install -d -m 700 -o operator -g operator /home/operator/.ssh
На рабочем компьютере создайте ключ ssh-keygen -t ed25519 -a 100, если его ещё нет. В Linux перенесите открытую часть командой ssh-copy-id operator@IP. В macOS и Windows Terminal при отсутствии ssh-copy-id добавьте содержимое .pub в /home/operator/.ssh/authorized_keys через открытый сеанс, затем задайте владельца operator и права 600. Приватный ключ на сервер копировать не нужно. Войдите как operator во втором терминале и выполните sudo -v. После проверки можно продолжать настройку VPS сервера.
Как безопасно перейти с пароля на SSH-ключи?
Добавьте открытый ключ отдельному пользователю, войдите им во втором сеансе и проверьте sudo. Затем создайте конфигурационный фрагмент, который читается раньше остальных, выполните sshd -t и загрузите новую конфигурацию службы. Исходный сеанс держите открытым до повторного входа, а при ошибке исправьте настройки через аварийную консоль.
В Ubuntu файлы из sshd_config.d читаются раньше основного sshd_config, а для большинства директив действует первое найденное значение. Имя 00-local-hardening.conf помещает локальный фрагмент в начало порядка чтения.
sudo tee /etc/ssh/sshd_config.d/00-local-hardening.conf >/dev/null <<'EOF'
PubkeyAuthentication yes
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sudo sshd -t
sudo sshd -T | grep -E '^(pubkeyauthentication|permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '
sudo systemctl reload ssh
После sshd -t выполните reload и, не закрывая текущую сессию, откройте вторую новым пользователем. Проверка вторым сеансом важнее самой команды: на Ubuntu 24.04 с сокет-активацией reload может вернуть ошибку, если ssh.service не запущен. Если вход не работает, исправьте фрагмент через VNC и повторите sshd -t.
Запретить входящие и открыть только нужные порты
UFW в стандартном Ubuntu изначально выключен, а в облачном образе пакет и вовсе может отсутствовать. Проверьте его, задайте политики и откройте SSH-порт. Если sshd слушает не 22-й порт, возьмите значение из sudo ss -utlnp.
if ! command -v ufw >/dev/null; then sudo apt update && sudo apt install ufw; fi
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw show added
sudo ufw enable
sudo ufw status numbered
sudo ss -utlnp
Перед ufw enable оставьте SSH-сеанс открытым. Второй терминал понадобится, чтобы проверить, как подключиться к VPS при действующих правилах. ufw status показывает эти правила, а ss -utlnp – слушающие сокеты и связанные процессы. Сетевой экран не останавливает сами службы.
Порты 80 и 443 добавляют после запуска веб-сервера. Базу данных, Redis и административную панель не нужно открывать всему интернету только потому, что приложение к ним подключается. Смена SSH-порта уменьшает шум от сканеров в журнале, но не заменяет ключи и запрет входа по паролю. В руководстве Ubuntu по UFW описаны простые правила, однако сетевой экран в панели провайдера остаётся отдельным уровнем.
Docker направляет трафик к опубликованным портам в обход обычных правил UFW. Сервис за обратным прокси привязывайте к 127.0.0.1. Для iptables правила пишите в цепочку DOCKER-USER: она документирована и не перезаписывается при перезапуске Docker. При другом бэкенде фильтруйте трафик в панели провайдера.
Обновления, время, локаль и swap без лишнего тюнинга
Разобравшись, как подключиться к VPS серверу, обновите систему и сверьте часы. Просмотрите предлагаемые изменения, установите пакеты и проверьте, нужна ли перезагрузка:
sudo apt update
sudo apt full-upgrade
sudo apt install fio iperf3 sysstat dnsutils
test ! -e /var/run/reboot-required || cat /var/run/reboot-required.pkgs
sudo systemctl --failed
timedatectl status
locale
swapon --show --bytes
free -h
В стандартной установке Ubuntu 24.04 пакет unattended-upgrades ежедневно применяет обновления безопасности. Сторонние репозитории без отдельного правила он не охватывает, а автоматическая перезагрузка по умолчанию выключена. Ответственного за окно обновлений и перезагрузку лучше всё равно назначить, а результат контролировать по /var/log/unattended-upgrades/.
Для серверных журналов удобно оставить UTC: sudo timedatectl set-timezone UTC. Локаль C.UTF-8 уменьшает расхождения в выводе скриптов, если приложение не требует другой: sudo localectl set-locale LANG=C.UTF-8. Менять локаль ради отдельной команды не нужно, достаточно запускать её с LC_ALL=C.
Swap даёт ядру запас при резком пике памяти. При нехватке RAM этот механизм может вызвать длительные задержки при обращении к диску. Сначала проверьте текущий swap и профиль приложения. Для базы данных или сервиса, чувствительного к задержке, размер и vm.swappiness выбирают после замеров. Если в vmstat постоянно растут столбцы si/so, пересмотрите лимиты или тариф до увеличения swap.
Как доказать, что VPS работает после настройки
Сразу после настройки сервер пустой, и это лучший момент снять базовую линию. Через месяц, когда появится жалоба на медленную работу, сравнивать будет не с чем. Зафиксируйте дату, исполнителя, ОС, ядро, vCPU, RAM, диск и версии утилит. Для CPU сохраните минутный лог mpstat, для диска используйте временный файл, а iperf3 запускайте до своего узла в целевом регионе.
Как проверить безопасность и базовую производительность VPS?
1. Сохраните эффективные параметры sshd -T, правила ufw status numbered и список слушающих сокетов ss -utlnp.
2. Сохраните минутный лог mpstat, запустите fio на две минуты и запишите p50/p95/p99, затем выполните прямой и обратный прогоны iperf3.
3. Приложите конфигурацию, версии и сырой вывод, затем повторите замеры в другое время. Один максимум не считается базовой линией.
date -Is; uname -r; lscpu | sed -n '1,16p'; free -h; lsblk
fio --version; iperf3 --version; mpstat -V
LC_ALL=C mpstat -P ALL 1 60 | tee mpstat.log
fio --name=baseline --filename=/var/tmp/fio.bin --size=1G --direct=1 \
--rw=randrw --rwmixread=70 --bs=4k --ioengine=libaio --iodepth=1 \
--runtime=120 --time_based --group_reporting --percentile_list=50:95:99 \
--output-format=json --output=fio.json
rm -f /var/tmp/fio.bin
: "${IPERF_HOST:?Укажите адрес сервера iperf3}"
iperf3 -c "$IPERF_HOST" -P 4 -t 30 -O 5 --json > iperf3-send.json
iperf3 -c "$IPERF_HOST" -P 4 -t 30 -O 5 -R --json > iperf3-recv.json
fio нагружает диск, поэтому запускайте его в согласованное окно: на основном сервере и на соседних VM нагрузка будет заметна. iodepth=1 показывает задержку одиночной очереди, а не максимальные IOPS при глубине 32. Файл должен помещаться на диске с запасом. В документации fio JSON содержит IOPS и completion latency percentiles, включая заданные p50, p95 и p99.
На собственном контрольном узле запустите iperf3 -s, задайте его адрес в IPERF_HOST и выполните прямой и обратный прогоны с одинаковыми параметрами. Публичный узел не служит эталоном. По официальной документации iperf3 для теста нужны клиент и сервер. Между прогонами не меняйте конечные узлы и их конфигурацию. Сохраните JSON и повторите замер трижды. Оценивайте %steal вместе с загрузкой vCPU: одиночный всплеск не доказывает проблему хоста.
Привязать домен и не ждать TTL вслепую
A-запись содержит IPv4 сервера, AAAA-запись содержит IPv6. Перед добавлением AAAA проверьте маршрут, сетевой экран и прослушивание сервиса по IPv6. Первоначальная настройка VPS также требует проверить, проксирует ли DNS-провайдер веб-трафик и какой IP увидит пользователь.
TTL определяет, как долго резолвер может хранить ответ в кеше. После изменения запросите авторитетный сервер зоны, а потом несколько рекурсивных резолверов. До истечения прежнего TTL часть из них может возвращать старый ответ.
dig +noall +answer A app.example.com @1.1.1.1
dig +noall +answer A app.example.com @8.8.8.8
dig +noall +answer AAAA app.example.com @1.1.1.1
AUTH_NS=$(dig +short NS example.com | head -n 1)
dig +noall +answer A app.example.com @"$AUTH_NS"
Если ответы расходятся, сравните их TTL с ответом авторитетного сервера. Очистка локального кеша не изменит запись у внешнего резолвера. Для HTTPS дополнительно проверьте сертификат и имя виртуального хоста, поскольку правильный A/AAAA ещё не подтверждает готовность приложения.
Для исходящей почты нужен PTR, который настраивает владелец IP-диапазона. Имя из PTR должно прямым запросом возвращаться к тому же адресу. Требования Gmail для всех отправителей включают согласованные прямую и обратную DNS-записи, а также SPF или DKIM. При отправке более 5000 писем в сутки на адреса Gmail нужны оба механизма и DMARC. Если сервер не отправляет почту напрямую, веб-сайту PTR не нужен.
Что добавить после первого часа: бэкап, мониторинг и сервис
После настройки сервер доступен для эксплуатации. Назначьте ответственных за обновления, резервные копии и секреты, а также зафиксируйте срок реакции на сбой. Без регулярной проверки списка ключей, заполнения диска и бэкапов даже завершённая настройка безопасности VPS быстро устареет.
Бэкапы храните вне VPS и регулярно восстанавливайте тестовую копию. Не стоит путать со снапшотами: они фиксируют состояние на момент создания, но не заменяют независимую копию и журнал восстановления. Частоту выбирают по RPO, а время восстановления по RTO. Для базы данных нужна согласованная копия средствами СУБД или остановка записи на время снимка.
В мониторинг включите доступность сервиса, свободное место, память, срок TLS-сертификата, обновления и дату последнего успешного бэкапа. Пороги задавайте после сохранения базовой линии. Секреты храните отдельно от истории команд, compose-файла и репозитория. Для каждого секрета укажите ответственного и период ротации.
Docker, панели и бэкапы требуют отдельных инструкций: у них разные сетевые правила, каталоги данных и процедуры обновления. Одного администратора и UFW недостаточно для командной работы, персональных данных, публичной БД или требований регулятора. В этих случаях нужны журналирование действий, раздельные роли, MFA, проверенное восстановление и контролируемый процесс выпуска изменений.
Перед размещением приложения соберите паспорт сервера: адреса, способ аварийного входа, ожидаемые порты, место хранения бэкапа, ответственных, команды проверки и условия замеров.
Через сутки после первого запуска повторите контрольные проверки. Убедитесь, что обновления завершились, место на диске не заканчивается, сервис отвечает, а задание бэкапа выполнилось успешно. Считайте, что настройка VPS закончена, когда текущее состояние можно проверить, а порядок восстановления понятен тому, кто будет сопровождать сервер.
Работаем с файлами на удаленном сервере как с локальными: шпаргалка по SSHFS
Когда нужно настроить постоянный и быстрый обмен файлами в локальной сети, мы поднимаем NFS или Samba. Но что делать, если сервер находится далеко в интернете, настраивать сложную шару некогда, а скачивать и закачивать файлы через scp или FileZilla уже надоело?
Тут на помощь приходит SSHFS (Secure Shell File System). Главная прелесть этой штуки в том, что на самом сервере вообще ничего не нужно настраивать. Если у вас есть SSH-доступ к серверу — значит, вы уже можете примонтировать его файловую систему к себе на ПК и работать с ней, как с обычной флешкой.
Делается это буквально в несколько команд.
Установка и подготовка На локальную машину (с которой будем подключаться) ставим пакет sshfs:
sudo apt install sshfs
Далее создаем директорию, которая будет служить точкой монтирования. Лучше всего делать это в своем домашнем каталоге, чтобы не возиться с правами root:
mkdir -p ~/mnt/remote_dir
(Ключ -p автоматически создаст все промежуточные каталоги, если их нет).
Монтируем удаленную директорию Синтаксис предельно простой:
sshfs user@remote_server:/path_to_remote_dir ~/mnt/remote_dir
Например, если я хочу примонтировать каталог My-folder с удаленного сервера (IP: 192.168.1.6) в свою созданную папку, команда будет выглядеть так:
sshfs admin@192.168.1.6:/home/admin/My-folder ~/mnt/remote_dir
После монтирования можно проверить результат командой df -h. Теперь вы можете копировать, удалять, редактировать файлы в IDE или просматривать логи прямо в примонтированной папке. Все изменения моментально происходят на сервере.
Важные нюансы (чтобы не отваливалось) У SSHFS есть особенность: если интернет моргнет, примонтированная папка может намертво зависнуть. Чтобы этого избежать, рекомендую монтировать с параметрами поддержания сессии:
sshfs -o ServerAliveInterval=15 admin@192.168.1.6:/home/admin/My-folder ~/mnt/remote_dir
(Эта опция будет каждые 15 секунд отправлять ping-пакет на сервер, не давая соединению разорваться).
Как размонтировать? Когда работа закончена, директорию нужно отмонтировать. Так как мы монтировали без прав суперпользователя, обычный umount может выдать ошибку прав. Правильнее использовать эту команду:
fusermount -u ~/mnt/remote_dir
(Если получаете ошибку «устройство занято», убедитесь, что вы закрыли все файлы из этой папки и сами вышли из директории в терминале).
Используете ли вы SSHFS в повседневной работе или предпочитаете другие инструменты? Пишите в комменты.
Больше подобных шпаргалок, команд и коротких заметок по Linux и администрированию серверов я регулярно публикую в своем Telegram-канале [Linux для Админов и DevOps]. Буду рад видеть там коллег по цеху, заходите!





