Skip to content
EN
← Все статьи

Настройка VPS сервера: чек-лист первых 30 минут до деплоя сайта

Коротко. Сразу после выдачи VPS, до выкладки проекта, нужно сделать восемь вещей: проверить ресурсы и тип виртуализации, завести непривилегированного пользователя с sudo, перенести SSH-ключ и отключить вход по паролю, поднять firewall и fail2ban, накатить обновления и включить автоустановку security-патчей, задать hostname, часовой пояс и NTP, добавить swap и лимиты открытых файлов. Веб-стек, SSL, бэкапы и мониторинг ставятся сразу следом — не «потом».

Почему первые 30 минут важнее последующего тюнинга

Свежий VPS в момент выдачи — это машина с публичным IP, открытым SSH и, как правило, паролем root, который вам прислали в письме. Сканеры находят такой хост за минуты: типовой сервер начинает получать переборы SSH ещё до того, как вы успели придумать имя проекту. Всё, что вы сделаете в первые полчаса, определяет, будет ли сервер жить годами или превратится в майнер-ферму на второй неделе.

Вторая причина — стоимость исправления. Поменять дистрибутив, разметку диска, имя пользователя или схему бэкапов легко на пустом сервере и мучительно после того, как на нём крутится прод с базой и почтой. Порядок шагов ниже выстроен именно по этой логике: сначала необратимое и фундаментальное, потом всё остальное.

Правило: не выкладывайте проект на сервер, где ещё не настроены firewall, автоматические security-обновления и бэкапы. Сайт, который «пока в тесте», индексируется, сканируется и ломается ровно так же, как продакшен.
Таймлайн первых тридцати минут настройки VPS: проверка ресурсов, пользователь с sudo, SSH-ключи, firewall, обновления, время, swap
Порядок шагов: сначала необратимые решения, потом сервисы приложения

Шаг 0. Какую ОС выбрать для сервера и почему не «самую свежую»

Для веб-сервера подходит LTS-ветка: Ubuntu Server LTS или Debian stable. Мотив прост — предсказуемость. LTS-релизы получают security-обновления годами без смены мажорных версий системных библиотек, а значит, ваш сервер не сломается от планового обновления. Ubuntu LTS выходит раз в два года и держит стандартную поддержку около пяти лет, Debian stable живёт примерно три года плюс продление силами LTS-команды.

«Самый свежий» промежуточный релиз (interim) — плохой выбор для прода: короткий срок поддержки (порядка девяти месяцев), после чего вы обязаны делать полное обновление дистрибутива на живом сервере. Разница в версии nginx или PHP решается подключением официального репозитория пакета, а не сменой ОС.

КритерийUbuntu Server LTSDebian stableПромежуточный релиз
Срок поддержкиГоды, фиксированГоды, фиксированМесяцы
Свежесть пакетовСредняяКонсервативнаяВысокая
Готовые инструкции в сетиМаксимумМногоМало
Риск сломать прод обновлениемНизкийОчень низкийВысокий
Кому подходитТиповой веб-проектДолгоживущий сервер, минимум измененийСтенд, эксперименты

Отдельно про панели: образы с преднастроенными панелями управления экономят время на старте, но забирают контроль над конфигами nginx и правилами firewall. Если вы читаете этот чек-лист, вам, скорее всего, нужен чистый образ. Разницу между тарифами и типами хостинга разбираем в статье Виртуальный хостинг, VPS или выделенный сервер.

Шаг 1. Проверить, что вам реально выдали

До установки софта убедитесь, что железо соответствует тарифу и что это не «оверселлинг» с ядром, поделённым на десятерых. Три минуты команд экономят день разбирательств с поддержкой.

# тип виртуализации: kvm — полноценная ВМ, lxc/openvz — контейнер
systemd-detect-virt

# процессор: число ядер, модель, флаги
lscpu | head -20

# память и swap (по умолчанию swap на VPS часто отсутствует)
free -h

# диски, разделы, свободное место
lsblk
df -hT

# сетевые интерфейсы и адреса
ip -br address

# версия ядра и дистрибутива
uname -r
cat /etc/os-release

Что смотреть в выводе:

  • Контейнерная виртуализация (lxc, openvz) — общее ядро с хостом. Нельзя загрузить свои модули, часто нельзя пользоваться собственным swap и некоторыми sysctl, могут не работать Docker-фичи и nftables. Для веб-сайта это обычно приемлемо, для нестандартного стека — блокер.
  • Дисковый бэкенд: virtio-диск на NVMe даёт совсем другой профиль задержек, чем сетевой том. Быстрая прикидка: dd if=/dev/zero of=/tmp/t bs=1M count=1024 conv=fdatasync и затем удалить файл.
  • Флаги CPU: наличие aes заметно влияет на скорость TLS-хендшейков, отсутствие — повод удивиться.

У большинства провайдеров, включая Selectel, тип виртуализации и дисковую подсистему видно ещё на этапе выбора конфигурации — сверяйте вывод с описанием тарифа, а не с ожиданиями.

Шаг 2. Первый вход, отдельный пользователь и sudo

Первое подключение почти всегда идёт под root — по паролю из письма или по ключу, добавленному при создании сервера. Работать под root постоянно не нужно: любая опечатка выполняется без подтверждений, а логи не показывают, кто именно что сделал.

# подключаемся первый раз (порт по умолчанию — 22)
ssh root@203.0.113.10

# 1. создаём пользователя: заведёт /home/deploy и спросит пароль
adduser deploy

# 2. выдаём права администратора
#    Debian/Ubuntu — группа sudo, RHEL/AlmaLinux/Rocky — wheel
usermod -aG sudo deploy

# 3. переносим авторизованные ключи root в профиль пользователя
rsync --archive --chown=deploy:deploy /root/.ssh /home/deploy/

# 4. права обязаны быть строгими, иначе sshd проигнорирует ключи
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

# 5. ПРОВЕРКА из нового окна терминала, старую сессию не закрывать
ssh -t deploy@203.0.113.10 'id; sudo true && echo sudo-ok'

# 6. и только после успешной проверки блокируем пароль root
passwd -l root
Никогда не закрывайте текущую SSH-сессию, пока не проверили новый доступ из отдельного окна. Это единственная защита от сценария «отключил пароль, ключ не подошёл, консоли у провайдера нет».

SSH-ключи и отключение парольного входа

Пароль подбирается перебором, ключ — нет. Минимальный набор изменений вносится не в основной конфиг, а в drop-in файл, чтобы обновление пакета не затёрло правки:

# /etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30

# проверяем синтаксис ДО применения — иначе sshd не поднимется
sshd -t

# перечитываем конфиг без разрыва текущих сессий
systemctl reload ssh

Полный разбор — генерация пары, ed25519 против RSA, ssh-agent, несколько ключей, отладка «Permission denied (publickey)» — в отдельной статье: настройка входа по SSH-ключу. Описание всех директив — в официальном руководстве sshd_config(5).

Смена стандартного порта 22 на нестандартный не является защитой, но заметно уменьшает шум в логах от массовых сканеров. Если меняете — сначала добавьте правило в firewall, потом правьте sshd, и обязательно поправьте профиль ufw.

Шаг 3. Firewall: закрыть периметр до установки софта

На чистой системе firewall обычно пуст: снаружи доступно всё, что слушает на 0.0.0.0. Пока сервисов нет — самое время задать политику «запрещено всё, кроме явно разрешённого».

# политика по умолчанию
ufw default deny incoming
ufw default allow outgoing

# разрешаем только необходимое
ufw allow OpenSSH        # профиль = 22/tcp; для другого порта: ufw allow 2222/tcp
ufw allow 80/tcp         # HTTP: нужен для редиректа и выпуска сертификата
ufw allow 443/tcp        # HTTPS

# страховка от самоблокировки: автосброс правил через 10 минут
systemd-run --unit=ufw-rollback --on-active=10min /usr/sbin/ufw --force reset

ufw enable               # запросит подтверждение, предупредит о разрыве SSH
ufw status verbose

# связь жива, правила верны — отменяем страховку
systemctl stop ufw-rollback.timer
Порядок обязателен: сначала ufw allow OpenSSH, только потом ufw enable. Обратный порядок — самая частая причина потери доступа к свежему серверу.

Базу данных, Redis, панели администрирования и метрики наружу не выставляют: они слушают на 127.0.0.1 или на приватном интерфейсе. Если доступ нужен извне — только через SSH-туннель или приватную сеть провайдера, но не правилом «разрешить 3306 всем». Что бывает, когда порт всё-таки открыт, разбираем в материале про открытые порты и их риски.

fail2ban одной строкой

Даже при отключённых паролях брутфорс продолжает стучаться и засорять журналы. fail2ban читает логи и банит источники средствами firewall:

apt install -y fail2ban
printf '[sshd]\nenabled = true\nmaxretry = 3\nbantime = 1h\nfindtime = 10m\n' > /etc/fail2ban/jail.d/sshd.local
systemctl restart fail2ban
fail2ban-client status sshd

Тонкости — backend для systemd-журнала, ложные срабатывания, разбор своих логов nginx, whitelist офисных адресов — в подробном руководстве: настройка fail2ban.

Схема периметра сервера: снаружи открыты только порты 22, 80 и 443, база данных и кэш слушают локальный интерфейс
Наружу — только SSH, HTTP и HTTPS; всё остальное на loopback

Шаг 4. Обновления и автоматические security-патчи

Образ VPS собирается заранее и к моменту выдачи обычно отстаёт на недели. Первое, что делается после закрытия периметра, — полное обновление:

apt update
apt full-upgrade -y
apt autoremove --purge -y

# требуется ли перезагрузка (появляется после обновления ядра/libc)
[ -f /var/run/reboot-required ] && cat /var/run/reboot-required.pkgs

Дальше включается автоматическая установка именно security-обновлений. Полностью автоматические обновления всех пакетов на веб-сервере — риск: мажорная версия PHP или nginx может приехать ночью. Security-ветка гораздо безопаснее и закрывает основную массу CVE.

apt install -y unattended-upgrades apt-listchanges

# включает периодические задания и создаёт 20auto-upgrades
dpkg-reconfigure --priority=low unattended-upgrades

# ключевые параметры в /etc/apt/apt.conf.d/50unattended-upgrades:
#   Unattended-Upgrade::Allowed-Origins — оставить только security-источник
#   Unattended-Upgrade::Mail "admin@example.com";
#   Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
#   Unattended-Upgrade::Automatic-Reboot "false";
#   Unattended-Upgrade::Automatic-Reboot-Time "04:00";

# сухой прогон: покажет, что именно установилось бы сейчас
unattended-upgrade --dry-run --debug

# проверяем, что таймеры активны и когда сработают
systemctl list-timers apt-daily.timer apt-daily-upgrade.timer

Обновление ядра требует перезагрузки, иначе патч не применён — вы работаете на старом ядре с уязвимостью. Заведите привычку смотреть /var/run/reboot-required и перезагружать сервер в согласованное окно. Справка по параметрам — в документации Debian.

Шаг 5. Hostname, время и NTP

Имя хоста участвует в логах, письмах и заголовках мониторинга. Ставится один раз, в FQDN-формате:

hostnamectl set-hostname web01.example.com

# в /etc/hosts должна быть строка с коротким и полным именем
# 127.0.1.1   web01.example.com web01
hostname -f

Время — недооценённый источник аварий. Перекос часов ломает проверку срока действия TLS-сертификатов, одноразовые коды TOTP, подписи запросов к API облаков и делает журналы бесполезными при разборе инцидента.

# часовой пояс: UTC для сервера удобнее, локальный — для отчётов
timedatectl set-timezone UTC

# статус синхронизации
timedatectl status

# для systemd-timesyncd
systemctl enable --now systemd-timesyncd
timedatectl show-timesync --all | head

# если используется chrony
chronyc tracking
chronyc sources -v
Расхождение часов даже в несколько минут даёт ошибки вида «сертификат ещё не действителен» у части клиентов и ломает двухфакторную авторизацию. Проверяйте синхронизацию сразу, а не когда пользователи начнут жаловаться.

Шаг 6. Swap, лимиты и лишние сервисы

Swap-файл на VPS с малой памятью

На тарифах с 1–2 ГБ памяти swap нужен не как «медленная память», а как подушка: без него ядро при пике убивает процесс через OOM killer, и падает обычно самый жирный — база данных или PHP-FPM. Со swap пик переживается замедлением, а не падением.

# swap уже есть?
swapon --show
free -h

# создаём файл (на ext4 достаточно fallocate; на XFS/btrfs — dd)
fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# закрепляем на перезагрузку
echo '/swapfile none swap sw 0 0' >> /etc/fstab

# уменьшаем агрессивность вытеснения
printf 'vm.swappiness=10\nvm.vfs_cache_pressure=50\n' > /etc/sysctl.d/99-swap.conf
sysctl --system

# проверка
swapon --show
cat /proc/sys/vm/swappiness

Ориентир по размеру: при 1–2 ГБ RAM берут swap примерно равный памяти, при 4–8 ГБ — половину, дальше 4 ГБ хватает почти всегда. На btrfs файл требует отдельной подготовки (без CoW), в контейнерной виртуализации собственный swap может быть недоступен — тогда единственный путь снизить риск OOM — тюнинг лимитов приложения.

Лимиты открытых файлов

Дефолтный лимит дескрипторов легко упирается на связке nginx + PHP-FPM + база под нагрузкой. Симптом — ошибки «too many open files» в логах при внешне свободных ресурсах.

# текущее значение для пользователя
ulimit -n

# для сессий пользователя: /etc/security/limits.d/90-nofile.conf
# *  soft  nofile  65535
# *  hard  nofile  65535

# для сервисов systemd лимиты берутся НЕ из limits.conf,
# а из юнита — правится через override
systemctl edit nginx
#   [Service]
#   LimitNOFILE=65535

systemctl show nginx -p LimitNOFILE

Что торчит наружу

Образы часто несут лишнее: почтовый демон, rpcbind, отладочные сервисы. Каждый слушающий порт — это поверхность атаки.

# кто слушает и от какого процесса
ss -tulpn

# список работающих сервисов
systemctl list-units --type=service --state=running

# отключить и удалить ненужное (пример)
systemctl disable --now rpcbind.socket rpcbind
apt purge -y rpcbind

# журнал не должен съедать диск
journalctl --disk-usage
journalctl --vacuum-time=14d
# постоянный лимит: SystemMaxUse=500M в /etc/systemd/journald.conf
Схема памяти VPS: оперативная память, swap-файл на диске и параметр swappiness, регулирующий вытеснение страниц
Swap не ускоряет сервер, но спасает от аварийного завершения процессов при пике

Шаг 7. Веб-стек, SSL, бэкапы и мониторинг — в этом порядке

Базовая часть закончена, сервер можно готовить под проект. Порядок установки имеет значение: каждый следующий слой опирается на предыдущий.

  1. Веб-сервер. nginx как фронт: TLS, статика, лимиты, проксирование. Конфигурация с нуля разобрана в руководстве по настройке nginx, security-часть — в материале про харденинг веб-сервера.
  2. Приложение. PHP-FPM, Node.js, Python-воркеры — отдельным пользователем, с сокетом на loopback, без прав записи в каталог с кодом там, где это возможно.
  3. База данных. Слушает только локальный интерфейс, отдельный пользователь на каждое приложение, пароль не в репозитории.
  4. SSL. Сертификат выпускается до продакшена, вместе с автопродлением и редиректом с HTTP. Пошагово — в статье про бесплатный сертификат Let's Encrypt.
  5. Бэкапы. Настраиваются ДО первого деплоя. Схема, проверка восстановления и хранение копий вне сервера — в руководстве по бэкапам сайта.
  6. Мониторинг. Включается в день запуска: доступность, срок сертификата, время ответа.
Бэкап, который ни разу не разворачивали, бэкапом не является. Проверьте восстановление на этом же чистом сервере, пока на нём нет боевых данных — второго такого удобного момента не будет.

Сводный чек-лист: шаг, команда, зачем и как проверить

ШагКоманда или файлЗачемКак убедиться, что применилось
Ресурсы и виртуализацияlscpu, free -h, df -hT, systemd-detect-virtСоответствие тарифу, ограничения контейнераВывод совпадает с описанием конфигурации
Пользователь с sudoadduser, usermod -aG sudoОтказ от постоянной работы под rootssh -t deploy@host 'sudo true' проходит
SSH-ключи/home/deploy/.ssh/authorized_keysВход без пароля, устойчивый к переборуВход без запроса пароля из нового окна
Отключение паролей/etc/ssh/sshd_config.d/10-hardening.confСнятие класса атак «брутфорс»sshd -t без ошибок; вход по паролю отклоняется
Пароль rootpasswd -l rootУчётка root не проходит по паролюpasswd -S root показывает статус L
Firewallufw allow OpenSSH, ufw enableНаружу открыто только нужноеufw status verbose, скан портов снаружи
fail2ban/etc/fail2ban/jail.d/sshd.localАвтобан источников перебораfail2ban-client status sshd
Обновленияapt full-upgradeЗакрытие известных уязвимостейapt list --upgradable пуст
Автопатчиunattended-upgradesSecurity-фиксы приезжают без участия человекаunattended-upgrade --dry-run --debug
Hostnamehostnamectl, /etc/hostsОсмысленные логи и письмаhostname -f даёт FQDN
Времяtimedatectl, chronyВалидность TLS, TOTP, корректные журналыtimedatectl status: synchronized = yes
Swap/swapfile, /etc/fstabЗащита от OOM killer на малой памятиswapon --show после перезагрузки
Лимитыlimits.d, LimitNOFILEНет ошибок «too many open files»systemctl show nginx -p LimitNOFILE
Лишние сервисыss -tulpn, apt purgeМинимальная поверхность атакиВ выводе только ожидаемые порты
Журналыjournald.conf, logrotateДиск не забивается логамиjournalctl --disk-usage в пределах лимита
SSL и бэкапыACME-клиент, скрипт копийHTTPS и восстановимость с первого дняТестовое восстановление прошло

Как проверить настройку снаружи

Внутренние команды показывают намерение, внешняя проверка — факт. После перезагрузки сервера прогоните его по внешнему контуру:

Схема порядка запуска: веб-сервер, приложение, база данных, затем сертификат, бэкапы и мониторинг доступности
Каждый слой опирается на предыдущий: SSL и бэкапы — не «после запуска», а часть запуска

Типовые ошибки первого часа

  • Включить ufw до разрешения SSH. Классика. Спасает только консоль провайдера.
  • Отключить пароли, не проверив ключ. Проверка делается из второго окна до закрытия первого.
  • Оставить базу на 0.0.0.0. Даже с паролем это приглашение: боты перебирают учётки MySQL и Redis круглосуточно.
  • Забыть про перезагрузку после обновления ядра. Патч установлен, но не применён.
  • Настроить бэкапы «после запуска». Первая же ошибка миграции приходится на период без копий.
  • Складывать бэкапы на тот же диск. Отказ тома уносит и данные, и копии.
  • Ставить панель поверх ручных конфигов. Панель перезапишет nginx и правила firewall, причём молча.

Частые вопросы

Сколько времени реально занимает первичная настройка VPS?

Пункты 0–6 из этого чек-листа — 20–40 минут при наличии готового SSH-ключа. Установка веб-стека, выпуск сертификата и настройка бэкапов добавляют ещё 1–2 часа. Если делаете это регулярно, шаги оформляются в скрипт или Ansible-роль и укладываются в несколько минут.

Нужен ли swap, если памяти достаточно?

Да, небольшой файл полезен даже при запасе: он позволяет ядру вытеснять неиспользуемые страницы и переживать краткие пики без OOM killer. Смысл теряется только при очень агрессивных требованиях к задержкам, где вытеснение недопустимо.

Стоит ли менять SSH-порт с 22?

Это не мера безопасности, а мера снижения шума: массовые сканеры стучатся на 22, и логи чище на нестандартном порту. Целевую атаку смена порта не остановит. Безопасность даёт связка «только ключи + fail2ban + firewall».

Root или sudo — принципиальна ли разница на одиночном сервере?

Да. Отдельный пользователь даёт журналируемость действий, защиту от случайного разрушительного вызова и возможность отозвать доступ одному человеку, не меняя общий пароль. Плюс sshd можно оставить с PermitRootLogin prohibit-password и снять целый класс попыток входа.

Можно ли ставить панель управления после ручной настройки?

Технически да, практически — источник конфликтов: панели переписывают конфигурации веб-сервера, правила firewall и задания cron под себя. Выбирайте один подход: либо панель с самого начала на чистой системе, либо ручное управление.

Как понять, что сервер настроен корректно, а не «вроде работает»?

По внешним признакам: сканирование показывает только ожидаемые порты, сертификат валиден с полной цепочкой, security-заголовки на месте, мониторинг видит сервер, а восстановление из бэкапа реально проверено. Всё остальное — предположения.

Чек-лист перед первым деплоем

  • Выбран LTS-дистрибутив, версия зафиксирована в документации проекта.
  • Проверены ресурсы, тип виртуализации и свободное место на диске.
  • Создан пользователь с sudo, вход по ключу проверен из отдельной сессии.
  • Парольная аутентификация отключена, пароль root заблокирован, sshd -t чист.
  • Включён firewall с политикой deny incoming; открыты только SSH, 80 и 443.
  • Работает fail2ban, jail для SSH активен.
  • Система полностью обновлена, unattended-upgrades ставит security-патчи.
  • Заданы hostname в FQDN, часовой пояс, синхронизация времени подтверждена.
  • Настроен swap и swappiness, лимиты дескрипторов подняты для сервисов.
  • Удалены лишние сервисы; ss -tulpn не содержит сюрпризов.
  • Ограничен размер журналов, logrotate работает.
  • Установлен веб-стек, выпущен сертификат, включён редирект на HTTPS.
  • Бэкапы настроены и один раз восстановлены до заливки боевых данных.
  • Подключён мониторинг доступности и срока действия сертификата.
  • Внешние проверки портов, SSL, заголовков и скорости пройдены после перезагрузки.

Проверьте ваш сайт прямо сейчас

Следить за своим сервером →
Другие статьи: Инфраструктура
Инфраструктура
Почта на своём домене: Яндекс 360, VK WorkSpace или свой сервер — настройка, отправка с сайта и переезд
21.07.2026 · 306 просм.
Инфраструктура
Алгоритмы балансировки нагрузки: Round Robin, Least Connections и другие
16.03.2026 · 268 просм.
Инфраструктура
Стратегии версионирования API: URL, заголовки и параметры запроса
16.03.2026 · 266 просм.
Инфраструктура
Rate Limiting в API: зачем и как настроить
14.03.2026 · 259 просм.