Откуда вообще знать, что сервер в твоей сети — это действительно твой сервер? Он запускает твой софт, отвечает на запросы, крякает как утка. Но что внутри? Если злоущик уже захватил машину, спрятаться можно где угодно — переживёт и обновления, и перезагрузки. Обычно хост один раз получает доверие при развёртывании, а потом висит в этом статусе вечно, даже если давно пора его отозвать.
Тут на сцену выходит remote attestation (удалённая аттестация). С помощью TPM можно криптографически доказать, что на хосте ожидаемое железо, прошивка, ядро и init-образ, а для некоторых конфигов — и корневая файловая система. После перезагрузки ты знаешь точное состояние машины. Без серьёзного физического вмешательства свежая загрузка либо даёт доверенное состояние, либо ломает доверие полностью.
Это называется measured boot (измеренная загрузка), её не надо путать с trusted boot. Она опирается на подписанные измерения, а не на подписанные артефакты, как secure boot. Покрытие намного больше, хотя и сложность — тоже. Даже вредоносные подписанные драйверы и руткиты не проскочат. Но зачем измерять, если не блокировать загрузку? Затем, чтобы зашифровать ключами TPM всю корневую файловую систему — без правильных измерений хост просто неработоспособен. Remote attestation (RA) не выдаст сертификаты машине с кривыми измерениями, а если подвязать TLS x509-сертификаты к TPM, неаттестованный хост не сможет даже аутентифицироваться по mTLS.
Это не панацея: физические атаки (вроде перехвата памяти) остаются проблемой. Но в связке с хорошим EDR и политиками LSM вы закрываете кучу дыр, особенно nasty supply chain-атак на ядро и драйверы, которые обходят пользовательские защиты. А что после загрузки? Это уже работа EDR. Доверенная загрузка — фундамент: на нём строятся криптографическое доказательство, что EDR установлен, неизменяемые файловые системы, подписанные обновления, confidential computing.
Проблема в том, что измерять каждый шаг загрузки для каждого хоста в организации — огромная работа. Придётся пересобрать и прошивки, и init-образы, и ядра. Зато появится шанс вычистить легаси-мусор и найти проблемы в цепочках поставок, о которых вы даже не догадывались.
TPM — это чёрный ящик с ограниченным криптоинтерфейсом. Внутри PCR (Platform Configuration Registers), которые только хранят хэши и умеют только наращиваться: новое значение хэшируется с предыдущим, отката нет. В разные PCR во время загрузки пишутся разные артефакты, каждый этап измеряет следующий. Разрыв цепочки портит все значения.
С этими значениями можно делать две вещи: sealing (запечатывание) — материал открывается только если PCR совпадают; и quotes (цитаты) — значения подписываются ключом, встроенным в TPM. RA знает происхождение этого ключа и получает железное доказательство измерений.
Сам ритуал непростой. Сначала в TPM зашит Endorsement Key (EK) — ключ расшифровки от производителя, с x509-сертификатом под PKI. EK доказывает, что TPM настоящий. От него производят Attestation Key (AK) — ограниченный ключ подписи, умеющий подписывать только quotes. Привязка AK к EK доказывается через challenge: RA шифрует credential публичным ключом EK, устройство расшифровывает его внутри TPM и отсылает обратно. AK доказывает, что хост загрузился правильно. Но нужен третий ключ — LDevID (Locally-scoped Device ID), ребёнок AK. В отличие от AK, LDevID может подписывать что угодно, а не только quotes. Поэтому его запечатывают на «золотые» PCR: при загрузке в плохое состояние он недоступен. Когда весь ритуал пройден, хост может доказать свою легитимность.
С sealing есть проблема: обновления меняют измерения и ломают аттестацию. Решение — политика TPM2_PolicyAuthorize, подписанная AuthKey. Этот ключ может лежать на самом узле (тогда он сам решает, принимать обновление) или у центрального авторитета.
Если инфра жёстко требует mTLS, неаттестованные хосты просто не получат сертификаты. TPM-бэкированные сертификаты сами отрубят доступ. Каждый хост имеет происхождение: данные, подписанные LDevID, доказывают, с какой конкретно машины они пришли. Ворклоуды могут отказаться запускаться на неаттестованном хосте, планировщик — требовать криптодоказательства перед выделением задач, а сами задачи — челленджить хост перед загрузкой данных. В следующем посте автор обещает рассказать про dm-verity и неизменяемые корневые образы с systemd.