#troubleshooting #aws #ssh #retool #paranoia #linux
Есть такая штука, называется
Какая-то платформа для менеджеров, я ей не пользовался никогда в бизнес уровне.
В UI интерфейсе мышкой подключаются
Это всё, что надо знать для начала, идём дальше.
В основном
Первый случай я не знаю для кого, у меня пока не было опыта публичных БД, второй способ мне не нравится, да и не пройти с ним SOC2 аудит, так что у нас только третий вариант - через ssh tunnel.
У них есть вполне годный гайд https://docs.retool.com/data-sources/guides/connections/ssh-tunnels, который подойдёт для 99% случаев.
Создаётся пользователь на бастион хосте(например через
При подключении ресурса вы в UI указываете ваш bastion хост, порт и прожимаете test connection.
Если всё ок- ошибки нет. Не ок - ошибка.
Ошибка чаще всего дурацкая, потому что открывается какой-то аналог developer tool и показывает длинный стактрейс.
С
В то время в качестве бастион хоста была убунту 18 вроде и мне пришлось промучить весь стакоферфлоу, чтобы найти решение для себя при ошибке, мне не хватало
Ровно после этого в официальной документации и появился этот совет, если коннекта нет.
Написал им в поддержку, чтобы поправили мануал для глупеньких я.
Тогда подключили какие-то бд, я сидел дальше ковырялся с конфигами, безопасностью, со временем обложил всё секьюрити группами типа
Потом добавились секюрити группы по MySQL/PostgreSQL типа
Так же сразу сделал отдельного пользователя в БД с чётко обрезанными правами.
Делал что-то ещё, и в целом был удовлетворён, что тварь какая-то ходит в мои сети.
Прошло много лет.
Ко мне приходят ребята инженеры, говорят хотят добавить новую БД для retool.
Уже подключена монга, mysql и всякое, а теперь надо и PostgreSQL.
Ок, говорю, ну там всё уже настроено - все ssh ключи, секьюрити группы и прочее - всё должно работать - другие то ресурсы(БД) работает до сих пор.
Берите креды и сами настраиваете, мы же договорились, что не должно быть боттлнека -девопса.
Они высылают скрин, что ошибка подключения. Я само собой не верю (бл, когда я научусь думать, что другие люди не глупее меня🐒 , баран самоуверенный).
Иду сам в retool, копирую все креды, создаю ресурс, но у меня тоже ошибка.
Извиняюсь перед ребятами, пилю тикет, начинаю разбираться.😭
Есть такая штука, называется
retool https://retool.com/Какая-то платформа для менеджеров, я ей не пользовался никогда в бизнес уровне.
В UI интерфейсе мышкой подключаются
resource и на их базе могут строятся какие-то таблички, панели и прочая не интересная мне информация для менеджеров и сейлзов(наверное).Resources чаще всего это база данных. Например MySQL или PostgreSQL. У retool тысячи их для любых интеграций.Это всё, что надо знать для начала, идём дальше.
В основном
Retool из интернета подключается к вашим ресурсам либо напрямую по hostname, либо к AWS через IAM credentials, либо через SSH bastion host.Первый случай я не знаю для кого, у меня пока не было опыта публичных БД, второй способ мне не нравится, да и не пройти с ним SOC2 аудит, так что у нас только третий вариант - через ssh tunnel.
У них есть вполне годный гайд https://docs.retool.com/data-sources/guides/connections/ssh-tunnels, который подойдёт для 99% случаев.
Создаётся пользователь на бастион хосте(например через
ansible или руками), добавляется их ssh public key, раскидываются права - всё готово. В общем всё по инструкции.При подключении ресурса вы в UI указываете ваш bastion хост, порт и прожимаете test connection.
Если всё ок- ошибки нет. Не ок - ошибка.
Ошибка чаще всего дурацкая, потому что открывается какой-то аналог developer tool и показывает длинный стактрейс.
С
retool я уже работал, подключал на проект много лет назад. В то время в качестве бастион хоста была убунту 18 вроде и мне пришлось промучить весь стакоферфлоу, чтобы найти решение для себя при ошибке, мне не хватало
PubkeyAcceptedKeyTypes +ssh-rsa
Ровно после этого в официальной документации и появился этот совет, если коннекта нет.
Написал им в поддержку, чтобы поправили мануал для глупеньких я.
Тогда подключили какие-то бд, я сидел дальше ковырялся с конфигами, безопасностью, со временем обложил всё секьюрити группами типа
resource "aws_security_group" "bastion" {
...
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
# https://docs.retool.com/data-sources/reference/ip-allowlist-cloud-orgs
# retool ip ranges only
# tfsec:ignore:aws-ec2-no-public-ingress-sgr
cidr_blocks = [
"35.90.103.132/30",
"44.208.168.68/30",
"3.77.79.248/30"
]
description = "SSH access from allowed IP ranges"
}
...Потом добавились секюрити группы по MySQL/PostgreSQL типа
resource "aws_security_group_rule" "this" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["*********"]
security_group_id = aws_security_group.rds.id
description = "Allow PostgreSQL access from ***** VPC"
}Так же сразу сделал отдельного пользователя в БД с чётко обрезанными правами.
Делал что-то ещё, и в целом был удовлетворён, что тварь какая-то ходит в мои сети.
Прошло много лет.
Ко мне приходят ребята инженеры, говорят хотят добавить новую БД для retool.
Уже подключена монга, mysql и всякое, а теперь надо и PostgreSQL.
Ок, говорю, ну там всё уже настроено - все ssh ключи, секьюрити группы и прочее - всё должно работать - другие то ресурсы(БД) работает до сих пор.
Берите креды и сами настраиваете, мы же договорились, что не должно быть боттлнека -девопса.
Они высылают скрин, что ошибка подключения. Я само собой не верю (бл, когда я научусь думать, что другие люди не глупее меня
Иду сам в retool, копирую все креды, создаю ресурс, но у меня тоже ошибка.
Извиняюсь перед ребятами, пилю тикет, начинаю разбираться.
Please open Telegram to view this post
VIEW IN TELEGRAM
😱3
#troubleshooting #aws #ssh #retool #paranoia #linux
Ок, что же говорит ошибка. Текст типа
и дальше огромная простыня трейса.
А ничего она не говорит, и так понятно, ясно понятно, нет подключения.
Прохожу снова по инструкции - всё ок.
Проверяю не менялся ли паблик ключ? Не менялся.
Не менялся ли пул публичных адресов? Не менялся.
Блин, ну я же не дурак.
Добавляю руками свой IP на секьюрити группу, подключаюсь на бастион хост и оттуда делаю телнет и подключение через cli к PostgreSQL.
Сетевая связность есть, коннект.
Проверяю ещё раз все секьюрити группы, поиск по коммитам, всё отлично.
Так, стоп, а предыдущие то ресурсы работают?
Захожу в
Чешу репу, гуглю решения, закидываю в 3 нейронки - решения нет.
Общие предположения, да и только.
В общем в траблшутинге и логах я просидел долго.
Чтобы не было стыдно, не буду говорить сколько, но много.
В итоге я просто начал смотреть все журналы, все конфиги и даже трейсы, мне было очень интересно.
Очевидно же, что у меня что-то не так, иначе бы ранее добавленные ресурсы не работали.
Спустя время дошёл до конца файла
А там паранойя, ну прям рили паранойя.
Я даже сам забыл про эту паранойю!
В общем добавляю очевидное
Перезапускаю
и Voilà! - коннект от
Описываюсь ребятам, они подтверждают, закрываю задачу.
Какая же мораль? Как обычно:
- не думай, что остальные глупее тебя, если пишут ошибка есть - значит она есть!
- вспоминай о своих параноидальных привычках, прежде, чем тратить время
- держи конфиг sshd в IaC (
* адреса endpoints к БД само собой должны быть полными и длинными, короткие URL лишь для примера
Ок, что же говорит ошибка. Текст типа
Test connection failed (120.327s):(SSH) Channel open failure: open failed
{query: "Connect Request", error: Object}
query: "Connect Request"
error: Object
message: "(SSH) Channel open failure: open failed"
data: Object
reason: 1
name: "Error"
message: "(SSH) Channel open failure: open failed"
и дальше огромная простыня трейса.
А ничего она не говорит, и так понятно, ясно понятно, нет подключения.
Прохожу снова по инструкции - всё ок.
Проверяю не менялся ли паблик ключ? Не менялся.
Не менялся ли пул публичных адресов? Не менялся.
Блин, ну я же не дурак.
Добавляю руками свой IP на секьюрити группу, подключаюсь на бастион хост и оттуда делаю телнет и подключение через cli к PostgreSQL.
Сетевая связность есть, коннект.
Проверяю ещё раз все секьюрити группы, поиск по коммитам, всё отлично.
Так, стоп, а предыдущие то ресурсы работают?
Захожу в
retool, в давно созданные ресурсы - тест проходит ок.Чешу репу, гуглю решения, закидываю в 3 нейронки - решения нет.
Общие предположения, да и только.
В общем в траблшутинге и логах я просидел долго.
Чтобы не было стыдно, не буду говорить сколько, но много.
В итоге я просто начал смотреть все журналы, все конфиги и даже трейсы, мне было очень интересно.
Очевидно же, что у меня что-то не так, иначе бы ранее добавленные ресурсы не работали.
Спустя время дошёл до конца файла
/etc/ssh/sshd_config перебирая по одному все включённые параметры, а там.... а там парам-пам-пам!А там паранойя, ну прям рили паранойя.
# bastion host 1.2.3.4
cat /etc/ssh/sshd_config |grep -v "^#"
...
Match User retool
PermitTTY no
AllowTcpForwarding yes
PermitOpen mysql.amazonaws.com:3306 docdb.amazonaws.com:27017
ForceCommand /bin/echo "Shell disabled!"
Я даже сам забыл про эту паранойю!
В общем добавляю очевидное
...
PermitOpen mysql.amazonaws.com:3306 docdb.amazonaws.com:27017 postgresql.amazonaws.com:5432
...
Перезапускаю
sudo systemctl restart ssh
и Voilà! - коннект от
retool есть.Описываюсь ребятам, они подтверждают, закрываю задачу.
Какая же мораль? Как обычно:
- не думай, что остальные глупее тебя, если пишут ошибка есть - значит она есть!
- вспоминай о своих параноидальных привычках, прежде, чем тратить время
- держи конфиг sshd в IaC (
ansible например), а не руками заполняй, баран. Поиском по iac я быстро увидел бы причину* адреса endpoints к БД само собой должны быть полными и длинными, короткие URL лишь для примера
2🔥10
#linux
Самое сложное это переступить свои привычки и стереотипы.
Начал карьеру с VSCode/vim/IDEA - привыкаешь с хоткеям, интерфейсу, удобству.
С браузером так же. Пересесть на другое - неудобно, непривычно, неохота.
По Linux утилитам тоже самое, одни плюсы: часть уже есть в операционной системе по умолчанию, часть ты знаешь так, что даже без нейронки и хелпа на память помнишь синтаксис.
Зачем переходить на другое?
- Его надо отдельно ставить. Фу.
- Снова учить синтаксис. Больно, да.
Однако причины перейти всё же есть.
Скорость работы, удобство и новые фичи.
Конкретно для меня это user/human-friendly.
Для себя я нашёл эти и даже успел к ним привыкнуть:
Остальное тоже пробовал, но не прижилось.
Фигня для rustаманов-зумеров 😁 .
Шучу, просто не зашло по задачам 🤡 .
Ниже список репозиториев, где есть несколько современных утилит - замена/альтернатива привычных всем:
- https://github.com/ibraheemdev/modern-unix
- https://github.com/johnalanwoods/maintained-modern-unix
Как бонус (не замена, а просто общий список):
- https://github.com/agarrharr/awesome-cli-apps
- https://terminaltrove.com/list/
Самое сложное это переступить свои привычки и стереотипы.
Начал карьеру с VSCode/vim/IDEA - привыкаешь с хоткеям, интерфейсу, удобству.
С браузером так же. Пересесть на другое - неудобно, непривычно, неохота.
По Linux утилитам тоже самое, одни плюсы: часть уже есть в операционной системе по умолчанию, часть ты знаешь так, что даже без нейронки и хелпа на память помнишь синтаксис.
cat, sed, ping, du, df, grep, awkЗачем переходить на другое?
- Его надо отдельно ставить. Фу.
- Снова учить синтаксис. Больно, да.
Однако причины перейти всё же есть.
Скорость работы, удобство и новые фичи.
Конкретно для меня это user/human-friendly.
Для себя я нашёл эти и даже успел к ним привыкнуть:
cat ~/.tool-versions
...
jq 1.8.1
direnv 2.37.1
duf 0.9.1
dust 1.2.3
bat 0.25.0
yq 4.48.1
delta 0.18.2
...
Остальное тоже пробовал, но не прижилось.
Шучу, просто не зашло по задачам
Ниже список репозиториев, где есть несколько современных утилит - замена/альтернатива привычных всем:
- https://github.com/ibraheemdev/modern-unix
- https://github.com/johnalanwoods/maintained-modern-unix
Как бонус (не замена, а просто общий список):
- https://github.com/agarrharr/awesome-cli-apps
- https://terminaltrove.com/list/
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
#kubernetes #linux #база
Существует достаточно частая проблема: ошибки категории "
Когда копаешь в одно, а проблема в другом.
Инженеры Kubernetes иногда сталкиваются с крайне сбивающей с толку ошибкой при запуске пода:
Не зная причины этой ошибки, мы сперва тратим время на:
- просмотр что за PVC используются у деплоймента/пода.
- что за нода сейчас запустила этот под, нет ли нехватки места на самой ноде
- лезут в графану, в метрики и графики по нодам, подам, PV
- как разбиты разделы диска на нодах, что и сколько отдаётся эфемеркам
- чего там по айнодам (ну наконец-то пригодились эти знания!🕺 )
- и так далее
И это правильные мысли и план, это так же может быть причиной ошибки, но наш случай про другое.
Попытка найти строку "
Истинная причина кроется в тонком различии между единицами измерения CPU и памяти в спецификации ресурсов. Это особенно критично для Проецируемых томов (Projected Volumes), таких как Service Account Token (
https://kubernetes.io/docs/concepts/storage/projected-volumes/
Когда инженер по ошибке использует суффикс CPU (m) для лимита памяти, например:
-
-
- Ядро Linux получает запрос на монтирование
То есть в нашем случае ошибка "
❕Стоит понимать, что Kubernetes API сервер не считает "512m" для памяти ошибкой валидации.
Он принимает это как легальное значение (0.512 байта), что позволяет поду быть созданным, но приводит к сбою выполнения (runtime failure) при монтировании на ноде.
Решение очевидное:
всегда используйте бинарные единицы (IEC) для ресурсов памяти: Mi (мебибайты), Gi (гибибайты).
Может есть и другие, я только эти использовал всегда.
Чтобы превентивно избавляться от такой проблемы, используйте дополнительно:
- pre-commit hooks
- валидаторы cli в CI/CD процессе
Какие-то конкретные утилиты советовать не буду, оставлю ссылки для примера:
- https://github.com/instrumenta/kubeval (давно не обновлялся, но он работает ок)
- https://github.com/yannh/kubeconform
- https://github.com/kubernetes-sigs/kubectl-validate
Кстати, аналогичные ошибки встречаются при монтировании секретов, конфигмапов и других tmpfs-бэкендов, использующих лимиты памяти контейнера.
Существует достаточно частая проблема: ошибки категории "
misleading".Когда копаешь в одно, а проблема в другом.
Инженеры Kubernetes иногда сталкиваются с крайне сбивающей с толку ошибкой при запуске пода:
MountVolume.SetUp failed... no space left on device.
Не зная причины этой ошибки, мы сперва тратим время на:
- просмотр что за PVC используются у деплоймента/пода.
- что за нода сейчас запустила этот под, нет ли нехватки места на самой ноде
- лезут в графану, в метрики и графики по нодам, подам, PV
- как разбиты разделы диска на нодах, что и сколько отдаётся эфемеркам
- чего там по айнодам (ну наконец-то пригодились эти знания!
- и так далее
И это правильные мысли и план, это так же может быть причиной ошибки, но наш случай про другое.
Попытка найти строку "
no space left on device" в исходном коде Kubelet на GitHub также не дает результатов, потому что Kubelet не генерирует этот текст - он просто ретранслирует низкоуровневую ошибку, полученную от ядра Linux(или от рантайма, тут могу наврунькать).Истинная причина кроется в тонком различии между единицами измерения CPU и памяти в спецификации ресурсов. Это особенно критично для Проецируемых томов (Projected Volumes), таких как Service Account Token (
kube-api-access-*), которые монтируются как tmpfs (файловая система в RAM).https://kubernetes.io/docs/concepts/storage/projected-volumes/
Когда инженер по ошибке использует суффикс CPU (m) для лимита памяти, например:
resources:
limits:
memory: "512m" # Ошибка, должно быть "512Mi"!
-
Kubelet парсит "512m" для памяти как метрический милли, что равно 0.512 байта. Поскольку размер тома (tmpfs) должен быть целым числом, это значение округляется до 0 байт (или ничтожно малого значения). Kubelet использует этот 0 байт для установки максимального размера тома tmpfs.-
Kubelet использует этот лимит памяти для установки максимального размера тома tmpfs для Service Account токена- Ядро Linux получает запрос на монтирование
tmpfs с нулевым или ничтожно малым размером. Системный вызов mount завершается неудачей (из-за попытки выделить даже минимальный объём, обычно 1 страница = 4 KiB). и возвращает низкоуровневую ошибку ENOSPC ("No space left on device"), поскольку невозможно создать файловую систему (даже в RAM) с таким малым выделением ресурсов.То есть в нашем случае ошибка "
no space left on device" на самом деле означает: "Не удалось создать RAM-диск (tmpfs) требуемого объема, потому что выделенный размер (0 байт) некорректен".❕Стоит понимать, что Kubernetes API сервер не считает "512m" для памяти ошибкой валидации.
Он принимает это как легальное значение (0.512 байта), что позволяет поду быть созданным, но приводит к сбою выполнения (runtime failure) при монтировании на ноде.
Решение очевидное:
всегда используйте бинарные единицы (IEC) для ресурсов памяти: Mi (мебибайты), Gi (гибибайты).
Может есть и другие, я только эти использовал всегда.
Чтобы превентивно избавляться от такой проблемы, используйте дополнительно:
- pre-commit hooks
- валидаторы cli в CI/CD процессе
Какие-то конкретные утилиты советовать не буду, оставлю ссылки для примера:
- https://github.com/instrumenta/kubeval (давно не обновлялся, но он работает ок)
- https://github.com/yannh/kubeconform
- https://github.com/kubernetes-sigs/kubectl-validate
Кстати, аналогичные ошибки встречаются при монтировании секретов, конфигмапов и других tmpfs-бэкендов, использующих лимиты памяти контейнера.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤19👍9
#linux
В эпоху активного использования AI, агентов и автокомплитов я стал чаще допускать ошибки.
Чёртовы AI не глядя могут дропнуть нужные файлы:херак раз - и нет важного файла.
С git‑файлами особых опасений нет, но дополнительные вещи вроде
Возвращаюсь к основам и просто запрещаю удаление файла:
Проверить, что флаг установлен, можно так:
Если я сам (а не нейронка) когда‑нибудь захочу удалить файл, сначала придётся снять флаг, а уже потом удалять:
Флаг immutable защищает от:
- перезаписи файла
- случайного удаления
- случайного переименования
- случайного sudo rm -r по директории, где лежит этот файл*
* Будет ошибка типа Operation not permitted на файле, в то время как остальные файлы в директории будут удалены
Если immutable поставить на саму директорию через
Иногда очень полезно вернуться к базовым инструментам Linux и защитить важные файлы и от нейросетей, и от себя самого, который запускает команды, не глядя, как макака.
В эпоху активного использования AI, агентов и автокомплитов я стал чаще допускать ошибки.
Чёртовы AI не глядя могут дропнуть нужные файлы:
С git‑файлами особых опасений нет, но дополнительные вещи вроде
.env в репозитории, которые в гитигноре, или в системе типа ~/.kube/config всё ещё хочется сохранить.Возвращаюсь к основам и просто запрещаю удаление файла:
sudo chattr +i .env
Проверить, что флаг установлен, можно так:
lsattr .env
Если я сам (а не нейронка) когда‑нибудь захочу удалить файл, сначала придётся снять флаг, а уже потом удалять:
sudo chattr -i .env
sudo rm .env
Флаг immutable защищает от:
- перезаписи файла
- случайного удаления
- случайного переименования
- случайного sudo rm -r по директории, где лежит этот файл*
* Будет ошибка типа Operation not permitted на файле, в то время как остальные файлы в директории будут удалены
Если immutable поставить на саму директорию через
chattr +i dir, тогда уже нельзя будет ни создавать, ни удалять, ни переименовывать файлы внутри неё - это ещё более жёсткая защита, но это мне пока не надо.Иногда очень полезно вернуться к базовым инструментам Linux и защитить важные файлы и от нейросетей, и от себя самого, который запускает команды, не глядя, как макака.
👍18🙈6🙉4🙊4
#aws #eks #kubernetes #bottlerocket #troubleshooting #security #linux #CVE
Сорри за частые посты сегодня ☔️
Пока я был в отпуске и спал, снова сломали все интернеты.
В мае 2026 вышла пара свежих уязвимостей ядра linux в ос
- первая: CVE-2026-31431, она же Copy Fail
https://copy.fail
- вторая: Dirty Frag, смежная к первой
https://github.com/V4bel/dirtyfrag
Обе уязвимости это локальное повышение привилегий (LPE).
То есть если кто-то запустил код на вашей ноде, он может стать рутом.
В контексте Kubernetes это означает выход из контейнера на хост.
Первым делом пошёл смотреть, а вообще мы уязвимы или нет.
Способ 1:
Внутри:
Если в ответ получаете:
Вы не уязвимы на практике, даже если версия AMI старая.
Если модуль загрузился без ошибок, уязвимы, читайте дальше.
Способ 2: через SSM напрямую на ноду (только для Bottlerocket)
Это нативный способ для Bottlerocket.
Я писал об этом не раз, искать по тегу #bottlerocket
Подключаемся к ноде и проверяем модули:
Если пусто, модули не загружены.
Пробуем загрузить принудительно:
Если Operation not permitted, не уязвимы.
Почему у нас не сработало, хотя версия ядра старая
У нас EKS с Bottlerocket AMI.
Bottlerocket по умолчанию запускается с
В этом режиме загрузка не подписанных модулей через modprobe из пространства пользователя запрещена.
То есть Copy Fail + Dirty Frag требуют загрузить модуль algif_aead (или esp4/esp6/rxrpc как обход), но lockdown просто не даёт это сделать.
Это не значит, что можно расслабиться.
Это значит, что есть один слой защиты.
Defence-in-depth требует добавить второй явный слой и всё равно обновить ядро.
Что делать в любом случае: явно блокируем модули
Независимо от того уязвимы вы или нет, правильнее явно запретить загрузку этих модулей.
Один lockdown это хорошо, но явный запрет лучше.
Bottlerocket (Terraform, launch template + user data):
Добавляем в bottlerocket.tpl:
Это работает на уровне Bottlerocket API.
Он сам создаст нужные записи в /etc/modprobe.d/ при старте ноды.
Если у вас Karpenter, то добавляете в NodeClass или EC2NodeClass в секцию userData аналогичный блок для вашего distro.
Если у вас самописные Terraform-модули для нод-групп, то смотрите где у вас формируется user_data для launch template.
Добавляете туда блок выше.
Паттерн один и тот же, разница только в синтаксисе шаблона.
Как проверить что всё применилось
Для Bottlerocket есть нативный способ: через apiclient прямо с ноды, без debug подов и без sheltie.
Работает через SSM send-command из любого места где есть aws cli.
Узнаём instance ID:
Запускаем команду через SSM:
Смотрим результат:
Если всё применилось, увидите:
Если патч не применён, только lockdown, без modules:
Это показывает конфиг именно так, как его видит сама OS.
Лучше чем смотреть файлы руками.
Можно спать дальше🛌
Пока я был в отпуске и спал, снова сломали все интернеты.
В мае 2026 вышла пара свежих уязвимостей ядра linux в ос
- первая: CVE-2026-31431, она же Copy Fail
https://copy.fail
- вторая: Dirty Frag, смежная к первой
https://github.com/V4bel/dirtyfrag
Обе уязвимости это локальное повышение привилегий (LPE).
То есть если кто-то запустил код на вашей ноде, он может стать рутом.
В контексте Kubernetes это означает выход из контейнера на хост.
Первым делом пошёл смотреть, а вообще мы уязвимы или нет.
Способ 1:
kubectl debug node/<имя_ноды> -it --image=busybox -- sh
Внутри:
chroot /host modprobe algif_aead
Если в ответ получаете:
modprobe: ERROR: could not insert 'algif_aead': Operation not permitted
Вы не уязвимы на практике, даже если версия AMI старая.
Если модуль загрузился без ошибок, уязвимы, читайте дальше.
Способ 2: через SSM напрямую на ноду (только для Bottlerocket)
Это нативный способ для Bottlerocket.
Я писал об этом не раз, искать по тегу #bottlerocket
Подключаемся к ноде и проверяем модули:
cat /proc/modules | grep -E 'algif_aead|esp4|esp6|rxrpc'
Если пусто, модули не загружены.
Пробуем загрузить принудительно:
modprobe algif_aead
Если Operation not permitted, не уязвимы.
Почему у нас не сработало, хотя версия ядра старая
У нас EKS с Bottlerocket AMI.
Bottlerocket по умолчанию запускается с
kernel.lockdown = integrity.
В этом режиме загрузка не подписанных модулей через modprobe из пространства пользователя запрещена.
То есть Copy Fail + Dirty Frag требуют загрузить модуль algif_aead (или esp4/esp6/rxrpc как обход), но lockdown просто не даёт это сделать.
Это не значит, что можно расслабиться.
Это значит, что есть один слой защиты.
Defence-in-depth требует добавить второй явный слой и всё равно обновить ядро.
Что делать в любом случае: явно блокируем модули
Независимо от того уязвимы вы или нет, правильнее явно запретить загрузку этих модулей.
Один lockdown это хорошо, но явный запрет лучше.
Bottlerocket (Terraform, launch template + user data):
Добавляем в bottlerocket.tpl:
[settings.kernel]
lockdown = "integrity"
[settings.kernel.modules.algif_aead]
allowed = false
[settings.kernel.modules.esp4]
allowed = false
[settings.kernel.modules.esp6]
allowed = false
[settings.kernel.modules.rxrpc]
allowed = false
Это работает на уровне Bottlerocket API.
Он сам создаст нужные записи в /etc/modprobe.d/ при старте ноды.
Если у вас Karpenter, то добавляете в NodeClass или EC2NodeClass в секцию userData аналогичный блок для вашего distro.
Если у вас самописные Terraform-модули для нод-групп, то смотрите где у вас формируется user_data для launch template.
Добавляете туда блок выше.
Паттерн один и тот же, разница только в синтаксисе шаблона.
Как проверить что всё применилось
Для Bottlerocket есть нативный способ: через apiclient прямо с ноды, без debug подов и без sheltie.
Работает через SSM send-command из любого места где есть aws cli.
Узнаём instance ID:
kubectl get node <имя_ноды> -o jsonpath='{.spec.providerID}' | sed 's|.*\/||'Запускаем команду через SSM:
aws ssm send-command \
--instance-ids <instance-id> \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["apiclient get settings.kernel"]' \
--region us-east-1
Смотрим результат:
aws ssm get-command-invocation \
--command-id <command-id> \
--instance-id <instance-id> \
--region us-east-1 \
--query 'StandardOutputContent' \
--output text
Если всё применилось, увидите:
{
"settings": {
"kernel": {
"lockdown": "integrity",
"modules": {
"algif_aead": { "allowed": false },
"esp4": { "allowed": false },
"esp6": { "allowed": false },
"rxrpc": { "allowed": false }
}
}
}
}Если патч не применён, только lockdown, без modules:
{
"settings": {
"kernel": {
"lockdown": "integrity"
}
}
}Это показывает конфиг именно так, как его видит сама OS.
Лучше чем смотреть файлы руками.
Можно спать дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥2❤1
#devops #linux #security
Только-только отгремели два LPE
- https://copy.fail/
- https://github.com/V4bel/dirtyfrag
Не успели донести ещё до продакшна изменения-фиксы, так уже третья проблема прилетела.
- https://github.com/v12-security/pocs/tree/main/fragnesia
Какой ад, если честно🤦♂️ 🤦♂️ 🤦♂️
Чот всё как-то проклято с этими LPE.
Ведь точно не последняя будет с такой-то волной интереса и доступностью AI агентов и ассистентов.
Только-только отгремели два LPE
- https://copy.fail/
- https://github.com/V4bel/dirtyfrag
Не успели донести ещё до продакшна изменения-фиксы, так уже третья проблема прилетела.
- https://github.com/v12-security/pocs/tree/main/fragnesia
Какой ад, если честно
Чот всё как-то проклято с этими LPE.
Ведь точно не последняя будет с такой-то волной интереса и доступностью AI агентов и ассистентов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8