Аргумент в пользу шифрования арендованного сервера уже, чем предполагает маркетинг, но куда весомее в этих узких рамках. NVMe-накопители выходят из строя и возвращаются поставщику с вашими данными всё ещё на борту. Ноды выводят из эксплуатации, а хранилища перепродают. Оборудование снимают образом или выносят из стойки. В каждом из этих случаев LUKS — это разница между читаемой файловой системой — вашими ключами, вашей базой данных, вашим почтовым хранилищем — и блоком шума, с которым никто ничего не сделает.
Чего он не даёт — так это защиты от машины, на которой вы работаете. Это разграничение — суть всего руководства, поэтому оно идёт первым, ещё до единой команды. Дальше — сама работа: правильно созданный том LUKS2, резервная копия заголовка, зашифрованный swap, удалённая разблокировка по SSH и план восстановления на случай перезагрузки, после которой сервер не поднимается. Сервер под всем этим можно арендовать без ID и оплатить в Monero; шифрование — это слой, который вы добавляете поверх, а не замена ему.
Что на самом деле защищает шифрование данных в состоянии покоя
Полное шифрование диска отвечает на один вопрос и отвечает исчерпывающе: что произойдёт, если диск окажется в чужих руках, пока он выключен? На арендованной инфраструктуре это не гипотеза. Диски выходят из строя и возвращаются поставщику. Ноды выводят из эксплуатации, а их хранилища перепродают. С томов снимают образы в ходе расследования, или они покидают здание в ящике.
- В зоне защиты. Выключенный диск, офлайн-образ вашего тома, диск, возвращённый по гарантии, выведенная из эксплуатации нода, скопированный файл снапшота. В каждом из этих случаев атакующему достаются шифротекст и заголовок — без парольной фразы на этом история заканчивается.
- Вне зоны защиты: работающая машина. Как только том открыт, ключ оказывается в памяти ядра, и файловая система видна всему, что обладает правами root.
- Вне зоны защиты: ваш трафик. Байты в канале — забота TLS и WireGuard. LUKS их вообще не видит.
- Вне зоны защиты: скомпрометированная учётная запись root. Злоумышленник, уже проникший внутрь, читает ваши файлы через ту же точку монтирования, что и вы. Для этого нужна защита сервера, и эти два средства защиты не взаимозаменяемы.
Список короткий намеренно. Шифрование данных в состоянии покоя — это дешёвое и очень ценное средство защиты со строго ограниченной областью действия, и почти всё разочарование, о котором сообщают люди, происходит от того, что они молча ожидали, что оно прикроет и три остальных пункта тоже.
Оговорка про арендованное железо, сказанная прямо
Когда ваш зашифрованный том открыт, ключ находится в оперативной памяти гостевой системы — а на любом VPS, где бы он ни находился, эта память живёт на машине, которую физически контролирует оператор. Гипервизор может читать память гостя. Это не изъян LUKS, не изъян KVM и не изъян конкретно этого хостинга; это то, что означает аренда компьютера, и любой провайдер, утверждающий обратное, описывает продукт, которого не существует.
Поэтому расчёт прямолинеен: шифрование данных в состоянии покоя делает офлайн-атаку невозможной и оставляет онлайн-атаку ровно там же, где она была. Диск, покинувший стойку, становится бесполезным. Работающий сервер настолько же уязвим, насколько был вчера. Обе половины этого утверждения верны одновременно, и руководство, рассказывающее только о первой половине, оказывает вам плохую услугу.
Что действительно сдвигает вторую стрелку — это другой набор мер, и они складываются с шифрованием, а не заменяют его. Здесь нечего раскрывать по документам, потому что регистрация — без KYC — только секретный токен и ничего больше, даже email. Оплата проходит в блокчейне, а не через банк. А юрисдикция, в которой находится сервер, решает, какие требования вообще имеют силу. Наш честный разбор того, что скрывает, а чего не скрывает VPS с оплатой в криптовалюте, разбирает остальное, а статья про Четырнадцать глаз раскрывает сторону обмена разведданными. Если воспринимать LUKS как один слой защиты среди нескольких — это отличное вложение. Если воспринимать его как щит от собственного хостинга — это заблуждение.
Том данных или корневая файловая система: решите, прежде чем печатать
Это может принимать одну из двух форм, и выбор здесь о риске, а не о надёжности.
- Зашифрованный том данных. Контейнер LUKS рядом с операционной системой. Всё важное — базы данных, почта, ключи, загрузки, резервные копии — живёт внутри него; сама ОС остаётся в открытом виде. Десять минут работы, никакого риска для загрузки и полная обратимость в любой момент. Именно это стоит собирать большинству читателей, и именно это делают шаги ниже.
- Зашифрованная корневая файловая система. Внутри всё, включая логи, списки пакетов и историю шелла, о которой вы забыли. Строго надёжнее, и по-настоящему сложнее применить к машине, которая уже работает.
О причине этой сложности стоит сказать прямо, потому что ни один туториал этого не делает: нельзя зашифровать файловую систему, которая прямо сейчас смонтирована на чтение-запись и обслуживает вашу SSH-сессию. Оба реальных метода — сжатие с копированием или cryptsetup reencrypt на месте — требуют, чтобы корень был отключён. На машине с внеполосной консолью вы просто загружаете установщик, и это рутинная операция. На безголовом VPS вам приходится сначала переводить работающую систему в RAM-диск, и если что-то в этом процессе пойдёт не так, сервер не поднимется, а путь восстановления — это переустановка, которая стирает диск.
Поэтому: соберите том данных сегодня, перенесите на него всё сколько-нибудь важное, а зашифрованный корень воспринимайте как решение, которое принимают в момент развёртывания, на машине, которой ещё нечего терять. Последний раздел разбирает именно этот путь, включая dropbear-initramfs для ввода парольной фразы по SSH при загрузке.
Что нужно, прежде чем начать
Не так уж много, и отчасти поэтому этим стоит заняться.
- Тариф. Шифрование не добавляет требований к RAM и почти не нагружает CPU. Cub (1 vCPU / 2 GB / 40 GB NVMe, $5.00/mo) достаточно; Scout (2 vCPU / 4 GB / 70 GB, $9.00/mo) — комфортный размер, если сервер к тому же выполняет реальный рабочий сервис. Единственная цифра, которая важна, — это диск, потому что зашифрованный том выделяется именно из него.
- Debian 12 или 13 из библиотеки шаблонов, либо Ubuntu LTS — команды ниже написаны под Debian, и в других системах названия пакетов отличаются. Развёртывание занимает около минуты, а полноценная виртуализация KVM означает настоящее ядро с модулями
dm-crypt, а не контейнер, одалживающий чужое. - Десять минут базовой защиты для начала. Шифрование на сервере, который всё ещё принимает вход по паролю, — это замок на двери без косяка.
- Парольная фраза, которую вы больше нигде не использовали, сгенерированная, а не придуманная, и сохранённая там, где она переживёт потерю этой машины. Восстановления не существует, сброса не существует, и никакой тикет в поддержку не поможет.
- Место за пределами сервера для хранения резервной копии заголовка. Еженедельные снапшоты включены в каждый тариф, но снапшот зашифрованного тома остаётся зашифрованным — полезен для отката, бесполезен, если парольная фраза утеряна.
Локация не имеет значения ни для чего из этого, так что выбирайте по цене или юрисдикции: Amsterdam, Paris, Bucharest и Sofia идут по базовой цене, тогда как Zurich, Reykjavik, Stockholm и Kuala Lumpur — с надбавкой.
Пошаговая инструкция
- Разверните сервер, защитите его и убедитесь, что у CPU есть AES-NI
Разверните Debian 13 из библиотеки шаблонов и для начала потратьте десять минут на базовые меры: только SSH-ключи, отключённый вход по паролю root, nftables default-deny, автоматические обновления безопасности. Затем убедитесь, что железо не заставит вас платить за это:
grep -o -m1 ' aes ' /proc/cpuinfo apt update && apt install -y cryptsetup cryptsetup benchmarkВам нужны показатели
aes-xtsв гигабайтах в секунду. У любого серверного x86-64 CPU последнего десятилетия есть AES-NI, так что узким местом будет не шифрование — а NVMe под ним, точно так же, как и раньше. - Выделите место под том
Если на диске вашего тарифа есть неразмеченное пространство, используйте его — настоящий раздел проще всего шифровать:
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT sgdisk -n 0:0:0 -c 0:secure /dev/vda partprobe /dev/vdaЕсли шаблон занял весь диск, не боритесь с этим. Контейнер на основе файла здесь полноправный вариант, ничего не стоит по пропускной способности на NVMe и может быть расширен позже:
fallocate -l 20G /var/lib/secure.img chmod 600 /var/lib/secure.img losetup --find --show /var/lib/secure.imgЗапомните loop-устройство, которое он выведет — обычно
/dev/loop0. Везде ниже используется/dev/disk/by-partlabel/secure; подставьте своё loop-устройство, если вы выбрали путь с контейнером. - Отформатируйте его как LUKS2 — и ограничьте затраты памяти
Это команда, которая решает всё, поэтому её стоит прочитать, а не просто вставить:
cryptsetup luksFormat --type luks2 \ --cipher aes-xts-plain64 --key-size 512 \ --pbkdf argon2id --pbkdf-memory 262144 --iter-time 5000 \ /dev/disk/by-partlabel/secure--key-size 512— это AES-256 в режиме XTS, который делит ключ пополам — это не AES-512, которого не существует.--pbkdf argon2id— это устойчивая к памяти функция деривации ключа, которая делает подбор вашей парольной фразы дорогим как по RAM, так и по CPU.--pbkdf-memory 262144ограничивает это значение 256 MB, и это та строка, которую люди пропускают, а потом жалеют. Если её не задать,cryptsetupсам подгоняет затраты памяти под объём RAM, доступный в момент форматирования. Разблокируйте тот же заголовок позже там, где памяти меньше — тариф на 1 GB, спасательное окружение, initramfs — и разблокировка может провалиться напрочь. Ограничивайте это осознанно. - Откройте том, создайте файловую систему и смонтируйте
cryptsetup --perf-no_read_workqueue --perf-no_write_workqueue \ --allow-discards open /dev/disk/by-partlabel/secure secure mkfs.ext4 -L secure /dev/mapper/secure mkdir -p /srv/secure mount -o noatime /dev/mapper/secure /srv/secure df -h /srv/secureДва флага workqueue имеют значение только на NVMe и больше нигде;
--allow-discardsсохраняет работу TRIM ценой раскрытия того, какие блоки заняты, всем, кто держит выключенный диск в руках. Оба обсуждаются ниже — варианты по умолчанию выше правильны для сервера общего назначения. - Сделайте резервную копию заголовка LUKS за пределами сервера
Сделайте это сейчас, пока на томе ещё нет ничего, что жалко потерять. Заголовок — это примерно 16 MB метаданных, хранящих слоты ключей, и повреждённый заголовок означает, что шифротекст невосстановим, как бы хорошо вы ни помнили парольную фразу:
cryptsetup luksHeaderBackup /dev/disk/by-partlabel/secure \ --header-backup-file /root/secure-header.img sha256sum /root/secure-header.imgСкопируйте его куда-нибудь ещё — заберите через
scp, положите в менеджер паролей, распечатайте хэш — а затем удалите локальную копию. Относитесь к этому файлу как к эквиваленту парольной фразы, потому что в сочетании с любой парольной фразой, которую он когда-либо хранил, он им и является. - Перенесите на том то, что действительно важно
Зашифрованный том, в который ничего не пишет, не защищает ничего. Сначала остановите сервис, перенесите его состояние, затем сделайте bind-mount старого пути, чтобы больше ничего не пришлось перенастраивать:
systemctl stop postgresql rsync -aHAX --info=progress2 /var/lib/postgresql/ /srv/secure/postgresql/ mv /var/lib/postgresql /var/lib/postgresql.old mkdir /var/lib/postgresql echo '/srv/secure/postgresql /var/lib/postgresql none bind 0 0' >> /etc/fstab mount /var/lib/postgresql systemctl start postgresqlУбедитесь, что сервис в порядке, прежде чем стирать через
shredили удалять каталог.old— и помните, что в файловой системе с copy-on-write или на NVMe с выравниванием износа удаление открытого текста — не то же самое, что его уничтожение. Чистая версия этой истории — создавать зашифрованный том ещё до появления сервиса. - Решите, как том будет разблокироваться, и будьте с собой честны
Вот развилка, на которую натыкается каждый. Добавьте том в
/etc/crypttabсnoauto, чтобы ничто не блокировало загрузку, и разблокируйте его вручную по SSH, когда он вам нужен:echo 'secure /dev/disk/by-partlabel/secure none \ luks,noauto,discard,no-read-workqueue,no-write-workqueue' >> /etc/crypttab cryptdisks_start secureЭто честная конфигурация: ключ существует только пока вы рядом, а после перезагрузки том остаётся закрытым, пока вы не скажете иначе. Цена в том, что после самопроизвольной перезагрузки сервис возвращается в выключенном состоянии.
Альтернатива — keyfile в
/etc/crypttab, чтобы том открывался автоматически. Если этот keyfile лежит на том же диске, вы не зашифровали вообще ничего — тот, кто держит выключенный диск, держит ключ рядом с замком. Это имеет смысл только тогда, когда ключ приходит оттуда, где диска нет: получен через туннель WireGuard при загрузке, либо введён в initramfs по SSH, как в последнем разделе. Выбирайте осознанно; вариант по умолчанию с ручной разблокировкой — единственный, который означает именно то, что говорит. - Зашифруйте swap и проверьте всё целиком
Swap — это место, куда память попадает, чтобы стать артефактом на диске, поэтому зашифрованный том рядом с открытым swap сливает ровно те секреты, которые вы пытались защитить. Случайный ключ на каждую загрузку — правильный ответ: нечем управлять, нечего терять. Сначала проверьте
swapon --showи подставьте своё устройство; если шаблон выдал вам swap-файл, а не раздел, удалите его и используйте вместо этого небольшой раздел, потому что устройству со случайным ключом нужно блочное устройство:swapoff -a sed -i '/swap/s/^/#/' /etc/fstab echo 'swap /dev/vda3 /dev/urandom \ swap,cipher=aes-xts-plain64,size=512' >> /etc/crypttab echo '/dev/mapper/swap none swap sw 0 0' >> /etc/fstabЗатем перезагрузитесь — пока ошибиться всё ещё дёшево — и честно проверьте результат:
lsblk -o NAME,FSTYPE,MOUNTPOINT cryptsetup status secure blkid /dev/disk/by-partlabel/secure # should say crypto_LUKS swapon --show # should show /dev/mapper/swapТест, который действительно что-то показывает: при закрытом томе убедитесь, что
/srv/secureпуст, а зависящий от него сервис отказывается запускаться. Если верно и то, и другое, шифрование настоящее, а не декоративное.
Слоты ключей, заголовки и смена парольной фразы
LUKS2 хранит до 32 слотов ключей. Каждый содержит копию одного и того же мастер-ключа, обёрнутую отдельной парольной фразой, поэтому вы можете добавить вторую парольную фразу, ничего не перешифровывая:
cryptsetup luksAddKey /dev/disk/by-partlabel/secure
cryptsetup luksDump /dev/disk/by-partlabel/secure | grep -A2 '^Keyslots'
cryptsetup luksKillSlot /dev/disk/by-partlabel/secure 1Две парольные фразы с самого начала — правильное решение по умолчанию: одна для использования, вторая — записанная и хранящаяся отдельно. Потеря единственного доступа к тому из-за опечатки в менеджере паролей — самый распространённый способ потерять данные LUKS, с большим отрывом опережающий всё, что может сделать злоумышленник.
Теперь — ловушка. Резервная копия заголовка, снятая до смены парольной фразы, всё ещё открывает том старой парольной фразой. Слоты ключей живут в заголовке, поэтому старая копия заголовка — это и старая копия слотов ключей — сам мастер-ключ под ними никогда не менялся. Если вы меняете фразу потому, что она могла утечь, необходимо уничтожить все резервные копии заголовка, снятые до смены, и сделать новую. Иначе смена не даёт ничего, кроме иллюзии спокойствия.
Тот же факт делает резервные копии заголовка чувствительными сами по себе: этот файл на 16 MB вместе с любой парольной фразой, которую он когда-либо знал, достаточен для расшифровки тома. Храните его там же, где хранили бы парольную фразу, а не там, где храните снапшоты.
Производительность: AES-NI, NVMe и два флага, которые стоит знать
cryptsetup benchmark за примерно пятнадцать секунд говорит правду именно для вашего vCPU. На любом CPU с AES-NI — а это любой серверный x86-64 процессор последнего десятилетия — стоит ожидать несколько гигабайт в секунду для aes-xts, с комфортным запасом быстрее, чем NVMe под ним. Практические накладные расходы на реальной нагрузке — это низкие единицы процентов, и упираются они в CPU, а не в задержку.
На быстром хранилище имеют значение две опции cryptsetup, и только на быстром хранилище:
cryptsetup --perf-no_read_workqueue --perf-no_write_workqueue \
--allow-discards open /dev/disk/by-partlabel/secure secureФлаги workqueue обходят внутренние очереди dm-crypt и передают ввод-вывод напрямую устройству. На вращающемся диске они ничего не меняют; на NVMe RAID10 они убирают реальное узкое место при высокой глубине очереди. Добавьте их в строку опций crypttab как no-read-workqueue,no-write-workqueue, чтобы сделать постоянными.
--allow-discards — вариант с компромиссом. Он пропускает TRIM к NVMe, что со временем поддерживает производительность записи — а заодно раскрывает всем, кто держит в руках выключенный диск, какие блоки заняты, а какие свободны. Это настоящая, пусть и скромная, утечка информации: она показывает примерно то, насколько заполнен том, и может намекнуть на структуру файловой системы. На сервере общего назначения выбирайте производительность. Если содержимое тома — из тех вещей, где чувствителен сам размер, оставьте discard выключенным.
Путь через корневую файловую систему и удалённая разблокировка по SSH
Если вы хотите зашифровать всё целиком, делайте это на машине, на которой ещё ничего нет — сначала разверните, потом конвертируйте, потом стройте. Сама конвертация стандартна: сжать корневую файловую систему, пока она отключена, создать контейнер LUKS2 в освободившемся пространстве, скопировать систему через rsync -aHAX, указать /etc/fstab и /etc/crypttab на mapper-устройство, затем выполнить update-initramfs -u -k all и переустановить GRUB. Проблемой для безголового VPS это делают именно слова пока она отключена: добраться до этого состояния без консоли означает сначала перевести работающую систему в RAM-корень, а это тот самый шаг, который заканчивается переустановкой, если что-то идёт не так.
То, что вообще делает зашифрованный корень пригодным для использования на удалённой машине, — это dropbear-initramfs — SSH-сервер размером примерно 200 KB, встроенный в загрузочный образ и слушающий, пока ядро ждёт парольную фразу:
apt install dropbear-initramfs cryptsetup-initramfs
# Debian 12/13: /etc/dropbear/initramfs/
cp ~/.ssh/unlock_key.pub /etc/dropbear/initramfs/authorized_keys
chmod 600 /etc/dropbear/initramfs/authorized_keys
echo 'DROPBEAR_OPTIONS="-I 300 -j -k -p 2222 -s -c cryptroot-unlock"' \
>> /etc/dropbear/initramfs/dropbear.conf
echo 'IP=:::::eth0:dhcp' >> /etc/initramfs-tools/initramfs.conf
update-initramfs -u -k allЗатем во время загрузки вы выполняете ssh -p 2222 root@your-ip, и принудительная команда cryptroot-unlock запрашивает парольную фразу. Прежде чем полагаться на это, стоит знать три вещи. У initramfs есть собственный host key, поэтому ваш клиент предупредит о несовпадении на порту 2222 — это ожидаемо и как раз причина выделить для этого отдельный порт. Этот host key и ваш authorized_keys лежат на незашифрованном загрузочном разделе, доступном для чтения всем, кто держит диск в руках, поэтому используйте ключ разблокировки, который не делает больше ничего. А -s отключает вход по паролю в initramfs, и это не опция, а обязательное условие.
Ещё одна деталь, которая кусается на маленьких тарифах, — та же, что и в шаге третьем, и здесь она кусается больнее всего. initramfs запускается раньше, чем большая часть вашей RAM становится доступна хоть для чего-то комфортного, поэтому заголовок, отформатированный с большим объёмом памяти Argon2id, может не разблокироваться на той же самой машине, где был создан. Форматируйте с ограниченным --pbkdf-memory и тестируйте перезагрузку, пока терять ещё нечего.
День второй: что меняется, а что нет
Совсем немногое, в этом и суть. Открытый том LUKS — обычное блочное устройство; fsck, rsync, df и ваш инструмент резервного копирования ведут себя точно так же, как раньше. Обновления ядра не затрагиваются, потому что dm-crypt встроен в дерево ядра. Расширение тома после апгрейда тарифа — это две команды — cryptsetup resize, а затем собственное расширение файловой системы — и не требует повторного шифрования.
Стоит выработать три привычки. Репетируйте перезагрузку по расписанию, а не узнавайте в три часа ночи, что парольная фраза, которую вы нигде не записали, существует в единственном экземпляре. Храните резервные копии зашифрованными отдельно — restic или borg на внешний сервер, что является отдельным средством защиты, не связанным с томом, и переживёт полную потерю сервера; дополнение с ежедневным резервным копированием во внешнее хранилище стоит $2.00/mo, если вы не хотите настраивать это сами. И закрывайте том прежде, чем перестанете заботиться о сервере: cryptsetup close secure перед плановым выключением, миграцией или переустановкой означает, что ключ покидает память прежде, чем диск перестаёт быть вашим.
В плане политики торговаться не о чем. Вы получаете полный root на госте KVM, и что вы делаете с блочным уровнем — исключительно ваше дело; шифрование собственного тома — обычное системное администрирование, а не особый случай. Политика допустимого использования касается поведения — жёсткий предел там: никакого CSAM и никакого терроризма — и ничего не говорит про dm-crypt. Шифрование меняет форму гипотетического плохого дня: выключенный том, покидающий это здание, превращается в шум, и это стоит десяти минут вашего времени.

