Короткий ответ: чтобы подготовить Ubuntu 24.04 на VPS с нуля, зайдите по SSH, обновите пакеты, создайте пользователя с sudo, войдите по SSH-ключу, отключите парольный вход и root, откройте в UFW только порты 22, 80 и 443, поставьте часовой пояс Europe/Moscow и проверьте систему командой lsb_release -a. На чистом сервере это занимает 15–25 минут, если не закрыть себе SSH.
Что понадобится
Гайд рассчитан на чистый VPS с Ubuntu 24.04 LTS (кодовое имя noble). Так отдают большинство панелей в 2026 году. Если на машине уже крутится чужой стек — не копируйте команды «отключить root» вслепую: сначала убедитесь, что у вас есть второй вход.
- IP сервера и доступ из панели хостинга (пароль root или готовый ключ);
- локальный компьютер с клиентом SSH (OpenSSH в Linux/macOS, Windows Terminal);
- ваш публичный ключ Ed25519 либо возможность сгенерировать пару;
- 15–25 минут и второе окно терминала — им проверяете вход, пока первое ещё открыто.
Официальная документация серверной Ubuntu: documentation.ubuntu.com/server. После этой статьи логичный следующий шаг — установка mise, чтобы не ставить Node, Java и Python из устаревших пакетов apt.
Шаг 1. Подключаемся по SSH
С панели хостинга обычно дают пользователя root и пароль. Подключение:
ssh root@IP_СЕРВЕРА
Если порт не 22 (редко, но бывает), добавьте -p. Пароль при вводе не отображается — это нормально. Если провайдер сразу выдал пользователя ubuntu с ключом, работайте им и пропускайте создание «ещё одного ubuntu»: вам нужен один sudo-пользователь, не два одинаковых.
Проверка: вы в шелле, приглашение похоже на root@hostname:~#. Сразу посмотрите, что это действительно 24.04:
lsb_release -a
uname -r
whoami
В lsb_release -a должны быть Ubuntu, Release 24.04 и Codename noble. Если там 22.04 или Debian — этот гайд не копируйте как есть: имена служб SSH и набор пакетов другие.
Шаг 2. Обновляем систему
На свежем VPS индекс пакетов почти всегда устарел. Сначала индекс, потом пакеты:
export DEBIAN_FRONTEND=noninteractive
apt update
apt -y upgrade
Если ядро или glibc обновились, Ubuntu оставляет флаг перезагрузки. Проверьте и при необходимости перезагрузитесь:
test -f /var/run/reboot-required && echo 'нужен reboot'
reboot
После reboot снова зайдите по SSH и повторите lsb_release -a. Не ставьте на этом шаге nginx, docker, nodejs и java «на всякий случай»: лишние пакеты — лишняя поверхность. Node.js из apt на Ubuntu 24.04 — это 18.19.1, уже EOL; Java и рантаймы ставьте через mise в следующей статье.
Проверка: apt update больше не предлагает сотни обновлений, команда завершается без ошибок о битых репозиториях.
Шаг 3. Создаём sudo-пользователя
Работать постоянно под root неудобно и опасно: любая опечатка в rm или в юните systemd бьёт по всей системе. Создайте отдельного пользователя — в примере deploy, имя может быть вашим:
adduser deploy
usermod -aG sudo deploy
id deploy
adduser спросит пароль и служебные поля; поля GECOS можно оставить пустыми. id deploy должен показать группы deploy и sudo.
Проверка прав sudo не выходя из текущего root-сеанса:
su - deploy
sudo -v
exit
После sudo -v система спросит пароль пользователя deploy. Если пишет, что deploy не в sudoers — вы забыли usermod -aG sudo или не перелогинились в su —.
Шаг 4. Вход по SSH-ключу
Пароль по сети можно перебрать. Ключ Ed25519 — короткий и достаточный вариант. На локальной машине, не на сервере:
ls -l ~/.ssh/id_ed25519.pub
ssh-keygen -t ed25519 -C "vps"
Если публичный ключ уже есть, вторую пару не плодите без нужды. Скопируйте ключ на сервер. Пока пароль root ещё работает:
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@IP_СЕРВЕРА
Если ssh-copy-id нет, на сервере под root:
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
nano /home/deploy/.ssh/authorized_keys
Вставьте одну строку публичного ключа (начинается с ssh-ed25519), сохраните, затем:
chown deploy:deploy /home/deploy/.ssh/authorized_keys
chmod 600 /home/deploy/.ssh/authorized_keys
ls -la /home/deploy/.ssh
Каталог должен быть 700, файл ключей — 600, владелец — deploy. Иначе sshd молча отвергнет ключ.
Критичная проверка: откройте второе окно и войдите не закрывая текущую root-сессию:
ssh -v deploy@IP_СЕРВЕРА
Должны попасть без пароля пользователя (passphrase ключа — другое дело, она локальная). Сразу проверьте sudo:
sudo whoami
Ответ — root. Только после этого переходите к отключению паролей. Если ключ не принят, смотрите /var/log/auth.log и права на .ssh; не отключайте пароль «чтобы потом разобраться».
Шаг 5. Отключаем парольный вход и root
На Ubuntu 24.04 настройки sshd часто лежат не только в /etc/ssh/sshd_config, но и в drop-in каталоге. Cloud-init на многих VPS прописывает PasswordAuthentication в отдельном файле, и правка основного конфига ничего не меняет. Сначала посмотрите, что реально действует:
grep -R "PasswordAuthentication\|PermitRootLogin\|KbdInteractiveAuthentication" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/
Создайте свой drop-in — так его не затрёт пакетный апдейт ssh:
cat <<'EOF' | sudo tee /etc/ssh/sshd_config.d/99-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
EOF
sudo sshd -t
sudo systemctl reload ssh
На Ubuntu 24.04 служба называется ssh, не «sshd». sshd -t должен промолчать: это проверка синтаксиса до reload.
Проверка во втором окне:
- новый вход ssh deploy@IP по ключу — успех;
- ssh root@IP — отказ;
- ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no deploy@IP — отказ.
Первое окно не закрывайте, пока второе не подтвердило вход. Если reload отрезал вас в новом окне — в старом верните PasswordAuthentication yes, снова sshd -t и systemctl reload ssh, затем чините ключ.
Шаг 6. UFW: только 22, 80 и 443
UFW — обёртка над nftables, она уже есть в Ubuntu 24.04. Политика: входящие запрещены, исходящие разрешены, явно открыты SSH и веб. Не открывайте 3306, 5432, 6379, 27017, 8080, 3000, 9090 «на будущее». База и приложение слушают localhost; наружу — только SSH и то, что терминирует nginx.
| Порт | Зачем | Открывать сейчас |
|---|---|---|
| 22/tcp | SSH | да, иначе отвалите себя |
| 80/tcp | HTTP и выпуск сертификата | да, даже если сайта ещё нет |
| 443/tcp | HTTPS | да |
| 3306, 5432 | MySQL / PostgreSQL | нет |
| 6379 | Redis | нет |
| 3000, 8080 | Node/Java «как есть» | нет, только 127.0.0.1 |
Порядок важен: сначала правило для SSH, потом enable.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
На вопрос «Proceed with operation» ответьте y. В status должны быть 22, 80, 443 (и их v6-пары, если IPv6 включён). Профиль OpenSSH надёжнее сырого «22»: если когда-нибудь смените порт в sshd, профиль нужно будет обновить отдельно — в этом гайде порт не меняем.
Проверка: текущая SSH-сессия жива, новое подключение из второго окна проходит. Если сессия зависла сразу после enable — вы не добавили OpenSSH. Восстановление только через VNC/консоль в панели хостинга: ufw allow OpenSSH && ufw reload.
Файл /etc/default/ufw по умолчанию содержит IPV6=yes. Не ставьте no, если у домена есть AAAA: пакеты придут на IPv6, а фильтр их отбросит. Либо настройте IPv6 нормально, либо не публикуйте AAAA, пока не готовы.
Шаг 7. Часовой пояс Europe/Moscow
Логи cron, Let’s Encrypt и systemd-таймеры должны совпадать с вашими. Для России в этом гайде — Europe/Moscow:
sudo timedatectl set-timezone Europe/Moscow
timedatectl
В выводе: Time zone: Europe/Moscow. RTC обычно в UTC — так и должно быть, системные часы при этом локальные. Дата в date должна совпадать с Москвой, а не с UTC и не с Europe/London, который часто стоит у европейских датацентров.
Fail2ban — по желанию
Fail2ban банит IP после серии неудачных попыток SSH. На ключе без пароля пользы меньше, но боты всё равно стучатся. Кратко:
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
На Ubuntu пакет включает jail sshd через debian-defaults. Не открывайте ради fail2ban лишние порты и не копируйте чужие jail с bantime = -1 в первый день: ошибка в фильтре может забанить вас. Если status sshd видит jail — достаточно.
Проверка, что сервер готов
Пройдитесь по списку под тем пользователем, с которым будете жить дальше:
lsb_release -a
whoami
sudo -n true && echo sudo_ok
timedatectl | grep 'Time zone'
sudo ufw status verbose
systemctl is-active ssh
ss -tlnp | grep -E ':22|:80|:443'
Ожидание: noble / 24.04, обычный пользователь (не root), sudo_ok, Europe/Moscow, UFW active с 22/80/443, ssh active. Слушающий 80/443 на этом этапе может отсутствовать — это нормально, правила файрвола уже есть. Дальше ставьте рантаймы через mise на Ubuntu 24.04, а не через apt.
Частые ошибки
- UFW enable без порта 22. Симптом: SSH замирает, консоль панели — единственный вход. Лечение: в VNC выполнить ufw allow OpenSSH. Правило OpenSSH всегда раньше enable.
- AAAA в DNS при неготовом IPv6. Браузер берёт IPv6, сайт «не открывается», с телефона на IPv4 всё живо. Либо слушайте [::] и держите UFW с IPV6=yes, либо уберите AAAA, пока не настроите. Не отключайте IPv6 в sysctl «чтобы заработало», если AAAA уже раздана.
- PasswordAuthentication правили не там. Cloud-init оставил drop-in с yes — парольный root жив. Смотрите весь /etc/ssh/sshd_config.d/, проверяйте новым сеансом, не ssh -v в том же окне.
- Права на .ssh. Каталог 755 или ключ 644 — sshd игнорирует authorized_keys. Только 700/600 и владелец пользователя.
- apt install nodejs «чтобы уже было». В Ubuntu 24.04 это Node 18.19.1 EOL. Не ставьте. Рантаймы — через mise.
FAQ
Можно ли оставить вход root только по ключу?
Технически да: PermitRootLogin prohibit-password. Для учебного VPS надёжнее PermitRootLogin no и sudo-пользователь. Тогда скомпрометированный ключ root не существует, а sudo даёт след в auth.log.
Что будет, если включить UFW и забыть SSH?
Новые подключения на 22 отбрасываются. Старая сессия иногда живёт, пока вы её не закроете. Не закрывайте её: добавьте OpenSSH и ufw reload. Если сессии уже нет — только консоль хостинга.
Нужно ли открывать 3306 или 5432, если база на этом же VPS?
Нет. MySQL и PostgreSQL должны слушать 127.0.0.1. Открытый 3306 в интернет — типичный путь к брутфорсу. Клиенту с ноутбука нужен SSH-туннель, а не дырка в UFW.
Почему с телефона сайт не открывается, а с ПК открывается?
Частый расклад: у домена есть AAAA, оператор даёт чистый IPv6, а nginx/UFW принимают только IPv4. Проверьте AAAA и ufw status verbose на строки v6. Пока IPv6 не настроен, не публикуйте AAAA.
Какое имя пользователя создавать — ubuntu или своё?
Если образ уже дал ubuntu с ключом в sudo — используйте его. Если заходите под root — создайте своего (deploy или имя). Не плодите двух админов «на всякий случай» без понимания, чей ключ куда прописан.