Что ваш провайдер может увидеть на самом деле
Начнём с физики, а не с политики, потому что политика может измениться, а физика — нет. На виртуальной машине образ диска живёт на железе, которое в стойку поставил кто-то другой. Если этот образ не зашифрован, его может прочитать любой, кто в итоге получит доступ к хранилищу: оператор с доступом к гипервизору, техник, меняющий вышедший из строя NVMe-накопитель в паре RAID-1, тот, кому в конце концов достанется этот диск при списании, и — тот случай, который на самом деле всех интересует, — любой, кто явится с обязывающим решением суда, обладающего юрисдикцией над этой машиной. Ничего из этого не требует злого умысла или бэкдора. Незашифрованный том — это просто файл, а файлы можно скопировать.
Второй уровень — это память. Наши тарифы VPS работают на KVM full virtualization, то есть вы запускаете собственное ядро, а не делите его с кем-то, — но оперативная память, которую вам выделяют, всё равно принадлежит гипервизору, а любой гипервизор технически способен на интроспекцию гостевой системы. Третий уровень — всё, что вообще никогда не касается диска: трафик, покидающий ваш сетевой интерфейс, метаданные, которые генерирует ваше приложение, DNS-запросы, которые вы разрешаете. На стороне аккаунта мы намеренно храним очень немного — хеш пароля argon2id, ваш баланс и журнал операций по нему, спецификации заказов и логи доступа, ротируемые через 14 дней, и нигде среди этого нет ни имени, ни адреса, ни номера телефона, ни карты, как указано на странице политики no-KYC. Не хранить ничего о вас — это не то же самое, что быть неспособным прочитать ваш диск, и только одну из этих двух гарантий вы можете обеспечить себе сами.
SP·02Что исправляет полнодисковое шифрование, а что нет
Полнодисковое шифрование — это мера защиты данных в состоянии покоя. Она полностью покрывает описанные выше сценарии, в которых том меняет владельца, пока машина выключена, или копия снимается в офлайне: списанный или отправленный по RMA диск, образ диска, том, клонированный на уровне хранилища, холодный снапшот, снятый у вас из-под носа. В каждом из этих случаев зашифрованный контейнер LUKS — это непрозрачный набор байт, и тому, кто им завладел, нужна парольная фраза, которая существовала только у вас в голове или на ноутбуке. Это реальная, жёсткая граница, и это самое крупное улучшение, которое большинство людей может внести в защиту арендованного сервера.
Не менее важно прямо сказать и о другой половине. У работающего сервера ключ находится в оперативной памяти — именно поэтому файловая система читаема для ваших собственных процессов, — поэтому шифрование никак не помогает против компрометации root в реальном времени, враждебного процесса внутри гостевой системы, дампа памяти, снятого, пока машина работает, или гипервизора, делающего интроспекцию этой памяти. Оно не шифрует то, что уходит через сетевой порт, и не поможет, если ваше приложение пишет секреты в лог, который вы потом отправляете куда-то ещё. Если ваша модель угроз действительно исключает интроспекцию гипервизора, честный ответ — не более сильный шифр, а выделенное оборудование от $66.00/мес, где над вами вообще нет никакого гипервизора. Для всего, что менее серьёзно, шифрование в состоянии покоя и провайдер, который почти ничего не хранит, вместе покрывают реалистичные сценарии — используемые здесь термины определены в глоссарии.
SP·03Зашифрованный том данных или зашифрованный root?
Есть два подхода, и они подходят для разных ситуаций. Первый — это зашифрованный том данных: операционная система остаётся в открытом виде, а всё, что действительно важно, — состояние приложения, база данных, хранилище документов, ваши ключи — кладётся в контейнер LUKS, смонтированный по выбранному вами пути. Его можно установить на машину, которая уже в проде, он никогда не блокирует перезагрузку и защищает именно тот материал, который кому-то действительно нужен. Читаемой при этом остаётся форма системы: список пакетов, юниты systemd, vhost'ы nginx, история команд шелла, логи.
Второй подход — это зашифрованный root, где внутри контейнера находится всё, кроме небольшого загрузочного раздела. Когда машина выключена, о ней нельзя прочитать вообще ничего — именно этот результат представляют себе большинство людей, когда говорят, что хотят зашифрованный сервер. Цену за это платят при каждой загрузке: перезагрузка намертво останавливается на запросе парольной фразы, на консоли, которую вы не видите, — пока вы не дадите машине способ спросить вас об этом удалённо. Именно ради этого существует следующий раздел. Эмпирическое правило такое: шифруйте root, когда собираете машину с нуля и можете протестировать её, прежде чем она понесёт какую-либо нагрузку; шифруйте том данных, когда машина уже существует, а простой обходится дорого. Конвертация живого root на месте с помощью cryptsetup reencrypt возможна в LUKS2, но мы не рекомендовали бы делать это с продакшен-сервером, который вы не сможете пересобрать.
Удалённая разблокировка: крошечный SSH-сервер в initramfs
Приём, который делает зашифрованный root практичным на удалённой машине, — это dropbear-initramfs. initramfs — это миниатюрная система, которую ядро распаковывает до того, как появляется настоящий root; поскольку на KVM VPS ядро принадлежит вам, внутрь можно поместить совсем небольшой SSH-демон. При загрузке машина поднимает сетевой интерфейс, запускает этот демон и ждёт. Вы подключаетесь, выполняете одну команду, парольная фраза разблокирует контейнер, загрузка продолжается уже в настоящей системе, а крошечный демон исчезает. Со стороны это выглядит как сервер, которому нужны лишние тридцать секунд и одно осознанное действие, чтобы вернуться в строй.
Почти всю боль причиняют две детали. Первая — у SSH-сервера в initramfs есть собственный хост-ключ, отличный от того, что настоящая работающая система предъявляет на том же адресе, — так что если оставить его на порту 22, ваш клиент будет каждый раз отказываться от второго подключения из-за несовпадения хост-ключа. Дайте ему отдельный порт и отдельный файл known_hosts, и проблема исчезает. Вторая деталь — тайм-аут: демон не должен ждать вечно, если вы спите, но и не должен сдаваться раньше, чем вы доберётесь до терминала. Пять минут — разумное значение по умолчанию. Ограничьте ключ так, чтобы он не мог делать ничего, кроме разблокировки, и не публикуйте адрес этого загрузочного листенера — тот же инстинкт, что лежит в основе материала как не оставлять своё имя на сервере.
Слоты ключей, заголовки и ошибка, в которую упираются все
Контейнер LUKS2 не шифрует ваши данные напрямую вашей парольной фразой. Он шифрует мастер-ключ вашей парольной фразой, хранит эту обёрнутую копию в слоте ключей в заголовке, а сам том шифрует уже мастер-ключом. Следствие из этого стоит усвоить: слотов несколько, так что можно добавить вторую парольную фразу или keyfile, не перешифровывая ни байта, а затем отозвать одну из них, не трогая остальные. Второе следствие острее — заголовок и есть данные. Перезапишите первые несколько мегабайт этого тома, и все слоты исчезнут разом, вместе с любой возможностью восстановления. Делайте резервную копию заголовка, вне машины, в момент создания контейнера и снова каждый раз, когда добавляете или удаляете ключ.
А ещё есть сценарий отказа, который на этом хостинге выглядит особенно жёстко. Регистрация здесь — это логин и пароль, восемь кодов восстановления и никакого email во всей цепочке, именно для того, чтобы утекать было нечему, — а это также значит, что не существует восстановления на основе личности вообще ни для чего, включая вас самих. Никто не может поручиться за вас, и ни у кого нет копии вашей парольной фразы. Поэтому стройте зашифрованную машину, пока у вас ещё есть рабочая, перезагружайте её осознанно и разблокируйте удалённо до того, как на ней появятся данные, храните резервную копию заголовка и второй слот ключей там, куда вы всё ещё сможете добраться, даже потеряв ноутбук, и убедитесь, что ваш план восстановления заканчивается повторным развёртыванием и восстановлением из бэкапа, а не тем, что кто-то другой вводит за вас парольную фразу.
SP·06Утечки по краям: swap, снапшоты и бэкапы
Зашифрованный root с незашифрованным разделом swap — это замок на двери при открытом окне: ядро будет выгружать в этот swap что угодно, включая ключевой материал. Решение — перегенерировать ключ swap из /dev/urandom при каждой загрузке, и это ничего не стоит, потому что swap не обязан переживать перезагрузку. Обеспечьте то же самое для /tmp через tmpfs, где это возможно, отключите гибернацию на сервере и подумайте насчёт discard, прежде чем его включать: передача TRIM на уровень хранилища полезна для накопителя, но раскрывает паттерн того, какие блоки используются, — это небольшое, но реальное разглашение того, насколько заполнен ваш том и где именно.
Бэкапы заслуживают отдельного размышления, потому что бэкап — это копия ваших данных где-то там, куда не дотягивается только что настроенное вами шифрование. Наша надстройка ежедневных зашифрованных бэкапов хранит снапшоты вне хоста на тарифах VPS, а ручные снапшоты — которые живут на том же хосте — это удобство отката, а не бэкап, как это сформулировано в FAQ. Если вы считаете провайдера частью своей модели угроз, шифруйте на стороне клиента, прежде чем что-либо покинет машину, ключом, который на ней не хранится. Эта же самая привычка делает путь восстановления переносимым: бэкап, который можете прочитать только вы, — это бэкап, который можно восстановить где угодно, в том числе на другом тарифном плане VPS в другом регионе.
SP·07Место шифрования в офшорной модели угроз
Шифрование — это одна из трёх защитных мер, которые отказывают независимо друг от друга, и именно поэтому использовать все три сразу — это не паранойя, а обычная инженерная практика. Первая — это что хостер знает о вас — ничего, если аккаунт — это логин, пополняемый предоплаченным крипто-балансом от $30.00, в 8 монетах и сетевых вариантах, покрывающих 7 валют, без карты и без документа во всей цепочке; этому посвящена статья анонимная оплата хостинга. Вторая — это чьё право применяется, что определяется тем, где находится машина, а не тем, где находитесь вы, и разбирается по регионам в статье какую офшорную локацию выбрать?, а с юридической стороны — в сравнении офшорных юрисдикций.
Третья — это что читаемо в состоянии покоя, и это целиком в ваших руках — ни один провайдер не может сделать это за вас, потому что провайдер, который хранит ваш ключ, не решил ту проблему, из-за которой вы вообще беспокоились. Сложите их вместе, и каждая мера закрывает свой отдельный сбой: утечка личности не раскрывает диск, юрисдикционный сюрприз не выдаёт парольную фразу, а украденный накопитель не называет ваше имя. Есть 6 регионов на выбор среди наших локаций, а VPS выходит в онлайн примерно за 15 min; на выделенном оборудовании, которое передаётся вам за 2–12 h вместе с учётными данными IPMI, можно пойти ещё дальше и загрузить собственный установщик, вместо того чтобы вообще доверять образу от провайдера.
SP·08Производительность и машины, которые не стоит шифровать
Вопрос производительности в основном решает железо. Каждый VPS во флоте работает на AMD EPYC 9354 с AES-NI, так что aes-xts-plain64 перемещает данные со скоростью в несколько гигабайт в секунду на ядро — далеко за пределами того, что любая отдельная нагрузка вообще запрашивает у массива NVMe RAID-1. Запустите cryptsetup benchmark на своей машине и смотрите на цифры сами, а не верьте на слово посту в блоге, включая этот. Реально измеримые накладные расходы проявляются в задержке, а не в пропускной способности, и только на нагрузках, которые и так упираются в fsync: реляционная база данных с интенсивной записью, загруженный почтовый спул, очередь, коммитящая каждое сообщение. Для веб-сервера, бэкенда приложения, конечной точки VPN или файлового хранилища эти издержки округляются до нуля.
Более полезный вопрос — какие машины не заслуживают этой лишней подвижной части. Машина, не хранящая никакого приватного состояния, ничего не выигрывает от шифрования и взамен получает перезагрузку, которая не может завершиться без присмотра, — публичное статическое зеркало, узел кеша, промежуточный Tor-релей, единственный секрет которого — ключ идентичности, который можно сменить за минуту. Шифруйте там, где есть что терять: база данных, хранилище почты, цель для бэкапов, машина, терминирующая ваш туннель WireGuard и хранящая его приватные ключи. Решайте по каждой машине отдельно, а не по флоту в целом, и записывайте, что есть что, — оператор через полгода — это вы, только с меньшим контекстом и худшим сном.
SP·09Шаг за шагом
-
01
Определите, что вы защищаете, и выберите схему
Запишите одно предложение, которое действительно имеет значение: каким файлам будет больно, если копия этого тома покинет здание. Если ответ — база данных и директория с ключами, зашифрованного тома данных достаточно, и вы сохраняете необслуживаемые перезагрузки. Если ответ — вся машина рассказывает историю, которую я бы предпочёл не рассказывать, стройте зашифрованный root и смиритесь с тем, что каждая загрузка будет требовать вашего участия. Не начинайте набирать команды, пока это предложение не существует.
-
02
Разверните новый VPS и защитите его прежде всего остального
Разверните сервер из панели управления — VPS выходит в онлайн примерно за 15 min — и сначала сделайте всю скучную работу на чистой машине, пока ошибка ещё ничего не стоит. SSH только по ключу, firewall с default-deny, автоматические обновления безопасности и установленный
cryptsetup.apt update && apt full-upgrade -y apt install -y cryptsetup ufw unattended-upgrades ufw allow OpenSSH ufw enable
-
03
Создайте контейнер LUKS2 и разместите в нём файловую систему
Для тома данных контейнер на основе файла — наименее инвазивный вариант, и ведёт себя точно так же, как раздел. Определяйте его размер по тому, что он должен хранить, а не по размеру диска. Выберите парольную фразу, которую сможете набрать по памяти в стрессовой ситуации, — это не тот пароль, который вы вставите из менеджера паролей на машине, которая ещё не загрузилась.
fallocate -l 40G /var/lib/vault.img cryptsetup luksFormat --type luks2 /var/lib/vault.img cryptsetup open /var/lib/vault.img vault mkfs.ext4 /dev/mapper/vault mkdir -p /srv/vault && mount /dev/mapper/vault /srv/vault
-
04
Добавьте второй ключ и сделайте резервную копию заголовка вне машины
Один слот ключей отделяет вас от полной потери данных ровно на один плохой день. Добавьте вторую парольную фразу или keyfile, выгрузите заголовок в файл и скопируйте этот файл куда-то за пределы сервера — на зашифрованный том на ноутбуке или в офлайн-хранилище. Повторяйте выгрузку каждый раз, когда меняете слот; устаревшая резервная копия заголовка может воскресить ключ, который вы считали отозванным.
cryptsetup luksAddKey /var/lib/vault.img cryptsetup luksHeaderBackup /var/lib/vault.img \ --header-backup-file /root/vault-header.img cryptsetup luksDump /var/lib/vault.img
-
05
Для зашифрованного root установите SSH-демон в initramfs
Актуально, только если зашифрован сам root. Положите свой публичный ключ туда, где его найдёт initramfs, перенесите листенер с порта 22, чтобы он никогда не конфликтовал с настоящим хост-ключом, поднимите интерфейс через DHCP и пересоберите initramfs. В Debian 12 пути изменились: там это
/etc/dropbear/initramfs/, а в Debian 11 —/etc/dropbear-initramfs/.apt install -y dropbear-initramfs cat ~/.ssh/id_ed25519.pub > /etc/dropbear/initramfs/authorized_keys echo 'DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 300"' \ >> /etc/dropbear/initramfs/dropbear.conf echo 'IP=:::::eth0:dhcp' >> /etc/initramfs-tools/initramfs.conf update-initramfs -u -k all
-
06
Перезагрузитесь осознанно, пока машина ещё пуста
Это тот шаг, который люди пропускают, а потом жалеют. Перезагрузитесь осознанно, до появления данных, и разблокируйте по сети точно так же, как вам придётся сделать это в три часа ночи. Держите загрузочный листенер в собственном файле
known_hosts, чтобы его хост-ключ никогда не спорил с настоящим. Если машина не поднимется обратно, вы потеряете тестовую машину, а не продакшен.reboot ssh -p 2222 -o UserKnownHostsFile=~/.ssh/known_hosts.boot root@203.0.113.10 # inside the initramfs: cryptroot-unlock
-
07
Закройте края и запишите план восстановления
Перегенерируйте ключ swap из
/dev/urandom, чтобы ничего из выгруженного не пережило перезагрузку, держите гибернацию выключенной и шифруйте бэкапы на стороне клиента, прежде чем они покинут машину. Затем напишите runbook восстановления — где лежит резервная копия заголовка, какой слот за что отвечает, и какой путь повторного развёртывания и восстановления вы пройдёте, когда разблокировка окажется невозможна. План, который вы не записали, — это план, которого у вас нет.# /etc/crypttab — swap re-keyed at every boot swap /dev/vda3 /dev/urandom swap,cipher=aes-xts-plain64,size=256


