Linux Ready | DevOps
11.8K subscribers
1.09K photos
78 videos
588 links
Авторский канал по разработке на Linux.
Ресурсы, обучения, задачи, шпаргалки.
Ежедневно информация пополняется!

Cотрудничество: @energy_c

Реклама на бирже: https://telega.in/channels/linux_ready/card
Download Telegram
👩‍💻 Изолируем программы от файловой системы через Bubblewrap!

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

В этом посте:
• Создаём изолированное файловое окружение через bwrap;

• Предоставляем доступ только к выбранным каталогам;

• Разграничиваем права на чтение и запись внутри окружения;

• Ограничиваем сетевой доступ с помощью —unshare-net.


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

🚪 Linux Ready | #гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤6🔥6🤝2
В Linux можно передать уже открытый сетевой сокет другому процессу без повторного открытия порта!

Этот механизм называется socket activation. Его поддерживает systemd: он сам открывает порт и передаёт готовый файловый дескриптор запускаемому сервису.

Например, можно создать сокет для приложения:
# /etc/systemd/system/myapp.socket
[Socket]
ListenStream=8080

[Install]
WantedBy=sockets.target


После включения сокета systemd начинает слушать порт, даже если приложение ещё не запущено:
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.socket


Когда приходит подключение, ядро ставит его в очередь, а systemd запускает myapp.service и передаёт ему слушающий сокет. Для работы нужен соответствующий unit-файл и приложение с поддержкой socket activation (например, через LISTEN_FDS). Обычный сервер, самостоятельно вызывающий bind(), без адаптации не подойдёт.

Проверить состояние можно так:
systemctl status myapp.socket
systemctl list-sockets


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

🔥 Socket activation позволяет отделить владение сетевым портом от жизненного цикла приложения. Полезно для сервисов с редкими запросами, запуска по требованию и сокращения перерывов при перезапуске.

🚪 Linux Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥6❤4🤝2
This media is not supported in your browser
VIEW IN TELEGRAM
✍️ linux-book — большое руководство по Linux на русском языке!

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

Оставляю ссылочку: GitHub 📱


🚪 Linux Ready | #репозиторий
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤11🔥7
Как диагностировать проблемы с MTU и Path MTU Discovery в линукс?

TCP-соединение установилось, мелкие пакеты проходят, а передача данных зависает? Возможно, поймали PMTU black hole: крупные пакеты с DF отбрасываются, а ICMP Fragmentation Needed не доходит до отправителя. Такое встречается с VPN, GRE и VXLAN.

Начнём с MTU интерфейса:
ip -d link show dev eth0


Например:
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500


Но MTU 1500 на интерфейсе ещё не означает, что пакеты такого размера пройдут весь маршрут.

Проверим маршрут:
ip -4 route get 203.0.113.10


Теперь отправим IPv4-пакет размером 1500 байт с запретом фрагментации:
ping -4 -M do -s 1472 -c 3 203.0.113.10


Размер: 1472 байта данных + 8 байт ICMP + 20 байт IPv4. Если пакет не проходит, попробуем 1400 байт:
ping -4 -M do -s 1372 -c 3 203.0.113.10


Если меньшие пакеты проходят, а большие нет — есть повод проверить Path MTU.

Отсутствие ответа на ping ещё не доказывает проблему с MTU. Кроме того, -M do учитывает уже известный ядру PMTU. Для проверки в обход этого ограничения можно использовать:
sudo ping -4 -M probe -s 1472 -c 3 203.0.113.10


Для дополнительной диагностики запустим:
tracepath -n 203.0.113.10


Утилита может показать обнаруженное ограничение:
pmtu 1400


Результат зависит от прохождения ICMP. В Debian/Ubuntu tracepath доступен в пакете iputils-tracepath.

Теперь посмотрим, какой PMTU известен ядру:
ip -4 route get 203.0.113.10


Если информация сохранена, вывод может содержать:
cache expires 420sec mtu 1400


Для действующего TCP-соединения проверим MSS и PMTU:
ss -tin dst 203.0.113.10


Например:
mss:1360 pmtu:1400


При стандартных 20-байтных заголовках IPv4 и TCP получаем MSS 1360. Фактические значения могут отличаться.

В линукс есть и встроенный механизм TCP MTU probing, который помогает при проблемах с определением MTU. Проверим его состояние:
sysctl net.ipv4.tcp_mtu_probing


Возможные значения:
0 — отключён
1 — включается при обнаружении проблемы
2 — включён постоянно


Сохраним исходное значение и временно включим механизм:
original=$(sysctl -n net.ipv4.tcp_mtu_probing)
sudo sysctl -w net.ipv4.tcp_mtu_probing=1


Повторим проблемную передачу через новое TCP-соединение. Если заработало — это дополнительный аргумент в пользу проблемы с PMTUD. Но механизм может сработать не сразу, а отсутствие улучшения не исключает проблему.

Вернём исходное значение:
sudo sysctl -w net.ipv4.tcp_mtu_probing="$original"


Механизм работает только для TCP в соответствующем сетевом пространстве имён и не заменяет правильную настройку MTU туннелей. Все проверки рассчитаны на IPv4. В IPv6 для обнаружения ограничений используется ICMPv6 Packet Too Big.

Адрес 203.0.113.10 приведён для примера. Замените его на адрес доступного узла, где воспроизводится проблема, а eth0 — на свой интерфейс.

🔥 PMTU black hole — одна из причин, почему TCP-соединение есть, а нормальной передачи данных нет. Проверка DF-пакетов, tracepath, PMTU и MSS помогает найти ограничение на маршруте, особенно в сетях с VPN и туннелями.

🚪 Linux Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍9❤7
❤️ Необычная и крайне интересная статья на Хабре: «Пустили ботов по SSH на фейковый сервер с четырьмя H100: что они там делали»!

В этой статье:
• Узнаете, как с помощью Python и Cowrie создать SSH-ловушку, имитирующую мощный сервер с четырьмя NVIDIA H100;
• Посмотрите, что делали атакующие боты после входа: меняли пароли, добавляли SSH-ключи и пытались установить майнеры;
• Разберёте результаты первых 12,5 часов эксперимента — 1 846 подключений и более 1 500 команд — и способы защиты SSH от подобных атак.

🔊 Продолжай читать на Habr!


🚪 Linux Ready | #статья
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍8🤝4❤2
В Git можно переносить незавершённые изменения между проектами или рабочими деревьями без коммитов и копирования файлов вручную!

Для этого достаточно обычного патча. Git умеет сохранить изменения в текстовый файл, а затем применить их в другом каталоге.
git diff > changes.patch


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

Перед применением полезно проверить, получится ли внести изменения:
git apply --check changes.patch


Если проверка прошла успешно, применяем:
git apply changes.patch


А если нужно перенести и изменения, уже добавленные в индекс, используйте:
git diff HEAD > changes.patch


Важно: новые неотслеживаемые файлы в такой патч автоматически не попадут.

🔥 git diff вместе с git apply — удобный способ переносить локальные правки между рабочими деревьями, тестовыми окружениями и копиями проекта без промежуточных коммитов.

🚪 Linux Ready | #совет
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤8🔥6
Почему линукс может показывать разные файлы по одному и тому же пути?

В линукс два процесса могут обращаться к /tmp, /etc или /var, но фактически видеть разные файловые системы. Причём для этого необязательно использовать docker или полноценный контейнер.

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

Проверим на практике. Сначала создадим тестовый каталог:
sudo mkdir -p /mnt/ns-test
echo "original" | sudo tee /mnt/ns-test/file


Теперь запустим отдельное пространство имён монтирования:
sudo unshare --mount --propagation private /bin/bash


Внутри новой оболочки смонтируем tmpfs поверх существующего каталога:
mount -t tmpfs tmpfs /mnt/ns-test
echo "isolated" > /mnt/ns-test/file
cat /mnt/ns-test/file


Результат:
isolated


Откроем второй терминал и выполним:
cat /mnt/ns-test/file


Здесь результат будет другим:
original


Оба процесса используют одинаковый абсолютный путь, но обращаются к разным объектам файловой системы.

Посмотреть пространства имён процессов можно через:
readlink /proc/self/ns/mnt


А для конкретного процесса:
readlink /proc/PID/ns/mnt


Если идентификаторы отличаются, процессы находятся в разных mount namespaces. Однако это ещё не означает, что их таблицы монтирования обязательно различаются.

Посмотреть реальные точки монтирования процесса:
cat /proc/PID/mountinfo


Можно также войти в существующее пространство имен другого процесса:
sudo nsenter --target PID --mount -- /bin/bash


После этого новая оболочка будет использовать его mount namespace. Именно этот механизм применяется в контейнерах и при изоляции сервисов systemd. Например, параметр PrivateTmp=yes позволяет сервису получить отдельные пространства для временных файлов в /tmp и /var/tmp.

Поэтому файл, созданный сервисом в /tmp, может быть недоступен по тому же пути из обычной пользовательской оболочки. После эксперимента выйдем из изолированной оболочки командой exit и удалим тестовый каталог:
sudo rm -rf /mnt/ns-test


🔥 Абсолютный путь в линукс не гарантирует обращение к одному и тому же файлу. При диагностике контейнеров и systemd-сервисов проверяйте не только путь, но и mount namespace процесса. Особенно если приложение видит файл, который отсутствует на хосте, или наоборот.

🚪 Linux Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥9❤8
👩‍💻 Откатывай изменения файлов без Git с помощью Linux!

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

Как работает:
• cp -a создаёт резервную копию файла с сохранением прав доступа, владельца и временных меток;

• nginx -t проверяет синтаксис и корректность конфигурации до применения изменений;

• повторный cp -a позволяет восстановить исходную версию файла, если новая конфигурация оказалась неудачной;

• && гарантирует, что systemctl reload nginx выполнится только после успешной проверки.


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

🚪 Linux Ready | #фишка
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤9👍6👎1🤝1
Как диагностировать переполнение TCP listen backlog в линукс?

Под нагрузкой TCP-сервис может терять новые подключения или увеличивать время их установления, хотя CPU не перегружен, а существующие соединения работают стабильно. Одна из возможных причин — переполнение accept queue, в которой завершённые TCP-подключения ожидают обработки через accept().

Размер очереди определяется аргументом backlog при вызове listen() и ограничивается net.core.somaxconn. Проверим listening socket на порту 443:
ss -lnt '( sport = :443 )'


Для TCP-сокета в состоянии LISTEN поле Recv-Q показывает количество соединений, ожидающих accept(), а Send-Q — максимальную длину очереди. Следующий результат указывает на её заполнение в момент измерения:
State   Recv-Q Send-Q Local Address:Port
LISTEN 128 128 0.0.0.0:443


Заполненная очередь ещё не доказывает потери подключений. Проверим системный лимит и счётчики переполнений TCP-стека:
sysctl net.core.somaxconn

nstat -az | grep -E \
'TcpExtListenOverflows|TcpExtListenDrops'


ListenOverflows учитывает события переполнения, а ListenDrops — более широкий набор отказов при обработке подключений. Счётчики относятся ко всему network namespace и не отражают точное количество уникальных потерянных соединений.

Для оценки динамики измерим прирост счётчиков за 30 секунд, используя два снимка статистики ядра.
nstat -az > /tmp/tcp-before.nstat
sleep 30
nstat -az > /tmp/tcp-after.nstat

awk '
NR == FNR { before[$1] = $2; next }
/^TcpExtListen(Overflows|Drops)[[:space:]]/ {
printf "%s: +%.0f\n", $1, $2 - before[$1]
}
' /tmp/tcp-before.nstat /tmp/tcp-after.nstat


Если ListenOverflows растёт одновременно с заполнением Recv-Q, необходимо проверить интенсивность обработки соединений приложением. Через bpftrace подсчитаем успешные вызовы accept4() процесса с PID 2451:
sudo bpftrace -e '
tracepoint:syscalls:sys_exit_accept4
/pid == 2451 && args->ret >= 0/
{
@accepted = count();
}

interval:s:1
{
print(@accepted);
clear(@accepted);
}'


Измерение приблизительное: оно не учитывает обычный accept() и другие процессы, а вывод и очистка счётчика не атомарны. Для многопроцессных серверов требуется учитывать всех обработчиков соединений.

От accept queue необходимо отличать SYN queue, которая используется при незавершённых TCP-handshake. Проверим параметры и статистику её переполнения:
sysctl net.ipv4.tcp_max_syn_backlog
sysctl net.ipv4.tcp_syncookies

nstat -az | grep -E \
'TcpExtSyncookiesSent|TcpExtTCPReqQFull'


Рост SyncookiesSent может указывать на давление на SYN queue, но не обязательно свидетельствует о SYN flood. Фактическое поведение зависит от конфигурации сокета и реализации TCP в ядре.

При переполнении accept queue параметр tcp_abort_on_overflow влияет на возможность сброса подключений через RST:
sysctl net.ipv4.tcp_abort_on_overflow


При значении 0 ядро обычно допускает повторную обработку подключения, что может увеличивать задержки. Значение 1 позволяет отправлять RST, но не устраняет причину перегрузки.

Если используется SO_REUSEPORT, несколько listening sockets могут обслуживать один порт с независимыми accept queues. Проверять их необходимо отдельно:
sudo ss -lntpe '( sport = :443 )'


🔥 Переполнение TCP listen backlog диагностируется по совокупности показателей: заполненности Recv-Q, динамике ListenOverflows и ListenDrops, интенсивности accept() и состоянию SYN queue. При подтверждённой перегрузке следует исследовать обработчики соединений, блокировки event loop и распределение нагрузки до изменения системных лимитов.

🚪 Linux Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥8❤6
👩‍💻 Ограничиваем доступ Linux-сервиса к файловой системе через systemd!

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

В этом посте:
• Настраиваем ограничения через ProtectSystem, ProtectHome и PrivateTmp;

• Выделяем отдельный каталог для записи с помощью StateDirectory;

• Проверяем доступ к системным и разрешённым каталогам через nsenter;

• Оцениваем параметры изоляции службы с помощью systemd-analyze security.


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

🚪 Linux Ready | #гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍6❤5
Gemini Pro на 24 месяца за 800₽!

Вместо 39.000₽ — всего 800₽ ($9.9) за 2 года. По акции сейчас это 33₽ в месяц, в 48 раз выгоднее!

➡Argon 4.0 + Claude Opus 5.5 — для кода
➡Nano Banana 2 Pro — для картинок
➡Генерация видео — ролики и анимации
➡AntiGravity + 5 ТБ облака
➡Opus 5.5 и Sonnet 5.5
➡Youtube Premium

Акция ограничена по времени, дальше будет официальная цена 480$!


Приобрести можно в Магазине с 20.000+ покупок и 2000+ отзывов (есть возвраты и замены).
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6👎4❤1🤝1
Как ограничить linux-сервису запись в файловую систему через systemd?

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

Для этого используются ProtectSystem=strict и ReadWritePaths. Они ограничивают запись через отдельное пространство монтирования (mount namespace), не изменяя глобальные права файлов.

Практика рассчитана на обычную линукс систему с systemd и поддержкой mount namespaces. В контейнерах с ограниченными привилегиями поведение может отличаться. Создадим каталог для данных приложения:
sudo mkdir -p /var/lib/test-app


Создадим тестовый сервис, который попытается записать файлы в разрешённый каталог и в защищённый /etc:
sudo tee /etc/systemd/system/test-app.service >/dev/null <<'EOF'
[Unit]
Description=Filesystem isolation test

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'touch /var/lib/test-app/ok && touch /etc/test-app-file'
ProtectSystem=strict
ReadWritePaths=/var/lib/test-app
EOF


Сервис намеренно запускается от root (без User=), чтобы продемонстрировать именно ограничения systemd, а не обычные права доступа к файлам. ProtectSystem=strict делает почти всю файловую иерархию доступной только для чтения внутри mount namespace сервиса, за исключением отдельных API-файловых систем.

ReadWritePaths исключает /var/lib/test-app из ограничения read-only, но не отменяет обычные права доступа и не позволяет записывать данные на файловую систему, изначально смонтированную только для чтения.

Убедимся, что тестовый файл в /etc отсутствует:
if [ -e /etc/test-app-file ] || [ -L /etc/test-app-file ]; then
echo "Ошибка: /etc/test-app-file уже существует"
else
sudo systemctl daemon-reload
sudo systemctl start test-app.service
fi


На типичной системе запуск завершится ошибкой: первая операция touch выполнится успешно, а вторая получит EROFS (Read-only file system). Поскольку используется Type=oneshot, юнит перейдёт в состояние failed.

Проверим результат и журнал сервиса:
test -f /var/lib/test-app/ok && echo "OK: запись разрешена"

if [ ! -e /etc/test-app-file ] && [ ! -L /etc/test-app-file ]; then
echo "OK: файл в /etc не создан"
fi

journalctl -u test-app.service -n 20 --no-pager


Первый файл должен существовать, второй — отсутствовать, а журнал должен содержать ошибку записи в /etc. Совокупность этих результатов подтверждает ожидаемое поведение изоляции. Если первый файл не создан, необходимо проверить журнал и причину сбоя.

Проверим загруженные параметры изоляции и оценим конфигурацию безопасности:
systemctl show test-app.service \
-p ProtectSystem \
-p ReadWritePaths

systemd-analyze security test-app.service


systemd-analyze security оценивает защитные настройки юнита, но не проверяет фактические права записи.

При этом ProtectSystem не изолирует сеть и процессы. Сервис с достаточными привилегиями, в частности с CAP_SYS_ADMIN, потенциально способен изменять ограничения монтирования. После проверки удалим тестовое окружение:
sudo systemctl stop test-app.service
sudo rm -f /etc/systemd/system/test-app.service
sudo rm -rf /var/lib/test-app
sudo systemctl daemon-reload
sudo systemctl reset-failed test-app.service


🔥 ProtectSystem=strict совместно с ReadWritePaths позволяет ограничить запись сервиса без изменения глобальных прав файловой системы. В продакшене эти настройки рекомендуется дополнять User, NoNewPrivileges и CapabilityBoundingSet, а для управления каталогами данных использовать StateDirectory.

🚪 Linux Ready | #практика
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥6❤4🤝1
📂 Шпаргалка по архитектуре Ansible!

Ansible позволяет автоматизировать настройку серверов, развертывание приложений и управление инфраструктурой без установки агентов на управляемые узлы.

На картинке — схема архитектуры Ansible: взаимодействие управляющего узла с серверами по SSH, а также основные компоненты — Inventory, ansible.cfg и Playbook.

Сохрани, чтобы не потерять!

🚪 Linux Ready | #ресурс
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍6🔥4