BashTex | Linux
2.5K subscribers
72 photos
13 videos
457 links
Авторский канал для тех, кто хочет глубже погрузиться в мир Linux.

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

Реклама: @dad_admin
Download Telegram
Как найти процессы, которые активно пишут на диск

1️⃣ iotop - самый быстрый способ


sudo iotop -o


Ключ -o показывает только процессы с активным I/O.

Для вывода без интерактивного режима:


sudo iotop -o -b -n 5


-b - batch mode
-n 5 - 5 обновлений и выход

Смотрите на колонки: DISK WRITE и COMMAND

2️⃣ pidstat - запись по процессам


pidstat -d 1


Показывает дисковую активность процессов каждую секунду. Главная колонка: kB_wr/s. Она показывает скорость записи на диск. Пример:


PID kB_rd/s kB_wr/s Command
1245 0.00 820.00 rsyslogd
2178 0.00 4096.00 mysqld


3️⃣ Проверка через /proc. У каждого процесса есть файл:


/proc/<PID>/io


Посмотреть статистику:


sudo cat /proc/<PID>/io


Ищем строку: write_bytes: Она показывает, сколько байт процесс записал с момента запуска.

Быстрый топ процессов по записи:


for pid in /proc/[0-9]*; do
[[ -r "$pid/io" ]] || continue
wb=$(awk '/write_bytes/ {print $2}' "$pid/io" 2>/dev/null)
cmd=$(cat "$pid/comm" 2>/dev/null)
[[ "$wb" -gt 0 ]] && echo "$wb PID=${pid##*/} $cmd"
done | sort -nr | head


4️⃣ Какие файлы пишет процесс


sudo lsof -p <PID>


Например:


sudo lsof -p 2178


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

5️⃣ Небольшая итоговая шпаргалка


sudo iotop -o


Кто пишет на диск прямо сейчас.


pidstat -d 1


Скорость чтения/записи по процессам.


sudo cat /proc/<PID>/io


I/O-статистика процесса.


sudo lsof -p <PID>


Какие файлы открыл процесс.

BashTex 📱 #storage
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Скрипт проверки зависших mount

Иногда сервер начинает странно тормозить: команда df -h зависает, ls не отвечает, а проблема оказывается в примонтированной NFS/SMB/сетевой ФС. Причина простая: mount есть, но I/O к нему не отвечает.

Проверить это можно через связку: timeout + stat. Можно выполнить stat для точки монтирования, но ограничить время ожидания.

▪️ Пример ручной проверки


timeout 3 stat /mnt/backup


Если ФС отвечает - увидим информацию о каталоге. Если команда зависла и была остановлена по таймауту - mount подозрительный.

🛠 Скрипт проверки всех mount


#!/usr/bin/env bash

TIMEOUT=3

findmnt -rn -o TARGET | while read -r mountpoint; do
if timeout "$TIMEOUT" stat "$mountpoint" >/dev/null 2>&1; then
echo "OK: $mountpoint"
else
echo "HANG: $mountpoint"
fi
done


Сохраняем:


nano check-mounts.sh


Делаем исполняемым:


chmod +x check-mounts.sh


Запускаем:


sudo ./check-mounts.sh


Пример вывода


OK: /
OK: /boot
OK: /home
HANG: /mnt/backup
HANG: /mnt/nfs-share


🛠 Также можно проверять только сетевые ФС


#!/usr/bin/env bash

TIMEOUT=3

findmnt -rn -t nfs,nfs4,cifs,smb3 -o TARGET | while read -r mountpoint; do
if timeout "$TIMEOUT" stat "$mountpoint" >/dev/null 2>&1; then
echo "OK: $mountpoint"
else
echo "HANG: $mountpoint"
fi
done


Такой вариант удобнее для серверов, где много локальных mount.

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

▪️ Быстрая проверка одной строкой


findmnt -rn -o TARGET | while read -r mp; do
timeout 3 stat "$mp" >/dev/null 2>&1 \
&& echo "OK: $mp" \
|| echo "HANG: $mp"
done


BashTex 📱 #mount #script
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13
systemd.path: запуск действия при изменении файла

Многие задачи автоматизации до сих пор решают через бесконечные циклы:

while true; do
if [ -f /tmp/reload ]; then
systemctl restart myapp
rm /tmp/reload
fi
sleep 5
done


Работает, но процесс постоянно висит в памяти и каждые несколько секунд проверяет состояние файловой системы.

▪️ Что есть лучше

В systemd существует специальный тип юнитов — .path.

Он использует inotify и реагирует на реальные изменения файлов или директорий, а не занимается постоянным опросом.

Пример: нужно перезапускать сервис после изменения конфигурации.

Создаем path-юнит:

[Path]
PathModified=/etc/myapp/config.yml

[Install]
WantedBy=multi-user.target
И связанный сервис:
[Service]
Type=oneshot
ExecStart=/bin/systemctl restart myapp.service
Активируем:
systemctl daemon-reload
systemctl enable --now myapp.path


Теперь изменение файла автоматически вызовет запуск сервиса.

▪️ Что умеет отслеживать

Не только изменение файла:

PathExists=/tmp/file
PathChanged=/var/log/app.log
DirectoryNotEmpty=/var/spool/tasks


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

▪️ Почему это удобно
Вместо собственных демонов, cron и циклов с sleep получаем событийную модель: пока ничего не происходит - не расходуются ресурсы. Как только происходит нужное событие - systemd запускает действие.

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
flock: защита от повторного запуска скрипта

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

Например, cron запускает задачу каждые 5 минут, но одна из прошлых итераций ещё не завершилась.

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

▪️Типичная ошибка

Допустим, скрипт выполняется 10 минут, а cron запускает его каждые 5:

*/5 * * * * /opt/backup.sh


Через некоторое время одновременно будут работать сразу несколько экземпляров.

▪️Решение через flock
Самый простой вариант - добавить блокировку:

flock -n /tmp/backup.lock /opt/backup.sh


Если lock-файл уже занят другим процессом, новая копия просто не запустится.

Ключ -n означает “не ждать освобождения блокировки”.

▪️Использование внутри скрипта

Можно защитить сам скрипт независимо от способа запуска:

exec 200>/var/run/myjob.lock

flock -n 200 || {
echo "Already running"
exit 1
}


Теперь второй экземпляр завершится сразу после старта.

▪️Чем лучше PID-файлов
Многие делают так:

echo $$ > /tmp/script.pid


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

▪️Где особенно полезно
Бэкапы, синхронизация файлов, обработка очередей, обновление данных, cron-задачи и любые скрипты, которые нельзя запускать параллельно.

BashTex 📱 #scripts #flock
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
PIPESTATUS: как узнать, где именно сломался пайп

Большинство администраторов знают про $?, но при работе с пайпами он может вводить в заблуждение.

Посмотрим на пример:

grep ERROR app.log | sort | uniq
echo $?


Если пайп состоит из нескольких команд, $? покажет код возврата только последней из них.

Если grep завершился с ошибкой, а uniq отработал успешно, вы увидите:

0


Хотя одна из команд фактически провалилась.

▪️Решение - PIPESTATUS

После выполнения пайпа Bash сохраняет коды возврата всех его команд в массиве PIPESTATUS:

grep ERROR app.log | sort | uniq

echo "${PIPESTATUS[@]}"


Результат может выглядеть так:

2 0 0


Здесь видно, что ошибка произошла именно в grep.

▪️Проверка конкретного этапа

Можно обратиться к нужному элементу массива:

grep ERROR app.log | sort | uniq

echo "${PIPESTATUS[0]}"


Проверяем первую команду в цепочке.

echo "${PIPESTATUS[1]}"


Проверяем вторую.

▪️А что насчёт pipefail?

Многие включают:

set -o pipefail


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

Но pipefail не показывает, какой именно этап завершился неудачно.
Для диагностики всё равно пригодится PIPESTATUS.

▪️Почему это важно

Если в скрипте есть длинные цепочки из grep, awk, sed, jq, sort и других утилит, обычный $? может скрыть проблему. PIPESTATUS позволяет быстро понять, где именно произошёл сбой.

BashTex 📱 #scripts #pipestatus
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
Почему журналы journald могут неожиданно заполнить диск

На сервере закончилось место, а в /var/log ничего подозрительного нет?

Часто виновником оказывается journald.

▪️Где хранятся логи

Проверить объём журналов можно одной командой:

journalctl --disk-usage


Например:

Archived and active journals take up 2.8G on disk.


На серверах с большим количеством сервисов объём может расти довольно быстро.

▪️Посмотреть самые “тяжёлые” журналы

Узнать, сколько данных записывается за последние сутки:

journalctl --since yesterday | wc -l


А если какой-то сервис генерирует тысячи сообщений в минуту:

journalctl -u myapp.service


Обычно проблема находится довольно быстро.

▪️Как очистить старые журналы

Оставить только последние 500 МБ:

journalctl --vacuum-size=500M


Или удалить записи старше 14 дней:

journalctl --vacuum-time=14d


Очистка происходит без остановки journald.

▪️Ограничение роста журналов

Настройки находятся в:

/etc/systemd/journald.conf


Например:

SystemMaxUse=1G
SystemKeepFree=2G


После изменения конфигурации:

systemctl restart systemd-journald


▪️Почему это важно

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

BashTex 📱 #scripts #systemd
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
tmpfiles.d: автоматическое создание и очистка директорий без cron

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

Хотя systemd умеет делать это самостоятельно.

▪️Что такое tmpfiles.d

Механизм tmpfiles.d позволяет создавать каталоги, менять права доступа, владельцев и автоматически удалять старые файлы по заданным правилам.

Конфигурации обычно находятся здесь:

/etc/tmpfiles.d/
/usr/lib/tmpfiles.d/


▪️Создание каталога при старте

Допустим, приложению нужен каталог для кэша:

d /var/cache/myapp 0755 myapp myapp -


Где:

d — создать директорию
0755 — права доступа
myapp myapp — владелец и группа

После применения:

systemd-tmpfiles --create


Каталог появится автоматически.

▪️Автоматическая очистка

Удалять файлы старше 7 дней:

D /var/tmp/myapp 0755 myapp myapp 7d


Теперь systemd будет очищать содержимое каталога согласно политике хранения.

Проверить правила можно так:

systemd-tmpfiles --clean


▪️Где это полезно

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

▪️Почему это удобнее cron

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

BashTex 📱 #scripts #tmpfiles
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Почему du и df показывают разный размер

Одна из классических загадок Linux:

df -h


Показывает:

/dev/sda1  100%


Но если проверить содержимое файловой системы:

du -sh /var
du -sh /home
du -sh /opt


Суммарный объём получается заметно меньше.
Куда пропало место?

▪️Что считают du и df

du подсчитывает размер файлов, которые видны в файловой системе.
df показывает занятые блоки на уровне самой файловой системы.
Из-за этого их значения могут различаться.

▪️Самая частая причина

Удалённый файл всё ещё открыт процессом.
Например:

rm app.log


Файл исчез из каталога, поэтому du его больше не видит.

Но если процесс продолжает писать в него, место останется занятым.
Найти такие файлы можно так:

lsof +L1


Пример вывода:

java 1234 user 5w REG ... app.log (deleted)


Пока процесс не завершится или не закроет дескриптор, место не освободится.

▪️Другие причины

Зарезервированные блоки ext4:

tune2fs -l /dev/sda1 | grep Reserved


Смонтированные файловые системы внутри каталогов:

mount | column -t


Или bind-монтирования, из-за которых данные учитываются неожиданным образом.

▪️Быстрая диагностика

Если диск внезапно заполнился:

df -h
lsof +L1


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

▪️Почему это важно

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

BashTex 📱 #scripts #du
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
Почему kill -9 - не лучший способ остановить процесс

Многие администраторы при зависшем процессе сразу используют:

kill -9 <PID>


Обычно это работает. Но далеко не всегда это правильное решение.

▪️Что делает SIGKILL

Сигнал -9 (SIGKILL) принудительно завершает процесс на уровне ядра.

Процесс не может его перехватить, обработать или проигнорировать.

Ядро просто убивает его.

▪️Что при этом не происходит

Процесс не успевает:
сохранить данные
закрыть файлы
завершить активные операции
удалить временные файлы
выполнить обработчики завершения

Например, база данных может не успеть корректно завершить транзакции.

▪️Что использовать сначала

Обычный сигнал завершения:

kill <PID>


или

kill -15 <PID>


Это SIGTERM.
Процесс получает запрос на завершение и может корректно освободить ресурсы.

▪️Посмотреть, реагирует ли процесс

Отправляем SIGTERM:

kill -15 1234


Проверяем:

ps -p 1234


Если процесс всё ещё работает спустя разумное время, тогда можно переходить к более жёстким мерам.

▪️Полезный приём

Для сервисов под systemd лучше использовать:

systemctl stop myapp


systemd сам отправит нужные сигналы в правильном порядке и подождёт завершения процесса.

Только если сервис не реагирует, будет применено принудительное завершение.

▪️Почему это важно

kill -9 часто помогает быстро решить проблему, но одновременно может создавать новые. Поэтому его лучше рассматривать как последний инструмент, когда процесс уже не отвечает на обычное завершение.

BashTex 📱 #scripts #kill9
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Проверка недавно созданных пользователей: UID, shell и следы активности

На сервере часто важно быстро понять, появлялись ли новые пользователи и насколько они “нормальные”.

Один из базовых источников - /etc/passwd, но там нет явной даты создания. Поэтому анализ строится через косвенные признаки.

▪️Поиск пользователей с обычным UID диапазоном
getent passwd | awk -F: '$3 >= 1000 {print $1, $3, $7}'

Обычно реальные пользователи находятся начиная с UID 1000.

Системные - ниже.

Смотрим shell: /bin/bash, /bin/zsh чаще у людей, /usr/sbin/nologin или /bin/false - сервисные аккаунты.

▪️Быстрый срез через lastlog

lastlog -t 30


Показывает пользователей, которые логинились за последние 30 дней. Новые аккаунты без активности сразу заметны.

▪️Проверка событий создания пользователей

journalctl _COMM=useradd --since "7 days ago"


или через auth лог:

grep useradd /var/log/auth.log


Здесь видны факты создания аккаунтов и изменения групп.

▪️Косвенная проверка “новизны”

Можно оценить свежесть через системные изменения:

stat /etc/passwd


или изменения shadow:

stat /etc/shadow


Если недавно был добавлен пользователь, эти файлы будут обновлены в тот же период.

▪️Дополнительная проверка активности

faillog -a


и

last


Позволяют понять, пытался ли пользователь входить в систему и с каких хостов.

▪️Почему это важно

Новые пользователи с UID 1000+, нестандартным shell или отсутствием логинов — один из первых сигналов, который стоит проверять при аудите сервера.

BashTex 📱 #scripts #du
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Работа с дескрипторами файлов через exec: FD 3, 4, логирование и контроль потоков

В Bash обычно работают только с stdin (0), stdout (1) и stderr (2). Но файловые дескрипторы на этом не заканчиваются - можно использовать FD 3, 4 и выше для более гибкого управления потоками.

▪️Базовая идея

Каждый процесс имеет таблицу файловых дескрипторов:

0 → stdin
1 → stdout
2 → stderr


Но можно открыть дополнительные:

exec 3>debug.log


Теперь FD 3 пишет в файл debug.log.

▪️Разделение логов

Классический приём - разделить обычный вывод и отладку:

echo "normal output"
echo "debug info" >&3


Результат:
stdout остаётся чистым
debug уходит в отдельный файл

▪️Перенаправление команд через FD

Можно связать вывод команды с кастомным дескриптором:

exec 4< input.txt


Теперь FD 4 читает файл как поток.
Чтение:

read -u 4 line
echo "$line"


▪️Логирование через единый канал

Удобный паттерн - централизованный лог:
exec 3>>/var/log/myapp.log

log() {
echo "$(date '+%F %T') $*" >&3
}


Теперь все логи идут через FD 3, без захламления stdout.

▪️Почему это лучше обычного >> везде
единая точка управления логированием
проще отключать/перенаправлять вывод
можно динамически менять файл логов через exec

▪️Закрытие дескрипторов

exec 3>&-


FD освобождается, файл больше не удерживается процессом.

▪️Где это реально используется
сложные Bash-скрипты с несколькими потоками данных
системы логирования без внешних библиотек
обработка нескольких входных источников одновременно
изоляция debug/production вывода
FD выше 2 - это недооценённый инструмент, который превращает Bash из набора команд в полноценную систему управления потоками.

BashTex 📱 #scripts #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6
Bash strict mode: что реально даёт set -euo pipefail и где он ломает логику

В bash часто добавляют так называемый "strict mode": set -euo pipefail

Идея простая - сделать скрипты более предсказуемыми и ловить ошибки раньше.

▪️Что означает каждая опция

-e - остановить скрипт при любой ошибке команды
-u - ошибка при использовании неинициализированной переменной
-o pipefail - пайп считается упавшим, если упала любая команда в цепочке

▪️Что это реально улучшает

Без strict mode многие ошибки проглатываются:


rm file_not_exist
echo "continue"


Или:


echo "$UNDEFINED_VAR"


будет явная ошибка, а не пустая строка.

▪️ pipefail: скрытая проблема пайп

Без него:


cat file | grep ERROR | sort


Возвращает код последней команды, даже если grep упал.

▪️ Где начинается проблема. Strict mode ломает сценарии, где ошибка - это нормальное состояние.

Пример:


grep pattern file.txt
echo "done"


Если совпадений нет, grep возвращает 1 и скрипт завершается, хотя это не ошибка логики.

▪️ Типичный workaround


grep pattern file.txt || true


Или:


set +e
grep pattern file.txt
set -e


Но это уже ручное управление поведением.

▪️ ещё один частый кейс - test / if


set -e

if grep pattern file.txt; then
echo "found"
fi


Здесь grep может упасть, но в контексте if это нормальный контроль потока - и это не считается фатальной ошибкой.

▪️ Итоговый баланс

Strict mode хорошо работает в:

• CI/CD
• одноразовых скриптах
• автоматизации без ветвлений

Но начинает мешать в:

• парсинге данных
• поиске (grep как логика)
• скриптах с ожидаемыми "ошибками как состоянием"

Это не универсальная защита, а переключатель модели поведения Bash-скрипта: от гибкого к строго детерминированному.

BashTex 📱 #scripts #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
coproc на практике: двусторонний обмен данными с процессом

В bash обычно все сводится к pipe: команда - команда. Но классический пайп односторонний. Если нужен диалог с процессом в обе стороны - используется coproc.

▪️ Что такое coproc. Он запускает процесс и даёт два канала:

stdin - в процесс
stdout - из процесса

И все это без временных файлов и костылей с FIFO.

▪️ Базовый пример


coproc BC { bc -l; }


Теперь у нас есть процесс калькулятора, с которым можно общаться.

Отправляем данные:


echo "2+2" >&"${BC[1]}"
read result <&"${BC[0]}"
echo "$result"


▪️ Как это устроено. После запуска bash создает массив:


${COPROC[0]} # stdout процесса
${COPROC[1]} # stdin процесса


Можно читать и писать независимо.

▪️ Реальный кейс: фоновый parser


coproc JSON { jq -c '.name'; }


Отправляем поток данных:


echo '{"name":"test"}' >&"${JSON[1]}"
read out <&"${JSON[0]}"
echo "$out"


▪️ Почему это лучше pipe Pipe работает так:


cmd1 | cmd2


Но:

• нет обратного канала
• процесс заканчивается сразу
• нельзя поддерживать состояние

coproc позволяет держать живой процесс и общаться с ним как с сервисом.

▪️ Важный момент. Процесс внутри coproc не перезапускается автоматически. Если он завершился - каналы перестают работать, и это нужно проверять вручную.

▪️ Где это реально полезно

• интерактивные CLI-инструменты (bc, python, sqlite3)
• долгоживущие парсеры (jq, awk, кастомные демоны)
• проксирование данных между процессами
• построение "мини-сервисов" прямо в Bash

coproc превращает bash из набора команд в примитивную систему IPC, где процессы начинают вести диалог, а не просто передавать поток данных в одну сторону.

BashTex 📱 #bash #scripts
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
nameref (declare -n): ссылки на переменные и передача массивов в функции

В Bash функции по умолчанию работают с копиями значений или с глобальными переменными. Но есть механизм, который позволяет имитировать “ссылки” - nameref.

▪️Что такое nameref

declare -n создаёт ссылку на другую переменную:

arr=(1 2 3)

declare -n ref=arr
ref[0]=999

echo "${arr[0]}"


Результат:

999


ref
не хранит данные - он указывает на arr.

▪️Передача массива в функцию без копирования
Классическая проблема:

func() {
local arr=("$@")
}


Это создаёт копию массива.

С nameref:

func() {
local -n arr=$1
echo "${arr[0]}"
}


Вызов:

data=(10 20 30)
func data


Функция работает с оригинальным массивом.

▪️Модификация массива внутри функции

func() {
local -n arr=$1
arr[1]=999
}

data=(10 20 30)
func data

echo "${data[@]}"
Результат:
10 999 30


▪️Где это особенно полезно
функции обработки конфигураций
парсинг JSON → массивы ключей/значений
работа с таблицами данных
построение библиотек на Bash без глобальных переменных

▪️Важный момент
nameref работает только с именами переменных:

local -n ref=$1


Нельзя передавать:
• значения
• выражения
• результаты команд

Только имя переменной.

▪️Ограничения
нельзя безопасно переиспользовать ссылку на разные переменные в одном scope без переопределения
сложнее отлаживать (меняется оригинальный объект)
требует Bash 4.3+

▪️Почему это важно

Без nameref Bash-функции либо копируют данные, либо используют глобальное состояние. declare -n даёт третий вариант — передачу по ссылке, что делает сложные скрипты заметно чище и ближе к языкам общего назначения.

BashTex 📱 #scripts #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Автоматическая реакция на OOM через systemd и cgroups: перезапуск и контроль памяти

OOM (Out Of Memory) - это не просто “закончилась память”. В Linux это механизм, при котором ядро начинает принудительно завершать процессы, чтобы система не упала целиком.

Проблема в том, что без контроля первым под нож часто попадает не тот процесс, который должен.

▪️Как systemd влияет на OOM

systemd работает поверх cgroups и может задавать приоритеты “жертвенности” процессов:

systemd-cgtop

Показывает, какие группы потребляют память.

▪️Контроль памяти на уровне unit

Можно ограничить сервис:

[Service]
MemoryMax=500M

Теперь процесс физически не сможет превысить лимит.

Дополнительно:

MemoryHigh=400M


Это мягкий порог - systemd начинает давить на процесс раньше, чем наступит OOM.

▪️Влияние на OOM Killer
Можно управлять приоритетом уничтожения:

OOMScoreAdjust=-500
или наоборот:
OOMScoreAdjust=500


Чем выше значение - тем выше шанс, что процесс будет убит первым.

▪️Автоматический перезапуск после OOM
systemd может перезапускать сервис даже после убийства ядром:

[Service]
Restart=on-failure
RestartSec=2


Это работает и для OOM-kill, потому что процесс считается завершённым с ошибкой.

▪️Практический сценарий
Типичная ситуация:

• сервис разогнал память
• ядро убивает его через OOM
• systemd фиксирует падение
• запускает новый экземпляр
• cgroups не дают повторно выйти за лимит

▪️Где начинается реальный контроль

Ключевой момент - сочетание:

• MemoryMax (жёсткий лимит)
• MemoryHigh (раннее давление)
• OOMScoreAdjust (приоритет убийства)
• Restart=on-failure (самовосстановление)

▪️Почему это важно

Без cgroups OOM - это хаос: ядро выбирает жертву само.

С systemd это превращается в управляемую систему: процесс либо не доходит до OOM, либо корректно переживает его через перезапуск и ограничение ресурсов.

BashTex 📱 #scripts #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6
Проверка файловых систем, смонтированных с опасными опциями

При аудите Linux обычно проверяют права доступа и SUID-биты. Но не менее важно посмотреть, как смонтированы файловые системы.

Если временный каталог или пользовательский раздел смонтирован с exec, suid или dev, это может значительно расширить поверхность атаки.

▪️Посмотреть все точки монтирования

Самый удобный способ:

findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS


Или классический вариант:

mount


▪️На что обратить внимание
Опции монтирования:
exec - разрешает запуск исполняемых файлов.
suid - позволяет работать SUID/SGID-битам.
dev - разрешает использование файлов устройств.

Для каталогов вроде /tmp, /var/tmp или /dev/shm обычно безопаснее использовать противоположные опции:
noexec,nosuid,nodev

▪️Пример проверки

findmnt -no TARGET,OPTIONS /tmp


Если вывод содержит:

rw,relatime


значит ограничения отсутствуют.

Более безопасный вариант:

rw,nosuid,nodev,noexec


▪️Проверка через fstab

Чтобы убедиться, что настройки сохранятся после перезагрузки:

grep -vE '^\s*#|^$' /etc/fstab


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

▪️Почему это важно

Представьте, что злоумышленник смог записать файл в /tmp. Если раздел смонтирован с exec, его можно сразу запустить. Если ещё и разрешён suid или dev, последствия могут быть значительно серьёзнее.
Несколько минут на проверку параметров монтирования могут устранить целый класс потенциальных проблем ещё до того, как они будут использованы.

BashTex 📱 #scripts #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Скрипт поиска процессов с аномальным потреблением памяти

Когда на сервере заканчивается память, первое желание - открыть top. Но он показывает только текущее состояние. Для автоматизации удобнее получить список самых “тяжёлых” процессов и использовать его в скриптах.

▪️Быстрый рейтинг по RSS

Размер физической памяти, занимаемой процессом (RSS), можно посмотреть так:

ps -eo pid,user,comm,rss --sort=-rss | head -10


Поле rss выводится в килобайтах, поэтому сразу видно, кто потребляет больше всего ОЗУ.

▪️Автоматическая проверка

Например, вывести процессы, использующие больше 1 ГБ памяти:

ps -eo pid,comm,rss \
| awk '$3 > 1048576 {
printf "%-8s %-20s %.1f MB\n", $1, $2, $3/1024
}'


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

▪️Если нужен максимум информации

Часть данных о процессе хранится в /proc:

grep -E 'VmRSS|VmSize' /proc/1234/status


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

Эти значения могут сильно отличаться.

▪️Не путайте RSS и VSZ

Большой VSZ ещё не означает проблему. Многие приложения резервируют память заранее, но фактически используют лишь небольшую её часть.
При поиске “пожирателей” памяти обычно ориентируются именно на RSS.

▪️Почему это важно

Периодическая сортировка процессов по RSS помогает заметить утечки памяти ещё до того, как сработает OOM Killer. Особенно полезно для Java, Python, Node.js и других долгоживущих сервисов.

BashTex 📱 #bash #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Анализ активных UNIX-сокетов: поиск неожиданных IPC-соединений

При аудите обычно смотрят TCP- и UDP-порты, но многие сервисы вообще не используют сеть. Вместо этого они обмениваются данными через UNIX-сокеты.
Именно поэтому их тоже стоит периодически проверять.

▪️Посмотреть все UNIX-сокеты

Самый удобный способ:

ss -xl


Ключ -x показывает UNIX-сокеты, а -l - только те, которые находятся в режиме ожидания соединений.

▪️Получить больше информации

Если нужны процессы-владельцы:

ss -xlp


Например:

u_str LISTEN 0 128 /run/docker.sock
users:(("dockerd",pid=812,fd=7))


Сразу видно, какой процесс создал сокет.

▪️На что обратить внимание

Особый интерес представляют сокеты в нестандартных местах:

/tmp/
/dev/shm/
/home/user/


Большинство системных сервисов используют /run или /var/run. Если сокет появился в /tmp, стоит проверить, кто его создал и зачем.

▪️Найти сокеты через файловую систему

find / -type s 2>/dev/null


Это покажет все файлы типа socket, даже если они сейчас не используются.

▪️Когда это полезно

UNIX-сокеты используют Docker, Podman, PostgreSQL, Redis, Nginx, PHP-FPM, systemd и десятки других сервисов.
Неожиданный сокет может указывать на недавно установленное ПО, самописный сервис или процесс, который не должен работать на сервере.

▪️Почему это важно

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

BashTex 📱 #bash #linux
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1