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

Сайт: networkadmin.ru
Реклама: @dad_admin
Биржа: https://telega.in/c/networkadminru
Download Telegram
🔎 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
База 🪄

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7😁2
🕜 Как timezone ломает логи, cron и расследование инцидентов

Timezone кажется мелочью ровно до первого инцидента. Сервис упал в 03:10. Мониторинг сработал в 00:10. В логах приложения ошибка в 05:10. А cron, который точно должен был запуститься ночью, вообще отработал не тогда. И начинается расследование не аварии, а вопроса: "чье это вообще время?" Проблема в том, что в инфраструктуре легко получить несколько разных временных реальностей:

• сервер живет в UTC;
• приложение пишет логи в локальном времени;
• контейнер использует другой timezone;
• база хранит timestamp без offset;
• мониторинг показывает время браузера;
• cron работает по системному времени хоста;
• разработчик смотрит все из своей локальной зоны.

В итоге события вроде бы относятся к одному инциденту, но на таймлайне разъезжаются на 2–3 часа.

▪️ Проверить timezone на Linux:


timedatectl


Посмотреть текущую дату с зоной:


date


Проверить UTC:


date -u


Для systemd-журнала удобно явно указывать временное окно:


journalctl --since "2026-05-29 03:00" --until "2026-05-29 03:30"


Но важно понимать: это окно интерпретируется в локальном времени системы, с которой вы работаете.

С cron тоже есть нюанс. Если на сервере стоит Europe/Moscow, то запись:


0 3 * * * /opt/scripts/backup.sh


запустится в 03:00 по времени этого сервера.

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

▪️ Что помогает не страдать:

• хранить серверное время в UTC;
• писать логи с timezone или offset;
• использовать ISO 8601 формат;
• не хранить timestamp без понимания зоны;
• явно документировать, в каком времени работает cron;
• синхронизировать время через NTP;
• при расследовании сразу строить единый таймлайн.

▪️ Хороший timestamp выглядит примерно так:


2026-05-29T03:10:42Z
# или так:
2026-05-29T06:10:42+03:00


🤩 Плохой timestamp:


2026-05-29 03:10:42


Потому что без timezone непонятно, это UTC, Москва, Хельсинки, время контейнера или фантазия приложения.

#linux #timezone

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1
📎 mergerfs: объединяем несколько дисков в одну точку монтирования

Иногда нужно быстро объединить несколько разных дисков в один общий каталог, но без RAID, LVM и сложной перестройки хранилища. Например, есть два диска, смонтированные так:


/mnt/sda
/mnt/sdb


А хочется получить одну общую точку: /mnt/storage. Чтобы приложения видели это как единое хранилище, а файлы физически раскладывались по исходным дискам. Для такой задачи хорошо подходит mergerfs. Это не RAID и не замена бэкапам. Это именно логическое объединение каталогов в одну файловую систему поверх уже существующих маунт поинтов.

▪️ Где это может пригодиться:

• видеосервер с архивом камер. Можно объединить несколько разнородных дисков и указать видеосерверу один общий путь.
• сервер со статикой или кэшем. Когда отказоустойчивость не критична, но нужно удобно расширять объем.
• backup-хранилище. Для некоторых сценариев бэкапов логическое объединение дисков вполне допустимо.
• сервер с дисками разного размера. Например, есть 2 ТБ + 3 ТБ, и хочется получить один общий каталог без плясок с RAID-массивами.

▪️ Пример на практике. Допустим, у нас есть два диска /dev/sda и /dev/sdb. Создаем разделы, файловые системы и монтируем их:


cfdisk /dev/sda
cfdisk /dev/sdb

mkfs.ext4 /dev/sda1
mkfs.ext4 /dev/sdb1

mkdir -p /mnt/sda1 /mnt/sdb1
mount /dev/sda1 /mnt/sda1
mount /dev/sdb1 /mnt/sdb1


Проверяем:


df -h


Теперь ставим mergerfs:


apt install mergerfs


Создаем общую точку монтирования:


mkdir -p /mnt/storage


И объединяем два диска:


mergerfs -o defaults,allow_other,category.create=mfs,moveonenospc=true,minfreespace=1G \
/mnt/sda1:/mnt/sdb1 /mnt/storage


После этого /mnt/storage будет показывать суммарный объем двух дисков. Проверяем:


df -h | grep storage


▪️ Что означают опции:

allow_other - Позволяет видеть файловую систему не только root, но и другим пользователям.
category.create=mfs - Новые файлы создаются там, где больше свободного места. mfs - most free space.
moveonenospc=true - Если при записи на выбранном диске закончилось место, mergerfs попробует перенести файл на другой диск.
minfreespace=1G - Если на диске осталось меньше 1 ГБ, новые файлы туда больше не пишутся.

▪️ Проверить распределение можно простыми файлами:


dd if=/dev/zero of=/mnt/storage/tempfile1 bs=1M count=1000
dd if=/dev/zero of=/mnt/storage/tempfile2 bs=1M count=1000

ls /mnt/storage
ls /mnt/sda1
ls /mnt/sdb1


Файлы будут видны в общей точке /mnt/storage, но физически лежать на одном из исходных дисков. Это важное отличие от RAID: каждый файл хранится целиком на конкретном диске, а не размазывается блоками по всем устройствам.

▪️ Плюсы такого подхода:

• можно объединять диски разного размера
• не нужно пересобирать массив
• легко добавить новый диск
• файлы остаются читаемыми напрямую с исходных mount point’ов
• удобно для статичных данных, кэша, архивов и бэкапов

▪️ Но есть и ограничения. Если один диск умрет, вы потеряете файлы, которые лежали именно на нем. Остальные диски при этом останутся читаемыми.
То есть mergerfs дает удобство единого пространства, но не дает отказоустойчивость. Для постоянного подключения mergerfs можно добавить в /etc/fstab или оформить через systemd mount. Это уже зависит от того, как вы привыкли управлять маунтами.

#mergerfs #storage

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
📷 QR-код прямо в консоли Linux или Windows Terminal

Иногда нужно быстро передать ссылку, Wi-Fi пароль, токен для теста или короткий текст с сервера на телефон. Можно не открывать браузер и не генерировать картинку. QR-код можно вывести прямо в терминале. В linux для этого удобно использовать qrencode.

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


apt install qrencode


▪️ Сгенерировать QR-код в консоли:


qrencode -t ANSIUTF8 "https://networkadmin.ru"


В терминале появится QR-код, который можно сразу отсканировать телефоном.

Если нужен PNG-файл:


qrencode -o qrcode.png "https://networkadmin.ru"


Можно передавать данные из pipe:


echo "ssh user@10.10.10.5" | qrencode -t ANSIUTF8


▪️ В Windows Terminal тоже можно использовать этот подход через WSL. Например, в Ubuntu внутри WSL:


sudo apt install qrencode
qrencode -t ANSIUTF8 "https://networkadmin.ru"


Если WSL нет, можно использовать PowerShell-модуль или сторонние утилиты, но через WSL обычно быстрее и проще.

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

#terminal #qrcode

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔒 Почему стандартной парольной политики AD часто недостаточно

В Active Directory можно настроить длину пароля, срок действия, историю и требования к сложности. Но есть неприятный нюанс: стандартная политика сложности не понимает, что такое плохой, но формально сложный пароль. Например:


Qwerty123
P@ssw0rd
Company2026
Admin@123


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

Фактически - это словарные и шаблонные пароли, которые легко угадываются или быстро подбираются. Проблема в том, что стандартная парольная политика AD проверяет структуру пароля, но плохо понимает его смысл. То есть пароль вида: P@ssw0rd2026! может выглядеть сложным для политики, но быть очень слабым с точки зрения реальной безопасности.

▪️ Как это можно исправить? В Windows смена пароля проходит через LSA. На контроллере домена в цепочку проверки можно добавить дополнительный password filter - компонент, который будет проверять новый пароль перед установкой. Такой фильтр может запретить пароль, если он:

• входит в список запрещенных слов
• похож на название компании
• содержит имя пользователя
• совпадает с типовыми шаблонами
• найден в базе скомпрометированных паролей
• слишком предсказуемо меняется по годам или сезонам

▪️ Из open-source решений для AD часто смотрят в сторону:

• PassFiltEx
• Lithnet Password Protection for Active Directory

Оба варианта позволяют расширить стандартную проверку паролей и отсеивать то, что обычная политика AD пропускает. Например, можно запретить пароли, связанные с: названием компании, доменом, брендами, городами, типовыми словами вроде Password, Qwerty, Admin, годовыми шаблонами вроде 2025, 2026, известными утечками паролей. Это особенно полезно в инфраструктурах, где пользователи любят обновлять пароль по принципу: Winter2025! Spring2026! Company2026!

С точки зрения пользователя - пароль новый. С точки зрения атакующего - почти тот же самый шаблон.

#windows #activedirectory

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Трезвый DevOps - уже не DevOps

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5
Как смотреть потоки процесса через ps, /proc и strace

Обычно при работе с ps мы смотрим процесс по PID или грепаем по имени:


ps -p 524 -o %mem,%cpu,cmd
ps ax | grep prometheus


Но часто удобнее сразу указать имя процесса через -C. Например, посмотрим потоки prometheus:


ps -T -C prometheus

PID SPID TTY TIME CMD
525 525 ? 00:55:34 prometheus
525 803 ? 00:03:10 prometheus
525 808 ? 00:09:22 prometheus
525 1054 ? 00:08:44 prometheus


PID - ID основного процесса
SPID - ID конкретного потока

▪️ Посчитать количество потоков


ps -T -C zabbix_server | wc -l


Важно: количество потоков и количество процессов - не одно и то же. Например:


ps -T -C zabbix_server | wc -l
ps ax | grep zabbix_server | wc -l


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

▪️ Посмотреть нагрузку по потокам. Если приложение тормозит, полезно вывести CPU/MEM с разбивкой по потокам. Например, для процесса с PID 508:


ps -L -o spid,%mem,%cpu,cmd 508

SPID %MEM %CPU CMD
1070 0.6 0.0 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
1071 0.6 0.1 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
1077 0.6 0.3 /usr/bin/python3 /usr/bin/fail2ban-server -xf start


Так можно увидеть, какой именно поток ест CPU.

▪️ Найти подробности потока через /proc. Если знаем PID процесса и SPID потока:


cat /proc/508/task/1077/stat


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


1077 (f2b/f.wp-login)


У Fail2ban это может подсказать, какой jail сейчас нагружает систему. Больше информации:


cat /proc/508/task/1077/status


▪️ Подключить strace к конкретному потоку. strace умеет подключаться не только к PID процесса, но и к SPID потока:


strace -p 1077


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


strace -p 1077 -o ~/strace.out


Можно ограничить типы системных вызовов. Открытие файлов и чтение:


strace -p 1077 -e trace=openat,read


Запись:


strace -p 1077 -e trace=write


Сеть:


strace -p 1077 -e trace=connect,recvfrom,sendto


▪️ Через htop. В htop тоже можно смотреть трейсы. Выберите нужный процесс или поток и нажмите: s. Если strace установлен, htop покажет системные вызовы в реальном времени.

#linux #htop

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
systemd.path: запуск действия при изменении файла

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

Например:

изменился конфиг - перезапустить сервис
появился файл - запустить обработчик
обновился сертификат - скопировать его и сделать reload

▪️ Пример: реагируем на изменение конфига. Допустим, нужно выполнить действие при изменении файла:


/etc/daemon/daemon.conf


Создаем unit:


/etc/systemd/system/daemon.path
[Unit]
Description=Watch /etc/daemon/daemon.conf for changes

[Path]
PathModified=/etc/daemon/daemon.conf

[Install]
WantedBy=multi-user.target


Этот .path будет следить за изменением файла.

▪️ Сервис, который запустится по событию. Теперь создаем:


/etc/systemd/system/daemon.service



[Unit]
Description=Run action after daemon.conf change

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo "daemon config changed at $(date)" >> /etc/daemon/restart.date'


Для примера сервис просто пишет дату события в файл:


/etc/daemon/restart.date


На практике в ExecStart можно указать любой скрипт:

• перезапуск сервиса;
• reload nginx;
• копирование файла;
• отправка алерта;
• валидация конфига.

▪️ Включаем и запускаем


systemctl daemon-reload
systemctl enable --now daemon.path


Проверяем статус:


systemctl status daemon.path


Теперь изменяем файл:


echo "# test" >> /etc/daemon/daemon.conf


И смотрим результат:


cat /etc/daemon/restart.date


Должна появиться новая строка с текущей датой.

▪️ Почему это удобно. Главный плюс- все работает через systemd. Значит, события и ошибки можно смотреть привычно:


journalctl -u daemon.path
journalctl -u daemon.service


Не нужно писать отдельный бесконечный watcher на bash или городить cron.

▪️ Полезные директивы


[Path]
PathModified=/path/file


Срабатывает при изменении файла.


PathChanged=/path/file


Срабатывает после закрытия файла, в который была запись.


PathExists=/path/file


Срабатывает, когда файл или каталог появился.


PathExistsGlob=/path/*.conf


То же самое, но с маской.


DirectoryNotEmpty=/path/dir


Срабатывает, когда в пустом каталоге появился файл.

#linux #systemd

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