RE:NODE

VDS12 мин чтения

Первый час на новом VDS: чек-лист настройки

Что сделать на свежем VDS: обновления, пользователь с sudo, ключи SSH, файрвол с запретом по умолчанию, время, swap и автоматические обновления безопасности.

1 прочтений

Свежий VDS - это машина с root-доступом, публичным адресом и без собственного мнения. Через считаные минуты после запуска автоматические сканеры начнут подбирать пароли на порту 22, а всё, что вы делаете дальше, предполагает основу, в которой стоят обновления, есть пользователь, не являющийся root, и отвечают только те порты, которые выбрали вы. На эту основу уходит около двадцати минут. Час в заголовке потому, что вы должны читать то, что набираете, и потому, что спешка на этом этапе - способ пересобирать машину через две недели.

Порядок ниже важен. Обновления идут перед настройкой, потому что пакеты, которые вы собираетесь настраивать, как раз и заменяются. Пользователь идёт перед закрытием SSH, потому что запереть root, не имея другого входа, - классический способ потерять сервер в первый же день. Файрвол идёт после SSH, потому что правило «запретить всё по умолчанию» без исключения для порта 22 обрывает сессию и заканчивает разговор.

Команды рассчитаны на Debian и Ubuntu - на них основана большая часть образов VDS. В системах семейства RHEL подставьте dnf вместо apt, wheel вместо sudo и firewalld вместо ufw; суть не меняется.

Первый вход и что проверить#

Вам пришлёт адрес и либо пароль root, либо ключ. Войдите и прочитайте запрос про отпечаток, а не набирайте yes рефлекторно: это единственный шанс убедиться, что вы говорите со своей машиной. Сравните его с отпечатком в консоли вашего провайдера, если тот его публикует.

bash
$ ssh root@203.0.113.10The authenticity of host '203.0.113.10' can't be established.ED25519 key fingerprint is SHA256:5xM8n...Are you sure you want to continue connecting (yes/no/[fingerprint])?

Затем потратьте две минуты на то, чтобы выяснить, что у вас на самом деле есть. Сделать это стоит до установки чего бы то ни было, потому что это единственный момент, когда машина в известном состоянии:

bash
$ cat /etc/os-release          # distribution and version$ uname -r                     # kernel$ lscpu | head -20             # cores, model, virtualisation flags$ free -h                      # memory, and whether swap exists$ df -h /                      # disk, and how much the image used$ ip -brief address            # addresses, v4 and v6$ ss -ltnp                     # what is already listening$ systemd-detect-virt          # kvm, lxc, none

Интереснее всего ss -ltnp. Чистый образ обычно показывает только sshd, а иногда ещё DHCP-клиент или агент передачи почты, слушающий на localhost. Всё остальное, слушающее на 0.0.0.0, - то, о чём вы не просили и в чём стоит разобраться. systemd-detect-virt сообщает, полная ли у вас виртуализация или вы делите ядро, а от этого зависит, возможны ли некоторые дальнейшие шаги вообще; почему это различие важнее маркетинга, объяснено в статье VPS, VDS или выделенный сервер.

Если пароль root пришёл по почте, считайте его уже публичным и планируйте полностью отключить вход по паролю в ближайшие двадцать минут. Это четвёртый шаг.

Обновите всё и перезагрузитесь#

Образ - это снимок на момент сборки, а это может быть и несколько месяцев назад. Прежде всего:

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

full-upgrade, а не upgrade, потому что upgrade отказывается удалять пакеты и поэтому тихо пропускает обновления, требующие смены зависимостей. На свежем образе эта разница обычно - ядро.

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

bash
$ [ -f /var/run/reboot-required ] && cat /var/run/reboot-required$ reboot

Обновление ядра ничего не значит, пока машина не перезапустится на новом. Совершенно новый VDS, на котором ничего не запущено, - самая дешёвая перезагрузка в вашей жизни, так что сделайте её. Войдите снова и убедитесь через uname -r, что версия сменилась.

Пользователь, который не root#

Работать целый день под root - значит выполнять каждую опечатку с полными правами, а каждый запущенный процесс наследует их. Создайте обычную учётную запись с возможностью повышать права осознанно:

bash
$ adduser deploy$ usermod -aG sudo deploy

adduser - интерактивная обёртка Debian: она создаёт домашнюю директорию, задаёт оболочку и запрашивает пароль. Задайте настоящий пароль, даже если собираетесь входить по ключам, потому что sudo его спросит.

Теперь дайте этому пользователю свой ключ SSH. Проще всего и надёжнее, если у root уже установлен ваш ключ, скопировать директорию целиком с исправлением владельца за один шаг:

bash
$ rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy/$ chmod 700 /home/deploy/.ssh$ chmod 600 /home/deploy/.ssh/authorized_keys

Эти права - не украшение. sshd отказывается использовать файл authorized_keys, доступный для записи кому-либо, кроме владельца, и делает это молча с точки зрения клиента, отчего и возникает загадка «он всё время просит пароль».

Откройте второй терминал и проверьте, прежде чем менять что-либо ещё:

bash
$ ssh deploy@203.0.113.10$ sudo -v

Держите эту вторую сессию открытой до конца статьи. Если изменение конфигурации сломает вход, вас спасёт уже открытая сессия.

Ключи SSH и закрытие парадной двери#

Если пары ключей у вас ещё нет, создайте её на своей машине, а не на сервере:

bash
$ ssh-keygen -t ed25519 -C "deploy@laptop"$ ssh-copy-id deploy@203.0.113.10

Используйте ed25519. Он меньше и быстрее RSA, а его поддерживает каждая реализация SSH за последнее десятилетие. Задайте закрытому ключу парольную фразу и пусть агент держит его разблокированным на рабочий день.

Затем отключите две вещи, которые делают сервер угадываемым. В современных Debian и Ubuntu /etc/ssh/sshd_config начинается со строки Include /etc/ssh/sshd_config.d/*.conf, и на этой детали спотыкаются почти все: sshd использует первое полученное значение ключевого слова, поэтому всё из этой директории главнее основного файла, лежащего ниже. Облачные образы нередко поставляют там файл, который снова включает вход по паролю.

bash
$ ls -la /etc/ssh/sshd_config.d/$ grep -r PasswordAuthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/

Напишите собственный файл с именем, которое сортируется раньше всего, что там уже лежит:

/etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin noPasswordAuthentication noKbdInteractiveAuthentication noPubkeyAuthentication yesAuthenticationMethods publickeyMaxAuthTries 3LoginGraceTime 20AllowUsers deploy

Проверьте синтаксис перед перезапуском, потому что плохой файл конфигурации означает, что sshd не поднимется:

bash
$ sshd -t && systemctl restart ssh

Теперь из третьего терминала докажите, что новый вход по-прежнему работает, а вход по паролю отклоняется. И только потом закройте сессию root.

Ключи SSH и защита разбирают остальное как следует: агенты, jump-хосты, ограничения на отдельные ключи и что делать, когда вы всё-таки заперли себя.

Файрвол: запрет по умолчанию#

Запретить входящие по умолчанию, разрешить исходящие, затем открыть ровно то, что нужно. В Ubuntu для этого ufw, и порядок команд имеет огромное значение:

bash
$ ufw default deny incoming$ ufw default allow outgoing$ ufw allow OpenSSH$ ufw enable$ ufw status numbered

ufw allow OpenSSH перед ufw enable - всегда. Включение политики «запретить всё» без правила для SSH сразу разрывает соединение, и вернуться можно только через консоль провайдера. ufw предупреждает, но предупреждение легко проскочить.

Затем службы, которые вы действительно собираетесь запускать:

bash
$ ufw allow 80/tcp$ ufw allow 443/tcp$ ufw allow 27015:27020/udp      # a range for game servers$ ufw allow from 10.0.0.0/24 to any port 5432 proto tcp

Последнюю форму стоит выучить. База данных, endpoint метрик или админ-панель должны быть доступны с названных адресов, а не отовсюду. Рассуждения - в статье правила файрвола, которые важны, а синтаксис полностью - в руководстве по ufw.

Одна ловушка: Docker публикует порты, записывая собственные правила iptables, и они полностью обходят правила ufw. Контейнер, запущенный с -p 5432:5432, открыт в интернет, даже если ufw status выглядит аккуратно. Либо привяжите публикацию к localhost через -p 127.0.0.1:5432:5432, либо добавьте свои правила в цепочку DOCKER-USER. В контексте это разобрано в статье Docker на VDS.

Время, имя хоста и мелкие настройки#

Неверные часы дают неверные логи, проваленные рукопожатия TLS и просроченные токены, и они незаметны, пока не станут заметны.

bash
$ timedatectl set-timezone Etc/UTC$ timedatectl set-ntp true$ timedatectl

Используйте UTC на серверах. Рано или поздно вы будете сопоставлять лог этой машины с логом другой, и вариант этой работы, где всё уже в UTC, - приятный вариант.

Дайте машине осмысленное имя, особенно если появится вторая:

bash
$ hostnamectl set-hostname web-01

Добавьте это имя в /etc/hosts рядом с 127.0.1.1, иначе sudo будет секунду зависать на каждой команде, пытаясь разрешить имя хоста и не справляясь.

Ещё две мелочи, которые стоит сделать, пока вы здесь. Задайте локаль (update-locale LANG=en_GB.UTF-8), чтобы скриптовые утилиты перестали печатать предупреждения о ней, и ограничьте журнал, чтобы логи не могли заполнить диск:

/etc/systemd/journald.conf
[Journal]SystemMaxUse=500MSystemMaxFileSize=50M

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

Автоматические обновления безопасности#

Сервер, который никто не обновляет, рано или поздно взломают. Автоматические обновления безопасности - самые ценные двадцать секунд в этом списке.

bash
$ apt install unattended-upgrades$ dpkg-reconfigure --priority=low unattended-upgrades

Это записывает /etc/apt/apt.conf.d/20auto-upgrades. Затем откройте /etc/apt/apt.conf.d/50unattended-upgrades и решите две вещи: может ли машина перезагружаться сама и когда.

/etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Automatic-Reboot "true";Unattended-Upgrade::Automatic-Reboot-WithUsers "false";Unattended-Upgrade::Automatic-Reboot-Time "04:00";Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";

Автоматические перезагрузки подходят веб-серверу и не подходят игровому серверу, на котором в четыре утра сидят люди. Если вы их отключите, вы взяли на себя работу перезагружаться после обновлений ядра самостоятельно, а проверять нужно /var/run/reboot-required. Убедитесь, что всё работает, а не предполагайте:

bash
$ unattended-upgrade --dry-run --debug$ cat /var/log/unattended-upgrades/unattended-upgrades.log

По умолчанию применяются только обновления безопасности, и это правильный охват. Расширение на все обновления на боевой машине меняет небольшой риск взлома на больший риск того, что пакет изменит поведение, пока вы спите.

Swap и потолок памяти#

Большинство небольших образов VDS поставляются вообще без swap. Без него всплеск памяти не замедляет, а убивает что-то: убийца нехватки памяти в ядре выбирает самый большой процесс, а это обычно именно то, ради чего вы держите сервер.

Небольшой файл подкачки - страховка, а не дополнительная память. Двух гигабайт достаточно на машине с 8 ГБ.

bash
$ fallocate -l 2G /swapfile || dd if=/dev/zero of=/swapfile bs=1M count=2048$ chmod 600 /swapfile$ mkswap /swapfile$ swapon /swapfile$ swapon --show

Чтобы он пережил перезагрузку, добавьте одну строку в /etc/fstab:

/etc/fstab
/swapfile none swap sw 0 0

Затем снизьте готовность ядра его использовать, чтобы он оставался страховочной сеткой, а не становился обычным состоянием:

bash
$ echo 'vm.swappiness=10' > /etc/sysctl.d/99-swap.conf$ sysctl --system

fallocate не работает на некоторых файловых системах, поэтому и предусмотрен запасной вариант с dd. А если сервер действительно использует swap в обычной работе, дело не в swap: машина слишком мала или что-то течёт. Как читать улики - в статье swap в Linux и OOM killer, а чего вам на самом деле не хватает - в статье CPU или RAM для игровых серверов.

Что может подождать до второго часа#

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

ДальшеЗачем
Backup или снимок, сделанный сейчасЧистая основа ничего не стоит и потом очень пригодится
fail2banПовторные неудачи начинают чего-то стоить атакующему
Обратный прокси и TLSВсему, что отдаёт HTTP, нужен nginx и сертификат
Юниты systemd для ваших службПерезапуск при сбое, запуск при загрузке, логи в одном месте
МониторингДиск, память и то, отвечает ли сервис вообще
Docker или ComposeТолько если нагрузка действительно состоит из нескольких служб

Каждый из этих пунктов подробно разобран в статьях fail2ban, службы systemd для ваших приложений и nginx как обратный прокси. Если вы планируете несколько игровых серверов на одной машине, статья несколько игровых серверов на одном VDS описывает порты, пользователей и надзор за процессами, пока вы не запутались.

Чего не делать в первый час: ставить панель управления, по которой вы ещё не приняли решения, открывать порты под службы, которых ещё нет, или следовать руководству по защите, которое меняет сорок значений sysctl, объяснить которые вы не можете. Каждое изменение, которое вы не можете объяснить, - изменение, которое вы не догадаетесь откатить, когда что-то сломается.

VDS - это машина, которой вы владеете целиком, включая обслуживание. Если этот список читается как работа, которой вы не хотели бы заниматься каждый месяц, честное сравнение есть в статье VDS или игровая панель, и ответ у разных людей действительно разный.

FAQ#

Какой дистрибутив выбрать?

Любой релиз с долгосрочной поддержкой, который вы уже знаете. Ubuntu LTS и Debian stable получают обновления безопасности годами, о них написано больше всего точной документации, и именно их подразумевает большинство инструкций по установке. Более новый релиз с коротким сроком жизни даёт версии пакетов, которые вам, скорее всего, не нужны, в обмен на обновление каждые девять месяцев.

Нужен ли мне пользователь без root, если машиной пользуюсь только я?

Да, и причина не в других людях. Работа под root делает каждую ошибку максимальной, каждый скомпрометированный процесс - процессом root, а каждую скопированную из интернета команду - командой root. Осознанный набор sudo - полусекундная пауза перед разрушительными.

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

Это убирает большую часть шума из логов аутентификации, и настоящие события становятся заметнее. Безопасности против того, кто целится именно в вас, это не добавляет: сканирование портов находит новый порт за секунды. Сделайте это ради тихих логов, если хотите, но никогда - вместо ключей и файрвола.

Стоит ли сразу ставить fail2ban?

Он полезен и вторичен. При отключённой аутентификации по паролю подбор пароля к SSH не может удаться, сколько бы попыток ни было, так что fail2ban здесь в основном экономит объём логов. Своё место он оправдывает перед веб-формами входа, почтой и всем остальным, что всё ещё принимает пароль.

Сколько swap добавить?

Столько, чтобы поглотить всплеск, но не столько, чтобы скрыть проблему. Один-два гигабайта на машине с 8 ГБ и больше, и низкий vm.swappiness. Правило, по которому серверам нужен swap пропорционально памяти, родом из эпохи гораздо более маленьких машин и гибернации.

Какой шаг чаще всего пропускают и жалеют?

Проверку второго входа до закрытия первой сессии. Каждая история о блокировке начинается с того, что кто-то перезапускает sshd после изменения конфигурации, закрывает терминал и обнаруживает, что в AllowUsers была опечатка. Держите рабочую сессию открытой, пока не удастся новая.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000