Часть первая.

Я не помню ни дня, когда Azure не работал бы в стрессовых условиях.

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

Весной и летом 2024 года началась масштабная инициатива по увеличению количества VM, которое мог хостить каждый узел. С точки зрения бизнеса всё было понятно: повышение плотности уже имеющихся серверов гораздо дешевле, чем построение новых дата-центров. Развёртывания Azure на мощностях компании всегда были ограничены шестнадцатью VM на узел. До того года собственные коммерческие облака Microsoft работали максимум с 32 VM, и это всё равно крошечная доля от теоретически поддерживаемых гипервизором 1024 VM.

Цель заключалась в увеличении на 50%, до 48 VM на узел, с перспективой увеличения до 64 в будущем. То, что должно было стать задачей по повышению произвольных ограничений ПО, привело к росту вылетов и инцидентов на 50%. Проблемы масштабировались ровно пропорционально плотности.

Ранее, когда я ещё продолжал работать над планом переработки интерфейса гипервизора для нижней части стека узлов Azure, мы провели исследование с командой Core OS, отвечавшей за другую сторону Hypervisor API. Данные трассировки вызовов показывали, что агенты узлов вместе атаковали гипервизор через интерфейс пользовательского режима WMI, в пике достигая 10 тысяч вызовов в секунду. У команды Hyper-V не было информации о том, какие агенты отвечали за это и почему было необходимо столько вызовов. С нашей стороны тоже никто не мог дать определённого ответа. На этом этапе стало понятно, что проект портирования выгрузки Overlake не будет никогда завершён. Не только из-за описанных выше зависимостей, но и из-за самого динамического поведения стека.

Команда Hyper-V планировала более чистый интерфейс в стиле HCS с gRPC-фронтендом, но команда Azure, находясь в условиях жёстких дедлайнов, решила двигаться дальше с уже имеющимся слоем абстракций (VMAL) и в качестве временной меры продолжать выполнять вызовы через WMI на хосте.

Даже если отставить в сторону проблемы портирования под Linux, план был нереализуемым из-за объёма вызовов, даже без учёта повышения плотности на 50% (а позже и на 100%), которое должны были добавить поверх.

Из-за все этих элементов работа была невыполнимой; для успеха плану не хватало ни глубины, ни информации.

Я ушёл из этой части организации. Ведущий инженер, который унаследовал проект, уважаемый ветеран разработки Windows, руководивший портированием на ARM32 в эпоху Windows 8, продержался ещё десять месяцев, а потом тоже покинул команду.

Стек управления VM никогда не работал с Overlake/Azure Boost SoC.

Отойдя от работы по повышению плотности VM и выгрузки, я обратил своё внимание на ещё одну фундаментальную часть стека узлов Azure: набор компонентов, который команда называла сервисами метаданных инстансов (это название было позаимствовано у Amazon EC2).

В Azure он состоит из доступного пользователям веб-сервера (WireServer), работающего в операционной системе хоста каждого узла, а также из поддерживающих компонентов сервисов.

Одна из конечных точек публично задокументирована; она предназначена для того, чтобы предоставлять информацию гостевым VM.

Интересно здесь то, что этот веб-сервис работает в операционной системе хоста, то есть в защищённой части машины.

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

Менее очевидно то, что операционная система хоста не изолирована от VM таким же образом.

Страницы памяти, принадлежащие каждому разделу VM, отображаются на процессы в хосте. В Windows это процессы vmmem.exe.

Это отображение необходимо для практических операций, например, для сохранения состояния VM на диск, включая полное содержимое памяти.

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

В этом контексте хостинг веб-сервиса, к которому имеет доступ любая гостевая VM, и его работа на стороне защищённого хоста, создавали гораздо большую поверхность атаки, чем я ожидал.

В тот же самый период ещё одна команда представила Metadata Security Protocol, нацеленный на повышение безопасности сервисов метаданных Azure при помощи добавления HTTP-заголовков, содержащих код аутентификации сообщений на основе хэша.

Хоть этот новый протокол стал желанным пополнением для борьбы с недопустимыми запросами, он не решал беспокоящую меня проблему атаки на сам веб-сервер.

Многие эксплойты побега из VM используют уязвимости в драйверах виртуальных устройств, находящихся посередине между хостом и VM. Работа веб-сервера в операционной системе хоста с незащищёнными конечными точками, открытыми для гостевых VM (пусть даже с подписыванием), создаёт более серьёзную угрозу безопасности.

Я рекомендовал полностью убрать из узлов WireServer и IMDS, и мою точку зрения безоговорочно подхватил вице-президент по архитектуре безопасности, автор популярной книги о моделировании угроз, с которым я поделился своими опасениями.

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

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

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

Новый код выкидывал исключения C++ в кодовой базе, которая изначально не содержала исключений. Руководства команды по кодингу напрямую противоречили руководствам организации в целом, а в практике тестирования не применялись долговременные тесты, поэтому они упускали утечки памяти и другие дефекты.

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

Это ещё нагляднее показывает нехватку технического руководства, распространившуюся на всю организацию.

Я назвал подсистему WireServer/IMDS, работающую в каждом узле Azure, «ходячей угрозой безопасности», которую следует устранить из узлов; эту точку зрения разделяли многие стейкхолдеры за пределами организации. План команды относительно Overlake заключался в повторении того же самого под другим названием; таким образом Azure Boost SoC становились бы раскрытыми любым гостевым VM через прямое сетевое соединение.

Эти сервисы должны хоститься только как собственные облачные сервисы, с кэшем учётных данных/секретов внутри каждой VM, которой они нужны, и содержать секреты только этой VM, зашифрованные при помощи vTPM там, где это возможно.

Такая схема хорошо работала бы и в сценариях с использованием bare-metal в качестве выбираемого пакета, применяющего физический TPM.

Руководство организации встало в защитную позицию и всё отрицало. Вскоре после этого она уволила меня.

При поспешном выпуске Azure компания Microsoft нарушила фундаментальные принципы надёжности и простоты эксплуатации.

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

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

Публичные отчёты продемонстрировали сотни таких вмешательств в одни лишь конфиденциальные правительственные облака. На самом деле, суммарное количество вмешательств было гораздо выше.

Инженеры OPEX и поддержки, получающие доступ к привилегированным частям системы, отправляли запросы на подтверждение Just-In-Time (JIT), которые распространялись в специальном списке рассылки. Эти запросы мог утверждать любой штатный член организации. После утверждения запрашивающий получал доступ к системе на восемь часов, в течение которых мог взаимодействовать с физическими узлами и контроллерами Fabric, а также управлять секретами, если запрошенный уровень доступа соответствовал RdmSecretsAdministrator.

Всего за два месяца, с 14 августа 2024 года по 26 октября 2024 года, в папке Outlook, которую я создал для отделения JIT-запросов от других сообщений, накопилось 14209 запросов — почти по 200 в день.

То, что изначально было временными мерами, превратилось в стандартные процедуры, обычной частью ведения бизнеса. Azure никогда не работал так гладко и независимо, как это обещалось. Microsoft представила миру и своим самым требовательным заказчикам изощрённую систему, постоянно подключенную к приборам жизнеобеспечения.

Эта фундаментальная хрупкость, укоренившаяся в поспешных решениях и необоснованных расчётах на возможную скорость роста и стабилизации платформы, привела к возникновению небольших, но постоянных помех. Со временем эти помехи накапливались.

В результате возник классический эффект бабочки: внутренние изъяны качества ПО узлов Azure, отсутствие дисциплины тестирования и увеличение архитектурной сложности саботировали попытки реализации важных проектов.

К началу 2025 года OpenAI, всё ещё формально вынужденная соблюдать соглашение ROFR с Microsoft, начала агрессивно диверсифицировать свои compute-ресурсы.

Быстро стали очевидны последствия этого: несмотря на рекордные прибыли, Уолл-стрит испытывала всё большие сомнения, а уверенность инвесторов в компании резко снижалась. Достигнув пика в конце октября 2025 года, за последующие месяцы акции Microsoft упали более чем на 30%, из-за чего компания потеряла больше триллиона от своей рыночной стоимости.

Колокола били уже давно.

Оглядываясь назад, становится очевидным более правильный путь: приостановить агрессивный выпуск фич, активно вкладываться в стабилизацию базового стека узлов, упростить экосистему агентов, восстановить дисциплину тестирования и ответственности, а уже потом начинать амбициозные проекты и обещать bare-metal флагманским клиентам.

Но по этому пути никто не пошёл. Организация уже адаптировалась к постоянному тушению пожаров. Что ещё более важно, в Microsoft больше не было опытных системных разработчиков (проектировщиков ядра, виртуализации и распределённых систем, создавших Fabric), необходимых для столь фундаментальной переделки.

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

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

Однако ситуацию можно спасти. В 2024 году я прочитал требования OpenAI к инфраструктуре, в которых описываются потребности и обещания, данные платформой Azure.

Текущие планы, скорее всего, провалятся (история подтвердила правильность этого предчувствия), поэтому я начал разрабатывать новые, чтобы заново выстроить стек узлов Azure с нуля, исходя из базовых принципов.

Основополагающими элементами новой платформы узлов стали простая кроссплатформенная компонентная модель для создания портируемых модулей, которые можно собирать как под Windows, так и под Linux, а также новая система обмена сообщениями, охватывающая весь узел и позволяющая агентам свободно взаимодействовать через границы гостевой системы, хоста и SoC. Эти идеи были широко распространены в виде письменных документов, а некоторые из них были представлены на высокоуровневом межорганизационном техническом совещании

Часть запросов OpenAI, связанных с её будущими узлами bare-metal, которые бы позволили им выжать последние несколько процентов из оборудования, требовали внесения расширений в саму карту Overlake. Я создавал драфты этих расширений и показывал их техническому партнёру подразделения, опытному архитектору ядер, недавно перешедшему на проект Azure; я знал его по предыдущей работе в команде разработчиков ядра.

Улучшения могли стать частью Overlake 4 — следующей старшей версии платформы выгрузки Windows Boost, а пока можно было развернуть программную реализацию для обеспечения истинных образов удалённых систем только для чтения и быстрых сбросов систем; это полезная фича, позволяющая выполнять быстрые эксперименты и откаты, характерные для исследовательских областей.

Я создал новый репозиторий кода, соответствующий новейшим стандартам управления Azure, и начал разрабатывать сами компоненты, стремясь показать пример и задать вектор развития.

Я решил «проблему удаления миллионов файлов», которая кажется простой, но всё равно требует тщательной обработки для надёжного выполнения в масштабах облака. Далее я создал LRU-кэш шифрования для отделения данных пользователей и следования базовым принципам безопасности в многопользовательских окружениях. Тоже довольно простая задача, но в этом и заключается цель разбиения на компоненты.

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

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

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

В конечном итоге областей для вырезания не останется, а исходные компоненты превратятся в скелеты, вызывающие новые компоненты. Кроме того, разбиение на компоненты позволит перемещать элементы системы; например, защищённый кэш можно использовать в ускорителе выгрузки, в хосте, внутри гостевой VM, в гостевом контейнере L1/L2 или в узле bare-metal при помощи однородной шины сообщений, объединяющей все части.

Это видение было пренебрежительно воспринято со стороны менеджмента младшего звена Azure Core, который, возможно, не осознал неотложности (или масштаба) изменений, необходимых для того, чтобы сделать платформу по-настоящему масштабируемой, одновременно снизив долговременные затраты на OPEX.

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

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

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

То, что начиналось, как технические разногласия, превратилось в что-то большее: проверку того, может ли Microsoft по-прежнему работать на уровне, ожидаемом от неё большинством стратегических заказчиков и партнёров.

Колокольный звон становился всё громче. В последующие месяцы я начал делиться своими опасениями не только с непосредственным руководством. 19 ноября 2024 года я отправил подробное письмо исполнительному вице-президенту направления Cloud + AI.

В нём были полностью изложены мои технические открытия, упомянуты замеченные мной пробелы в руководстве, а также приведены конкретные предположения по устранению первопричин проблем.

7 января 2025 года, всё ещё за несколько месяцев каких-либо публичных проявлений напряжённости в отношениях с OpenAI, я отправил более сжатый отчёт CEO.

В начале письма говорилось о потенциальных угрозах основной сфере деятельности Microsoft и национальной безопасности, затем шёл короткий список пунктов с перечислением ключевых проблем стека узлов Azure и организационных трудностей.

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

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

В этом письме я рассказывал об отсутствии ответа на предыдущие сообщения; я приложил к нему письмо, отправленное мной CEO, и отметил, что частичная утеря OpenAI и связанные с ней проблемы были предотвратимы.

За последующие месяцы ответа я не получил — ни одного подтверждения, вопроса, уточняющего запроса или подтверждения о получении, ни от исполнительного вице-президента, ни от CEO, ни от совета директоров.

Полное отсутствие каких-либо отзывов само по себе стало ещё одним показателем.

Проблемы в коммуникациях были выявлены задолго до заметной смены настроений заказчиков.

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

Эта серия статей началась с рассказа о потрясении одного инженера с первого его дня работы в организации.

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

Но ни на одном из уровней эти сигналы не привели ни к какому ответу.

Колокольный звон, о котором я говорил выше, стал хорошо слышен далеко за пределами офисов Azure Core в западном кампусе.

Но неизвестно, слышит ли его высшее руководство...