NetworkAdmin.ru
4.71K subscribers
250 photos
35 videos
2 files
660 links
Авторский блог про сетевое и системное администрирование.

Сайт: networkadmin.ru
Реклама: @dad_admin
Биржа: https://telega.in/c/networkadminru
Download Telegram
Заказал с алика видеокарту, это не обман?

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁11
Кто жрет канал прямо сейчас

Когда сервер или рабочая машина внезапно начинают “тупить по сети”, первый вопрос обычно очень приземленный: кто именно сейчас жрет канал? Для такой быстрой диагностики есть две простые и очень полезные утилиты: iftop и nethogs. Обе показывают сетевую активность в реальном времени, но делают это по-разному.

iftop - показывает трафик между хостами
nethogs - показывает трафик по процессам

Именно в этом их главное различие.

▪️ iftop - кто с кем говорит. iftop похож на top, только для сети. Он показывает, какие IP-адреса и соединения прямо сейчас генерируют трафик, и в каких объемах.

Установка:


apt install iftop


Запуск:


iftop -i eth0


Что удобно в iftop:

• сразу видно самые тяжелые соединения;
• можно понять, идет ли трафик наружу или внутрь;
• удобно ловить внезапные бэкапы, репликации, выгрузки и подозрительные соединения.

Типичные находки:

сервер льет бэкап в удаленное хранилище;
кто-то качает большой файл по SCP;
приложение внезапно активно общается с внешним API;
контейнер или VM начали активно ходить в сеть.

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

▪️ nethogs - какой процесс виноват. Если нужен ответ не куда идет трафик, а какой процесс его генерирует, тогда удобнее nethogs.

Установка:


apt install nethogs


Запуск:


nethogs eth0


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

rsync
curl
docker
python
apt
любой другой живой процесс

Это особенно полезно, когда на хосте много сервисов, и по одним только IP трудно понять, кто виноват.

▪️ Когда что использовать

iftop - если нужно быстро понять: с какими IP идет обмен, какие соединения самые тяжелые, куда вообще уходит канал
nethogs - если нужно понять: какой процесс грузит сеть, кто именно качает или отдает данные, какой сервис стал шумным

⚠️ Важно

Обе утилиты обычно требуют root-права, иначе картина может быть неполной.

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

#linux #network

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🦖 Reverse Path Filtering: защита или источник странных сетевых багов

Иногда сеть вроде настроена правильно, маршруты есть, интерфейсы подняты, а пакеты все равно куда-то пропадают. Особенно часто это всплывает на серверах с несколькими интерфейсами, policy routing, VPN, асимметричной маршрутизацией или в роли роутера. Одна из причин - Reverse Path Filtering (rp_filter). Это механизм в linux, который проверяет: если пакет пришел с какого-то IP, а мы захотели бы отправить ответ до этого IP через другой интерфейс - не выглядит ли это подозрительно? Если выглядит - пакет может быть отброшен.

▪️ Зачем это вообще нужно:

защита от IP spoofing;
базовая проверка правдоподобности маршрута;
уменьшение шансов принять пакет с поддельным source IP.

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

▪️ Где rp_filter часто ломает жизнь:

multihomed-серверы с несколькими uplink;
VPN и туннели;
policy based routing;
асимметричные маршруты;
NAT-сценарии;
Kubernetes / overlay-сети;
Linux в роли маршрутизатора

▪️ Типичная ситуация:

• пакет приходит через eth1;
• ядро считает, что обратный путь до source IP должен идти через eth0;
• rp_filter решает, что пакет подозрительный;
• пакет молча дропается

Снаружи это выглядит очень неприятно: ping иногда работает, иногда нет; сервис доступен только с части адресов; VPN поднимается, но трафик странно теряется; один интерфейс живой, а ответы уходят не туда; tcpdump показывает входящий пакет, но приложение его не видит.

▪️ Проверить можно так:


sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.eth0.rp_filter


Обычно значения такие:

0 - выключено
1 - strict mode
2 - loose mode

▪️ Что важно понимать:

strict mode хорош для простых хостов с одной понятной маршрутизацией. Но в сложной сетевой схеме он легко становится источником магических багов. Часто более безопасный компромисс - это loose mode:


sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2


Или точечно для интерфейса:


sysctl -w net.ipv4.conf.eth1.rp_filter=2


Полностью отключают обычно только там, где точно понимают, зачем это нужно.

#linux #network

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
❗️ lsof: кто держит файл, порт или точку монтирования

Иногда нужно ответить на очень простой вопрос: кто это держит? Файл удалили, а место не освободилось. Порт занят, но непонятно кем. Диск не размонтируется, потому что "device is busy". Во всех этих случаях помогает lsof - утилита, которая показывает открытые файлы. В linux почти все является файлом: обычные файлы, сокеты, сетевые соединения, устройства, точки монтирования. Поэтому lsof умеет находить очень много полезного.

▪️ Установка:


apt install lsof

#или
yum install lsof```

▪️ Кто держит конкретный файл


lsof /var/log/app.log


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


lsof | grep deleted


или аккуратнее:


lsof +L1


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

▪️ Кто слушает порт. Например, нужно понять, кто занял 8080:


lsof -i :8080


Для TCP:


lsof -iTCP:8080 -sTCP:LISTEN


В выводе будет видно имя процесса, PID и пользователь. Это удобно, когда сервис не стартует с ошибкой вроде: address already in use

▪️ Кто держит точку монтирования. Допустим, не получается размонтировать диск:


umount /mnt/backup


А в ответ: target is busy

Смотрим, кто держит файлы внутри:


lsof +D /mnt/backup


После этого можно понять, какой процесс мешает размонтированию: shell с текущей директорией внутри mount point, backup-скрипт, rsync, база или зависший процесс.

▪️ Кто держит сетевые соединения. Показать все сетевые соединения:


lsof -i


Только TCP:


lsof -iTCP


Только UDP:


lsof -iUDP


Это не всегда замена ss, но часто удобно, когда нужно быстро связать соединение с процессом.

▪️ Что полезно запомнить:


lsof /path/to/file
lsof -i :PORT
lsof -iTCP:PORT -sTCP:LISTEN
lsof +D /mount/path
lsof +L1


#linux #lsof

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍4
💿 LVM RAID на практике: RAID1, замена диска и проверка целостности

LVM умеет не только создавать обычные логические тома, но и собирать RAID-массивы. Это удобно, когда хочется управлять дисками, томами и отказоустойчивостью в одном месте, без отдельного mdadm.

Ниже будет шпаргалка по созданию LVM RAID1, замене вылетевшего диска и включению проверки целостности через DM Integrity.

Создаем RAID1 из двух дисков:


apt install lvm2
pvcreate /dev/sdb /dev/sdc
vgcreate vgroup /dev/sdb /dev/sdc
lvcreate --type raid1 -l 100%FREE -n lvraid1 vgroup


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


lvs -o+segtype


Создаем файловую систему и монтируем том:


mkfs.ext4 /dev/vgroup/lvraid1
mkdir /mnt/lvraid1
mount /dev/vgroup/lvraid1 /mnt/lvraid1


Смотрим итоговую структуру: lsblk
Теперь можно записать данные и дождаться полной синхронизации:


cp -r /var/log/* /mnt/lvraid1/


Если после этого отключить один из дисков, данные останутся доступны. RAID1 продолжит работать в degraded-состоянии.
Проверить статус можно так:


lvs -a -o name,devices vgroup


Если один диск пропал, в выводе появится устройство со статусом [unknown].
Допустим, вместо старого диска в системе появился новый /dev/sdd.

Добавляем его в VG:


pvcreate /dev/sdd
vgextend vgroup /dev/sdd


Удаляем пропавший диск из volume group:


vgreduce --removemissing vgroup --force


Проверяем, что [unknown] исчез:


lvs -a -o name,devices vgroup


Теперь восстанавливаем RAID и добавляем новый диск в зеркало:


lvconvert --repair vgroup/lvraid1
lvconvert -m1 vgroup/lvraid1 /dev/sdd


На вопросы LVM отвечаем утвердительно. Наблюдать за синхронизацией можно так:


lvs -a -o name,devices vgroup
lvs -o+segtype


В итоге диск заменен, данные на месте, система продолжает работать.
Это один из плюсов LVM RAID: замена диска проходит достаточно логично и без остановки сервера, если железо позволяет hot-swap.

▪️ Еще одна интересная возможность LVM RAID - конвертация уровней RAID на лету. Например, можно начать с RAID1 на двух дисках, а потом добавить еще два диска и прийти к RAID10. Правда, прямой конвертации из RAID1 в RAID10 нет: обычно это делается через промежуточные этапы. Примерная схема:


pvcreate /dev/sdc /dev/sde
vgextend vgroup /dev/sdc /dev/sde
lvconvert --type raid5_n vgroup/lvraid1
lvresize -l5118 vgroup/lvraid1
lvconvert --stripes 1 vgroup/lvraid1
lvconvert --stripes 2 vgroup/lvraid1
lvconvert --type raid10 vgroup/lvraid1
lvconvert --type raid10 vgroup/lvraid1


Размер в lvresize нужно подбирать под конкретный LV. LVM в процессе обычно сам подсказывает, что ему нужно: где не хватает места, где конвертация идет в несколько этапов, и какой промежуточный тип требуется. Если RAID10 создается с нуля, все намного проще. Добавляем 4 диска в VG и создаем LV:


lvcreate --type raid10 -l 100%FREE -n lvraid10 vgroup


▪️ Самая интересная часть - DM Integrity. LVM RAID может проверять целостность данных с помощью контрольных сумм. Это позволяет обнаруживать повреждения и пытаться восстановить данные из другой копии в составе RAID. Включить integrity можно сразу при создании LV:


lvcreate --type raid1 --raidintegrity y -L 9G -n lvraid1 vgroup


Важный момент: под метаданные integrity нужно свободное место. Если указать 100%FREE, можно получить ошибку, потому что LVM не сможет выделить место под служебные данные. Если в VG есть свободное место, integrity можно добавить к уже существующему RAID-томy:


lvconvert --raidintegrity y vgroup/lvraid1


При чтении данных будет проверяться контрольная сумма. Если она не совпадет с сохраненной, LVM попытается восстановить данные из другой копии RAID.
Для каждого диска в составе такого LV создаются дополнительные служебные тома под integrity metadata. Статистику ошибок можно смотреть так:


lvs -o+integritymismatches vgroup/lvraid1_rimage_0_imeta


Нужная колонка: IntegMismatches
Также события по DM Integrity будут попадать в системный лог, например: /var/log/syslog

#lvm #raid

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112
Смотря какой fabric
Смотря сколько details

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥101😁1
🛡 Как защитить скрипт от повторного запуска

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

flock - это утилита для работы с файловыми блокировками. Идея простая: перед запуском скрипт пытается взять lock-файл. Если блокировка уже занята, значит другая копия скрипта еще работает.

▪️ Самый простой вариант:


flock -n /tmp/myjob.lock /opt/scripts/myjob.sh


/tmp/myjob.lock - файл блокировки
-n - не ждать освобождения lock, а сразу завершиться
/opt/scripts/myjob.sh - команда, которую нужно выполнить

Если первый запуск еще работает, второй просто не стартует.

▪️ Для cron это выглядит так:


*/5 * * * * flock -n /tmp/backup.lock /opt/scripts/backup.sh

`
Теперь даже если бэкап длится дольше 5 минут, новая копия не запустится поверх старой.

▪️ Можно добавить логирование:


flock -n /tmp/backup.lock /opt/scripts/backup.sh || echo "backup already running"


▪️ Но часто удобнее встроить flock прямо в сам скрипт:


#!/usr/bin/env bash
set -euo pipefail

LOCK_FILE="/tmp/myjob.lock"

exec 200>"$LOCK_FILE"

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

echo "start job"

# основная логика скрипта
sleep 30

echo "done"


exec 200>"$LOCK_FILE" открывает lock-файл на файловом дескрипторе 200
flock -n 200 пытается взять блокировку
если блокировка занята - скрипт завершается
пока скрипт работает, дескриптор открыт и lock удерживается

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

▪️ Где хранить lock-файл? Для временных задач часто используют:


/tmp/myjob.lock


Для системных сервисов лучше:


/run/myjob.lock


/run обычно живет в tmpfs и очищается после перезагрузки. Это удобно для runtime-блокировок.

▪️ Есть и режим ожидания:


flock /tmp/myjob.lock /opt/scripts/myjob.sh


В этом случае второй запуск будет ждать, пока первый освободит lock.
Можно задать таймаут ожидания:


flock -w 60 /tmp/myjob.lock /opt/scripts/myjob.sh


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

#bash #flock

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83
🌀 Почему "процесс жив" не означает "сервис работает"

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


systemctl status myapp


показывает active (running), PID есть, порт вроде слушается - значит все хорошо? Не всегда.

Процесс может быть живым, но сам сервис уже фактически не работает:

завис на подключении к базе;
потерял доступ к Redis или очереди;
перестал обрабатывать запросы;
отвечает только частью функционала;
уперся в пул соединений;
ловит deadlock внутри приложения;
слушает порт, но возвращает 500.

Поэтому нормальная проверка должна отвечать не на вопрос: "процесс существует?" А на вопрос: "сервис реально выполняет свою задачу?"

▪️ Самый простой пример - HTTP health check:


curl -fsS http://127.0.0.1:8080/health


Если endpoint возвращает 200 OK, уже лучше, чем просто проверять PID. Но и здесь есть нюанс.
Плохой health check: /health -> 200 OK просто потому что приложение запустилось.

▪️ Хороший health check проверяет зависимости:

доступна ли база;
работает ли очередь;
можно ли читать конфиг;
не закончились ли critical ресурсы;
готов ли сервис принимать трафик;

В кубере это разделяют на разные проверки:

liveness - процесс жив или его надо перезапустить;
readiness - можно ли отправлять на него трафик;
startup - успел ли сервис нормально подняться.

Эту же логику полезно применять и без k8s. Например:


curl -fsS http://127.0.0.1:8080/ready


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

▪️ Для обычного linux-сервера можно использовать health check в связке с systemd, HAProxy, Nginx, keepalived или внешним мониторингом. Пример проверки в скрипте:


#!/usr/bin/env bash

if curl -fsS http://127.0.0.1:8080/health >/dev/null; then
echo "OK"
exit 0
else
echo "FAIL"
exit 1
fi


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

#linux #monitoring

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
🔎 mtr: диагностика сети

Если сеть начинает лагать, то обычно первым делом запускают:


ping 8.8.8.8


Потом:


traceroute 8.8.8.8


ping показывает задержку и потери до конечного узла. traceroute показывает маршрут. А mtr объединяет оба подхода в одном инструменте. По сути, mtr - это живая диагностика маршрута: он постоянно отправляет пакеты и показывает статистику по каждому hop`у.

▪️ Установка:


apt install mtr


или:


yum install mtr


Запуск:


mtr 8.8.8.8


▪️ В интерфейсе видно:

через какие узлы идет маршрут;
где растет задержка;
на каком hop’е появляются потери;
как меняется картина во времени.

▪️ Для разовой проверки удобен report-режим:


mtr -rw 8.8.8.8


-r - report mode
-w - широкий вывод, чтобы не резались имена хостов

Можно указать число пакетов:


mtr -rw -c 100 8.8.8.8


Это уже полезнее, чем скриншот после 5 секунд наблюдения.

▪️ Главное правило чтения mtr:

Потери на промежуточном hop’е не всегда означают проблему. Многие маршрутизаторы специально ограничивают ответы на ICMP/TTL exceeded. Поэтому если на одном промежуточном узле видно 50% loss, а дальше и до конечного хоста потерь нет - скорее всего, это не авария. Проблема становится реальной, когда потери продолжаются на всех следующих hop’ах, включая конечный адрес. Пример:


hop 5: 30% loss
hop 6: 30% loss
hop 7: 30% loss
target: 30% loss


Вот это уже похоже на реальную потерю по пути. А если так:


hop 5: 80% loss
hop 6: 0% loss
target: 0% loss


то, скорее всего, просто сам hop не любит отвечать на диагностические пакеты.

▪️ Полезные варианты:


mtr -4 networkadmin.ru # только IPv4.
mtr -6 networkadmin.ru # только IPv6.
mtr -T networkadmin.ru # TCP-режим, полезно, когда ICMP фильтруется.
mtr -u networkadmin.ru # UDP-режим


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

#linux #network

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍2🔥1
А вот это уже пахнет на настоящему дорого

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13
ℹ️ DISM и SFC: базовая реанимация windows без переустановки

Когда windows начинает вести себя странно, не всегда нужно сразу переустанавливать систему. Симптомы могут быть разные:

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

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

▪️ SFC проверяет целостность системных файлов. Запускать нужно из cmd или PowerShell от администратора:


sfc /scannow


Если SFC найдет поврежденные файлы, он попробует заменить их корректными копиями. Но есть нюанс: SFC берет файлы из компонентного хранилища windows. Если само хранилище повреждено, SFC может не справиться. Вот тут нужен DISM.

▪️ DISM проверяет и восстанавливает component store:


DISM /Online /Cleanup-Image /CheckHealth


Быстрая проверка, есть ли признаки повреждения.


DISM /Online /Cleanup-Image /ScanHealth


Более глубокое сканирование.


DISM /Online /Cleanup-Image /RestoreHealth


Восстановление повреждений.

▪️ Обычно рабочий порядок такой:


DISM /Online /Cleanup-Image /RestoreHealth
sfc /scannow


Сначала чиним компонентное хранилище, потом проверяем системные файлы. Если Windows Update работает нормально, DISM сам подтянет нужные компоненты. Если нет - может понадобиться ISO-образ windows той же версии.

Пример с указанием источника:


DISM /Online /Cleanup-Image /RestoreHealth /Source:wim:D:\sources\install.wim:1 /LimitAccess


D: - смонтированный ISO
install.wim - образ установки
:1 - индекс редакции внутри WIM
/LimitAccess - не ходить в Windows Update

Индекс можно посмотреть так:


DISM /Get-WimInfo /WimFile:D:\sources\install.wim


▪️ Где это реально помогает:

после неудачных обновлений;
после внезапного выключения;
при ошибках системных файлов;
когда Windows Update ведет себя странно;
при повреждении системных компонентов.

#windows #dism #sfc

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18
😑 Почему сервис работает вручную, но падает в systemd

Распространенная ситуация: запускаете приложение руками и все работает.


/opt/myapp/start.sh


А через systemd:


systemctl start myapp


сервис падает, не видит файлы, не находит переменные, не может подключиться к сокету или пишет что-то вроде:

No such file or directory
Permission denied
command not found

И тут важно понять главное: запуск руками и запуск через systemd - это не одно и то же окружение. Когда вы запускаете команду из shell, у вас уже есть:

переменные окружения;
текущий каталог;
пользовательская сессия;
PATH;
ssh-agent;
загруженный профиль .bashrc / .profile;
права вашего пользователя.

А systemd запускает сервис гораздо строже.

▪️Самые частые причины:

Нет нужного PATH. В shell команда находится, а в systemd нет.

Плохо:


ExecStart=python app.py


Лучше:


ExecStart=/usr/bin/python3 /opt/myapp/app.py


Другой рабочий каталог. Скрипт ожидает файлы рядом с собой, а systemd запускает его не оттуда.


WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh


Не хватает переменных окружения. Например, DB_HOST, API_TOKEN, JAVA_HOME.


Environment="DB_HOST=127.0.0.1"
EnvironmentFile=/etc/myapp/myapp.env


Не тот пользователь. Вручную запускали от root, а сервис работает от myapp.


User=myapp
Group=myapp


И внезапно выясняется, что нет прав на логи, конфиги или каталоги данных.

Сервис стартует раньше зависимости. Например, приложение поднимается раньше базы, сети или mount point.


After=network-online.target postgresql.service
Wants=network-online.target


Скрипт требует интерактивную оболочку. Если внутри завязка на .bashrc, алиасы, read, sudo с паролем или интерактивные команды - в systemd это почти гарантированно сломается. Что смотреть первым делом:


systemctl status myapp
journalctl -u myapp -xe
systemctl cat myapp


Полезно вывести окружение процесса:


systemctl show myapp -p Environment


И проверить unit на синтаксис:


systemd-analyze verify /etc/systemd/system/myapp.service


#linux #systemd

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
Одно без другого невозможно

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3💊1
🖥 trap в bash: как правильно ловить ошибки и чистить временные файлы

В скриптах часто есть временные файлы, lock-файлы, промежуточные каталоги и другие следы работы. Проблема начинается, когда скрипт падает посередине. Например: временный файл остался в /tmp; lock-файл не удалился; mount point не размонтировался; сервис был остановлен, но обратно не запущен; промежуточные данные остались в неконсистентном состоянии. Для таких случаев в bash есть trap. Он позволяет выполнить команду или функцию при наступлении события: выход из скрипта, ошибка, Ctrl+C, kill и так далее.

▪️ Самый частый сценарий - чистка временных файлов при завершении скрипта.


#!/usr/bin/env bash
set -euo pipefail

TMP_DIR="$(mktemp -d)"

cleanup() {
rm -rf "$TMP_DIR"
}

trap cleanup EXIT

echo "working in $TMP_DIR"
# основная логика скрипта


mktemp -d создает временный каталог
cleanup() описывает, что нужно убрать
trap cleanup EXIT гарантирует запуск cleanup при выходе из скрипта. Даже если скрипт завершится с ошибкой, временный каталог будет удален.

Можно ловить не только обычный выход, но и прерывание с клавиатуры:


trap cleanup EXIT INT TERM


EXIT - любой выход из скрипта
INT - прерывание через Ctrl+C
TERM - сигнал завершения процесса

▪️ Полезный пример с lock-файлом:


#!/usr/bin/env bash
set -euo pipefail

LOCK_FILE="/tmp/myjob.lock"

cleanup() {
rm -f "$LOCK_FILE"
}

trap cleanup EXIT

if [[ -e "$LOCK_FILE" ]]; then
echo "script already running"
exit 1
fi

touch "$LOCK_FILE"

# основная логика
sleep 30


Но тут важный момент: для защиты от повторного запуска лучше использовать flock, а не просто проверку файла. Зато trap отлично подходит, чтобы гарантированно убрать временные следы после работы.

▪️ Еще полезный прием - выводить сообщение при ошибке:


error_handler() {
echo "error on line $LINENO"
}

trap error_handler ERR


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

▪️ На практике часто объединяют оба подхода:


cleanup() {
rm -rf "$TMP_DIR"
}

on_error() {
echo "script failed on line $LINENO"
}

trap cleanup EXIT
trap on_error ERR


trap не делает скрипт надежным сам по себе. Он только помогает корректно завершиться и прибрать за собой.

#bash #scripting

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3
Безопасная работа с удалением и chmod

find - одна из самых полезных и часто используемых утилит в linux. Но именно с ней часто происходят самые неприятные аварии. Хотели удалить старые логи - удалили не тот каталог. Хотели поправить права - сломали половину /var/www. Хотели найти временные файлы - случайно зацепили mount point. И проблема не в find, а в том, что он очень послушный. Что написали - то и сделал.

Поэтому главное правило: сначала показать, потом делать.

🤩 Плохой подход:


find /var/log -name "*.gz" -delete


🤩 Лучше сначала так:


find /var/log -name "*.gz" -print


Посмотрели список, убедились, что там нет ничего лишнего и только потом добавили действие:


find /var/log -name "*.gz" -delete


Для удаления по возрасту тоже сначала проверяем:


find /backup -type f -mtime +30 -print


И только после проверки:


find /backup -type f -mtime +30 -delete


▪️ Очень важный флаг - -type. Если удаляем файлы, явно пишем:


find /backup -type f -name "*.tar.gz" -mtime +14 -delete


Если меняем права каталогов:


find /var/www -type d -exec chmod 755 {} \;


Если меняем права файлов:


find /var/www -type f -exec chmod 644 {} \;


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

▪️ Для chmod часто удобнее использовать + вместо \;:


find /var/www -type f -exec chmod 644 {} +


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

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


find /data -type f -name "*.log" -print0 | xargs -0 rm -f


Но если можно обойтись встроенным -delete, часто лучше использовать его:


find /data -type f -name "*.log" -mtime +7 -delete


▪️ Еще один полезный предохранитель - ограничение глубины:


find /var/log -maxdepth 1 -type f -name "*.gz" -print


Так find не уйдет рекурсивно во все вложенные каталоги. И наоборот, если нужно пропустить верхний уровень:


find /data -mindepth 1 -type d -empty -delete


Это помогает не удалить сам корневой каталог поиска, если он вдруг окажется пустым.

#bash #find

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42
Добрый вечер 🎩

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁12
💚 Работа с journalctl

Когда сервис падает, первое желание - открыть /var/log и начать искать глазами. Но на современных linux-системах часто быстрее идти сразу в journalctl. journalctl показывает логи из systemd-journald: сервисы, kernel-сообщения, boot-логи, ошибки юнитов и многое другое.

▪️ Самый базовый сценарий:


journalctl -u nginx


Так смотрим логи конкретного сервиса.

Если нужен только последний запуск:


journalctl -u nginx -b


-b ограничивает вывод текущей загрузкой системы. Это удобно, чтобы не утонуть в старых событиях.

Посмотреть последние строки:


journalctl -u nginx -n 100


Следить за логами в реальном времени:


journalctl -u nginx -f


Это аналог tail -f, только для systemd-журнала.

▪️ Если сервис не стартует, полезная связка такая:


systemctl status nginx
journalctl -u nginx -xe


status дает краткую картину, а journalctl уже показывает детали: ошибки конфига, проблемы с правами, отсутствующие файлы, failed dependency и так далее.
Очень удобно фильтровать по времени:


journalctl -u nginx --since "10 minutes ago"


или так:


journalctl -u nginx --since "2026-06-24 10:00" --until "2026-06-24 11:00"


Для разбора аварий это особенно полезно: сужаете окно до момента инцидента и смотрите только нужный кусок.

▪️ Ошибки по всей системе:


journalctl -p err -b


Где -p err показывает сообщения уровня error и выше за текущую загрузку.

▪️ Kernel-сообщения:


journalctl -k -b


Тут можно увидеть проблемы с дисками, драйверами, OOM, сетевыми интерфейсами и железом. Например, если подозрение на OOM killer:


journalctl -k -b | grep -i "killed process"


Еще полезно смотреть логи предыдущей загрузки, если сервер уже перезагрузился после аварии:


journalctl -b -1


А список доступных загрузок:


journalctl --list-boots


Так можно понять, что происходило перед reboot, panic или зависанием.

▪️ Для читаемого вывода без pager:


journalctl -u nginx --no-pager


Для вывода в JSON, если нужно парсить:


journalctl -u nginx -o json


#linux #journalctl

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍1
Pagefile в Windows Server: отключать, уменьшать или оставить как есть

Pagefile в Windows часто вызывает споры. Особенно на серверах, где много RAM. Логика обычно такая: "У нас 64/128/256 ГБ памяти, зачем нам файл подкачки? Отключим и освободим место на диске." Звучит разумно, но в проде это может закончиться странными ошибками, падениями приложений и отсутствием нормального crash dump после аварии.

Pagefile - это не просто "медленная RAM на диске". В Windows он нужен для управления виртуальной памятью и commit limit. Проще говоря, система и приложения могут резервировать память, даже если прямо сейчас физически вся RAM не занята. А commit limit считается примерно как: RAM + pagefile.

Если pagefile отключить, общий лимит commit уменьшается. И приложение может получить ошибку выделения памяти даже тогда, когда в Task Manager "свободная память вроде есть".

▪️ Где pagefile особенно важен:

• SQL Server и другие тяжелые сервисы;
• терминальные серверы;
• серверы с большим количеством процессов;
• системы, где нужны crash dump после BSOD;
• приложения, которые активно резервируют память.

Отключать pagefile полностью обычно плохая идея. Да, иногда это работает годами. А потом в момент нагрузки сервер внезапно начинает вести себя странно: сервисы падают, процессы не стартуют, в логах появляются ошибки memory allocation, а нормального дампа для расследования нет.

▪️ Что делать на практике?

Самый безопасный вариант для большинства серверов: оставить System managed size. Windows сама подберет размер pagefile под нагрузку и конфигурацию системы. Если диск маленький или есть строгие требования по месту, можно задать фиксированный минимальный размер, но полностью отключать не стоит.

Например:

• оставить небольшой pagefile на системном диске для crash dump;
• вынести основной pagefile на отдельный быстрый диск, если это реально нужно;
• контролировать не только RAM, но и commit usage.

▪️ Что смотреть в мониторинге:


Memory\Committed Bytes
Memory\Commit Limit
Paging File\% Usage


Если Committed Bytes регулярно приближается к Commit Limit, проблема не в размере pagefile как таковом. Система реально упирается в доступный commit, и нужно разбираться с нагрузкой или памятью.

Отдельный нюанс - crash dump. Для полноценного дампа памяти Windows может требовать pagefile на системном диске достаточного размера. Если pagefile отключен или слишком мал, после падения системы вы можете не получить нужный дамп.

#windowsserver #pagefile

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
✔️ systemd-timesyncd: где настраивать NTP в Debian

Настройка времени на серверах обычно вспоминается только тогда, когда мониторинг начинает ругаться. В debian сейчас часто по умолчанию работает systemd-timesyncd. Обычно там уже прописаны стандартные NTP-серверы debian вроде:


0.debian.pool.ntp.org


или серверы времени от хостера, если система развернута из его шаблона.

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


systemd-timesyncd[308]: Timed out waiting for reply from 195.90.182.235:123 (0.debian.pool.ntp.org)


То есть timesyncd отправил запрос на NTP-сервер, но не дождался ответа. Первое, что можно попробовать - это заменить набор серверов времени. Основной конфиг находится здесь:


/etc/systemd/timesyncd.conf


Но лучше не править его напрямую, а сделать drop-in конфигурацию:


mkdir -p /etc/systemd/timesyncd.conf.d
nano /etc/systemd/timesyncd.conf.d/custom.conf


Добавляем свои NTP-серверы:


[Time]
NTP=0.ru.pool.ntp.org 1.ru.pool.ntp.org 2.ru.pool.ntp.org 3.ru.pool.ntp.org
FallbackNTP=ntp0.vniiftri.ru


После этого перечитываем конфигурацию и перезапускаем службу:


systemctl daemon-reload
systemctl restart systemd-timesyncd


Проверить общие настройки времени:


timedatectl


А конкретный статус синхронизации:


timedatectl timesync-status


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


Server: 51.250.35.68 (0.ru.pool.ntp.org)


Логи службы удобно смотреть так:


journalctl -u systemd-timesyncd


Если время вообще не синхронизируется с внешними серверами, не спешите часами копаться в конфиге. Очень часто NTP-трафик режется на стороне провайдера. Причина простая: UDP/123, как и DNS, может использоваться в DDoS amplification-атаках. Поэтому некоторые провайдеры блокируют внешний NTP и предлагают использовать свои внутренние серверы времени.

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

Есть и обходные варианты. Например, можно использовать htpdate, который получает время через HTTP:


apt install htpdate


Но это уже скорее запасной вариант, а не замена нормальной NTP-синхронизации.

#linux #timesyncd

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
👥 Кто установил или удалил приложение в Windows Server

Когда инфраструктурой управляет несколько администраторов или команд, иногда всплывает неприятная ситуация: с сервера пропал агент, приложение или важный компонент. Например, был установлен Zabbix Agent, антивирус, backup-клиент или monitoring exporter, а потом внезапно его нет.

В Windows такие вещи часто можно расследовать через Event Viewer. Если приложение было установлено через MSI-пакет, Windows пишет события от провайдера MsiInstaller в журнал Application.

▪️ Полезные Event ID:

11707 - приложение успешно установлено
11724 - приложение успешно удалено

То есть можно посмотреть, кто и когда устанавливал или удалял нужный MSI-пакет.

▪️Ищем события по Zabbix:


$appname='*Zabbix*'

Get-WinEvent -FilterHashtable @{
LogName="Application"
ID=11707,11724
ProviderName='MsiInstaller'
} |
Where-Object {
$_.Message -like $appname
} |
Select-Object TimeCreated,
@{
Name='Username'
Expression={
(New-Object System.Security.Principal.SecurityIdentifier($_.UserId)).
Translate([System.Security.Principal.NTAccount]).Value
}
},
Message


В результате получим:

• время события
• пользователя
• текст события MSI Installer
• информацию об установке или удалении приложения

Так можно быстро понять, когда именно агент был удален и под какой учетной записью это произошло. Это полезно не только для Zabbix. Можно искать любое MSI-приложение:


$appname='*Chrome*'
$appname='*Backup*'
$appname='*Endpoint*'


▪️ Если нужно посмотреть все установки и удаления MSI-приложений без фильтра по имени:


Get-WinEvent -FilterHashtable @{
LogName="Application"
ID=11707,11724
ProviderName='MsiInstaller'
} |
Select-Object TimeCreated, Id, ProviderName, UserId, Message


Этот способ работает именно для приложений, которые ставились или удалялись через MSI. Если программу удалили вручную, через portable-директорию, скриптом с удалением файлов или сторонним инсталятором без нормальной записи в MSI-события, этих Event ID может не быть.

Еще один нюанс - глубина хранения логов. Если журнал Application уже перезаписан, старые события вы не найдете. Поэтому для нормального расследования лучше заранее настроить: увеличенный размер журналов, Windows Event Forwarding, централизованный сбор логов и аудит административных действий

#windowsserver #eventviewer

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62
👨‍💻 socat: инструмент для диагностики портов, сокетов и туннелей

nc знают почти все. Но если нужно не просто открыть порт или проверить соединение, а быстро связать между собой TCP, UDP, Unix socket, файл, stdin/stdout или сделать простой туннель тут очень выручает socat. Название расшифровывается примерно как SOcket CAT. По сути, это утилита, которая умеет соединять два конца передачи данных. Этими концами могут быть:

TCP-порт;
UDP-порт;
Unix socket;
файл;
pipe;
stdin/stdout;
псевдотерминал;
TLS-соединение.

▪️ Установка:


apt install socat


▪️ Самый простой пример - поднять TCP listener:


socat TCP-LISTEN:8080,fork STDOUT


Теперь все, что прилетает на порт 8080, будет выводиться в терминал.

Можно сделать простой echo-сервер:


socat TCP-LISTEN:8080,fork EXEC:/bin/cat


Подключаемся:


nc 127.0.0.1 8080


И все, что отправляем, возвращается обратно.

▪️ Очень частый сценарий - проброс порта:


socat TCP-LISTEN:8080,fork TCP:10.10.20.15:80


Теперь локальный порт 8080 будет проксировать трафик на 10.10.20.15:80. Это удобно, когда нужно быстро проверить сервис, временно открыть доступ или обойти неудобную сетевую схему без настройки полноценного reverse proxy.

▪️ socat также отлично работает с Unix socket. Например, если приложение слушает только Unix socket, можно временно вывести его в TCP:


socat TCP-LISTEN:9000,fork UNIX-CONNECT:/run/app/app.sock


И наоборот - TCP в Unix socket:


socat UNIX-LISTEN:/tmp/test.sock,fork TCP:127.0.0.1:8080


▪️ Еще полезный пример - тест UDP:


socat - UDP-LISTEN:5353,fork


И отправка UDP-пакета:


echo "test" | socat - UDP:127.0.0.1:5353


socat - это не замена нормальному reverse proxy, firewall, VPN или service mesh. Но для быстрой диагностики и временного связывания разных типов соединений он невероятно удобен. Когда нужно срочно понять, что происходит с портом, сокетом или сетевым потоком, socat часто оказывается тем самым инструментом, который решает задачу одной командой.

Главное - не забыть потом убрать временный listener.

#linux #socat

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72