4722
Авторский блог про сетевое и системное администрирование. Сайт: networkadmin.ru Реклама: @dad_admin Биржа: https://telega.in/c/networkadminru
🤩 Как грепнуть вывод, который "не грепается"
Иногда команда что-то выводит в терминал, но обычный grep внезапно ничего не находит.
Хороший пример - проверка модулей Nginx:
nginx -V
nginx -V | grep http_realip_module
nginx -V пишет вывод не в stdout, а в stderr. А пайп | по умолчанию передает дальше только stdout. Решение:
nginx -V 2>&1 | grep http_realip_module
2>&1
grep, awk, sed и другие утилиты.nginx -V обычно идут одной длинной строкой. Чтобы сделать вывод более читаемым, можно разбить его по пробелам:
nginx -V 2>&1 | tr ' ' '\n' | grep http_realip_module
--with-http_realip_module
2>&1 - объединяем stderr и stdout tr ' ' '\n' - заменяем пробелы переносами строк grep - ищем нужный параметр
command 2>&1 | grep error
command >stdout.log 2>stderr.log
❌ UAC в Windows Server: почему админ не всегда "полный админ"
В Windows Server можно войти под учеткой из группы Administrators и все равно получить: Access denied. Это не баг. Чаще всего причина - UAC.
После входа администратор обычно получает два security token:
• обычный, с урезанными правами
• elevated, с полными административными правами
Поэтому PowerShell или CMD, запущенные обычным способом, могут работать не так, как ожидается.
▪️ Проверить, входит ли пользователь в локальные администраторы:
whoami /groups
$principal = New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
$principal.IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
False
Start-Process powershell.exe -Verb RunAs
Access denied.
🔍 Как посмотреть environment-переменные запущенного процесса
Иногда во время диагностики нужно понять, в каком окружении реально запущено приложение. Например:
• какой PATH оно видит
• какой HOME используется
• под каким пользователем работает
• какие переменные передал systemd
• какой config-файл или endpoint попал в environment
/proc/<PID>/
/proc/<PID>/environ
cat /proc/1427/environ
LANG=en_US.UTF-8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binHOME=/var/lib/prometheusUSER=prometheus...
/proc/<PID>/environ разделены не переносами строк, а символом NUL. Поэтому читать такой вывод неудобно.xargs:
xargs -0 -n1 < /proc/1427/environ
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
HOME=/var/lib/prometheus
USER=prometheus
LOGNAME=prometheus
SHELL=/usr/sbin/nologin
tr '\0' '\n' < /proc/1427/environ
tr '\0' '\n' < /proc/1427/environ | grep '^PATH='
pgrep -a prometheus
systemctl show prometheus -p MainPID
ps eww -p 1427
🪄 Почему просто пробросить порт иногда не работает
Классическая задача: есть сервер за NAT, нужно открыть наружу его сервис. Делаем DNAT:
iptables -t nat -A PREROUTING \
-p tcp --dport 8443 \
-j DNAT --to-destination 10.20.0.15:443
conntrack - механизмом отслеживания состояний соединений.
клиент → внешний IP:8443
↓ DNAT
10.20.0.15:443
Client → NAT → Backend
Client ←────── Backend
iptables -t nat -A POSTROUTING \
-d 10.20.0.15 \
-p tcp --dport 443 \
-j MASQUERADE
conntrack -L
conntrack -L -p tcp --dport 443
conntrack -S
sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
nf_conntrack: table full, dropping packet
tcpdump:
tcpdump -i any -nn port 8443 or port 443
✨ Systemd-команды, которые быстро дают информацию о системе
У systemd есть несколько команд, которыми удобно пользоваться почти на любом современном linux-дистрибутиве. Плюс в том, что интерфейс везде примерно одинаковый: ubuntu, debian, rocky и другие системы.
1️⃣ hostnamectl - что это вообще за сервер
Одна из самых полезных команд:
hostnamectl
Static hostname: app-prod-02
Icon name: computer-vm
Chassis: vm
Machine ID: 97e42f42c9da49e39a8c0fcb45a2d772
Boot ID: 8aa12e8be6874464a2ec83c070bdcc76
Virtualization: kvm
Operating System: Ubuntu 24.04.2 LTS
Kernel: Linux 6.8.0-60-generic
Architecture: x86-64
Hardware Vendor: QEMU
Hardware Model: Standard PC
Сразу видно:
hostname
дистрибутив
версию ядра
архитектуру
виртуализацию
производителя виртуального железа
uname -a
cat /etc/os-release
lsb_release -a
timedatectl
Local time: Mon 2026-09-17 11:38:42 CEST
Universal time: Mon 2026-09-17 09:38:42 UTC
RTC time: Mon 2026-09-17 09:38:42
Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Полезно, когда нужно сразу проверить:
локальное время
UTC
timezone
работает ли синхронизация
в каком режиме RTC
date
timedatectl.
loginctl
SESSION UID USER SEAT LEADER CLASS TTY IDLE
3 1001 admin - 1842 user pts/0 no
loginctl session-status 3
3 - admin (1001)
Since: Mon 2026-09-17 11:20:15 CEST; 18min ago
Leader: 1842 (sshd)
Remote: 10.40.12.27
Service: sshd; type tty; class user
State: active
Unit: session-3.scope
├─1842 "sshd: admin@pts/0"
├─1850 -bash
└─2141 loginctl session-status 3
Здесь уже видно:
когда подключился пользователь
откуда пришел SSH
PID сессии
какие процессы внутри нее запущены
w
who
id
loginctl полезен, когда нужны именно детали systemd-сессии.
journalctl
journalctl -b
journalctl -u nginx
journalctl -p err
journalctl -f
То есть:
логи текущей загрузки
логи конкретного сервиса
только ошибки
просмотр в реальном времени
localectl
System Locale: LANG=en_US.UTF-8
VC Keymap: (unset)
X11 Layout: us
locale
localectl удобен именно как systemd-интерфейс для системных настроек locale.
🥱 Как быстро разобраться с дисками и маунтами
Когда на сервере несколько дисков, LVM, отдельные разделы и сетевые маунты, быстро понять "что куда примонтировано" бывает не так просто. Для базовой диагностики хватает трех команд:
1️⃣ lsblk - структура дисков
lsblk
lsblk -f
sda
├─sda1 ext4 /boot
└─sda2 LVM2_member
├─vg-root ext4 /
└─vg-data xfs /data
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
blkid
/etc/fstab.
/dev/sdb1: UUID="a1b2-c3d4" TYPE="ext4"
/dev/sdb1:
UUID=a1b2-c3d4 /backup ext4 defaults 0 2
findmnt
findmnt /data
findmnt -T /var/lib/myapp/data/file.db
findmnt -t ext4
/etc/fstab:
findmnt --verify
lsblk - какие блочные устройства есть и как они связаны blkid - UUID, LABEL и тип файловой системы findmnt - что и куда реально примонтировано
🤩 Как расшифровать код ошибки Windows через certutil
При установке обновлений Windows рано или поздно встречаются ошибки вида:
0x80070422
certutil.exe. Например:
certutil -error 0x80070422
ERROR_SERVICE_DISABLED
The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.
0x80070422
Get-Service wuauserv,bits,cryptsvc
Get-Service wuauserv | Select-Object Name,Status,StartType
certutil -error полезен не только для Windows Update. Команда помогает расшифровывать различные HRESULT, Win32 и системные коды ошибок, которые встречаются в:Event Viewer
PowerShell
установщиках
службах Windows
DISM
сетевых компонентах
сертификатах и криптографии
certutil -error 0x80070005
E_ACCESSDENIED
Access is denied.
🌚 watch: простая динамическая диагностика в терминале
Иногда не нужен отдельный мониторинг, графики и дашборд. Нужно просто увидеть, как меняется состояние системы прямо сейчас. Для этого в линукс есть простая команда watch. Она периодически запускает другую команду и обновляет вывод в терминале.
Например, смотреть свободное место:
watch df -h
watch -n 1 df -h
watch -d free -h
watch выделит строки и значения, которые изменились между обновлениями.
watch -n 1 'du -sh /var/log'
watch -n 1 free -h
watch -n 1 'ss -s'
watch -n 1 'systemctl --failed'
watch -n 1 'ps -p 1234 -o pid,%cpu,%mem,etime,cmd'
watch -n 1 cat /proc/mdstat
watch -n 1 'find /data/incoming -type f | wc -l'
watch:
watch -t 'ss -s'
watch -n 1 'ps aux | sort -rk 3 | head'
🖥 Windows зависла на "Подготовке Windows": как проверить состояние удаленно
Типичная ситуация: после установки обновлений, компонентов или серверных ролей отправляем Windows в перезагрузку и видим сообщение:
Выполняется подготовка Windows.
Не выключайте компьютер.
PsExec.exe \\192.168.158.10 -u localadmin powershell.exe
PsExec.exe \\192.168.158.10 -i 1 -u localadmin powershell.exe
Get-Volume
Get-Process |
Sort-Object CPU -Descending |
Select-Object -First 15 Name, Id, CPU
Get-CimInstance Win32_Service |
Where-Object State -eq "Stop Pending" |
Select-Object Name, DisplayName, ProcessId, State
TrustedInstaller
Get-Content C:\Windows\Logs\CBS\CBS.log -Tail 50
taskkill /PID <ProcessId> /F
DISM /Online /Cleanup-Image /RestoreHealth
sfc /scannow
Get-WinEvent -FilterHashtable @{
LogName = "System"
StartTime = (Get-Date).AddHours(-6)
} |
Where-Object Message -match "update|servicing|TrustedInstaller" |
Select-Object TimeCreated, Id, LevelDisplayName, Message
👁 Linux audit rules: минимальный набор для контроля критичных файлов
Обычные логи не всегда отвечают на главный вопрос: кто изменил конфигурацию и какой процесс это сделал? Для таких задач в Linux есть auditd. Он фиксирует обращения к файлам на уровне ядра и сохраняет пользователя, процесс, команду и время события.
▪️ Установка:
apt install auditd audispd-plugins
systemctl enable --now auditd
nano /etc/audit/rules.d/critical-files.rules
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
-w /etc/ssh/sshd_config -p wa -k ssh_config
-w /root/.ssh/ -p wa -k ssh_keys
-w /etc/systemd/system/ -p wa -k systemd_units
-w /etc/cron.d/ -p wa -k cron_changes
-w /etc/crontab -p wa -k cron_changes
-w /etc/audit/ -p wa -k audit_config
-w - файл или каталог для наблюдения -p w - запись в файл -p a - изменение атрибутов и прав -k - удобная метка для поиска
augenrules --load
auditctl -l
ausearch -k ssh_config -i
ausearch -k sudoers -ts today -i
aureport -f -i
какой файл изменили
UID и реального пользователя
PID процесса
исполняемую команду
успешность операции
точное время
Вы не заставите меня их закрыть. 🤩
#юмор
🧑💻 NetworkAdmin
💚 Как один неверный chmod -R ломает прод сильнее, чем падение сервиса
Падение сервиса обычно видно сразу. Мониторинг красный, пользователи жалуются, в логах ошибка. Перезапустили, откатили, восстановили. А вот один неверный chmod -R может сломать прод намного тише и неприятнее. Классический сценарий:
chmod -R 777 /var/www
chmod -R 755 /
• SSH перестанет принимать ключи, потому что~/.ssh и authorized_keysстали слишком открытыми
• приватные ключи начнут считаться небезопасными
• nginx/apache потеряют доступ к нужным файлам или, наоборот, получат лишний доступ
• база данных откажется стартовать из-за неправильных прав на data directory
• sudo может начать ругаться на права конфигов
• приложения начнут писать туда, куда не должны
• исполняемые файлы потеряют нужные биты
chmod -R 755 "$DIR"
$DIR пустой, неправильный или подставился не тот путь - последствия могут быть очень неприятными.
: "${DIR:?DIR is empty}"
find "$DIR" -maxdepth 2 -print
chmod -R 755 /var/www/app
find /var/www/app -type d -exec chmod 755 {} +
find /var/www/app -type f -exec chmod 644 {} +
chown -R www-data:www-data /var/www/app/storage
ls -la
namei -l /var/www/app/storage/file.log
stat /var/www/app/storage
namei -l особенно удобен: он показывает права на каждом уровне пути.
🤩 Почему места достаточно, но приложение всё равно не может записать файл
Иногда на сервере возникает странная ситуация. Проверяем диск:
df -h
No space left on device
df -i
IUse% близко к 100%, новые файлы создаваться не будут, даже если свободные гигабайты еще есть. Типичные виновники: миллионы мелких cache-файлов, сессии приложения, временные файлы, мелкие логи и т.д. Найти каталоги с большим количеством файлов:
find /var -xdev -type f | cut -d/ -f1-3 | sort | uniq -c | sort -nr | head
quota -s
xfs_quota -x -c 'report -h' /mountpoint
/data, а сервис пишет в /var/lib/app, /tmp или внутрь контейнера. Полезно посмотреть mount point:
df -h /path/to/file
systemctl cat myapp.service
systemctl show myapp.service | grep -i limit
findmnt -o TARGET,OPTIONS
mount | grep ' ro,'
✏️ Пишем события скриптов в Windows Event Viewer
В Windows-скриптах часто делают логирование в обычные текстовые файлы:
C:\Scripts\Logs\script.log
New-EventLog -LogName Application -Source "MyScript"
После этого можно писать события в журнал Application:
Write-EventLog `
-LogName Application `
-Source "MyScript" `
-EntryType Information `
-EventID 1 `
-Message "Запущен PowerShell-скрипт опроса состояния сервера"
Write-EventLog `
-LogName Application `
-Source "MyScript" `
-EntryType Error `
-EventID 1001 `
-Message "Скрипт завершился с ошибкой при подключении к серверу"
1 - старт скрипта
2 - успешное завершение
100 - предупреждение
1001 - ошибка подключения
1002 - ошибка доступа
New-EventLog -LogName CustomPSLog -Source "PS1Script"
Write-EventLog `
-LogName CustomPSLog `
-Source "PS1Script" `
-EntryType Information `
-EventID 1 `
-Message "PowerShell script started"
eventcreate /t information /l application /id 1 /d "BAT script started"
eventcreate /t error /l application /id 1001 /d "BAT script failed"
💚 Test-NetConnection: удобная диагностика сети в Windows без telnet
В PowerShell есть встроенная команда Test-NetConnection, которую удобно использовать для быстрой сетевой диагностики. У нее есть короткий alias:
tnc
tnc
ComputerName : internetbeacon.msedge.net
RemoteAddress : 13.107.4.52
InterfaceAlias : Ethernet
SourceAddress : 192.168.50.24
PingSucceeded : True
PingReplyDetails (RTT) : 28 ms
• какой интерфейс используется
• локальный IP
• удаленный IP
• проходит ли ICMP
• RTT
tnc app01.pc_02.local -Port 443
ComputerName : app01.pc_02.local
RemoteAddress : 10.30.10.15
RemotePort : 443
InterfaceAlias : Ethernet
SourceAddress : 192.168.50.24
TcpTestSucceeded : True
TcpTestSucceeded : True
tnc 8.8.8.8 -TraceRoute
tnc db01.networkadmin.local -Port 5432 -InformationLevel Detailed
tnc db01.networkadmin.local -Port 5432 -InformationLevel Quiet
True
if (tnc db01.networkadmin.local -Port 5432 -InformationLevel Quiet) {
"PostgreSQL доступен"
}
🦖 GNU parallel: когда xargs уже мало для массовых задач
Для простого параллельного запуска часто хватает xargs:
cat hosts.txt | xargs -n1 -P4 ping -c 1
apt install parallel
parallel -j 4 ping -c 1 ::: 10.20.0.11 10.20.0.12 10.20.0.13
-j 4 означает, что одновременно выполнять максимум 4 задания.
parallel -j 8 'curl -fsS http://{}/health' :::: hosts.txt
find /var/log -name '*.gz' -print0 |
parallel -0 -j 4 'gzip -t {}'
parallel -k -j 4 'echo START {}; sleep 2; echo DONE {}' ::: srv1 srv2 srv3
-k результаты будут появляться по мере завершения задач.
parallel --halt soon,fail=1 -j 4 './deploy.sh {}' :::: hosts.txt
parallel -S server1,server2 'hostname; uptime' ::: 1
xargs -P отлично подходит, если нужно:быстро распараллелить одну простую команду
минимум синтаксиса
не нужен сложный контроль выполнения
parallel удобнее, когда нужны:несколько источников аргументов
управление количеством джобов
сохранение порядка вывода
остановка при ошибках
удаленный запуск
более сложные шаблоны команд
parallel -j 6 './backup.sh {} > logs/{}.log 2>&1' :::: databases.txt
🔐 PASSWD_NOTREQD в Active Directory: почему этот флаг нужно контролировать
При стандартной парольной политике Active Directory пользователь не может иметь пустой пароль, если в домене настроены минимальная длина и требования к сложности. Но есть исключение - флаг:
PASSWD_NOTREQD
PasswordNotRequired
Get-ADUser -Filter {PasswordNotRequired -eq $true} `
-Properties PasswordNotRequired |
Select-Object SamAccountName,Enabled,PasswordNotRequired
Особенно важно проверить:
• привилегированные учетные записи
• сервисные аккаунты
• старые или забытые учетные записи
• пользователей, созданных через автоматизацию
• тестовые аккаунты, которые случайно остались в проде
Get-ADUser -Filter {PasswordNotRequired -eq $true} `
-Properties PasswordNotRequired,LastLogonDate,Description |
Select-Object SamAccountName,Enabled,LastLogonDate,Description
Set-ADUser -Identity "test-user" -PasswordNotRequired $false
✍️ DNS-диагностика без гадания и браузера
Когда сайт не открывается, очень легко сразу обвинить nginx, firewall или приложение. Но проблема может быть банально в DNS. Для нормальной диагностики удобнее всего использовать dig.
▪️ Базовый запрос:
dig networkadmin.ru
ANSWER SECTION
dig +short networkadmin.ru
dig @8.8.8.8 networkadmin.ru
dig @10.20.0.10 app.networkadmin.ru
dig @1.1.1.1 app.networkadmin.ru
dig A networkadmin.ru
dig AAAA networkadmin.ru
dig MX networkadmin.ru
dig TXT networkadmin.ru
dig NS networkadmin.ru
dig +trace networkadmin.ru
dig networkadmin.ru
ANSWER SECTION- показывает, сколько секунд ответ еще может храниться в кеше.
dig -x 203.0.113.15
cat /etc/resolv.conf
resolvectl status
🖥 Get-ADUser: полезные примеры для работы с пользователями Active DirectoryGet-ADUser - один из самых часто используемых PowerShell-командлетов при работе с active directory. С его помощью можно получать информацию о пользователях:
логин и имя
отдел и должность
компанию
состояние учетной записи
дату истечения пароля
дополнительные AD-атрибуты
ActiveDirectory
Get-Module -ListAvailable ActiveDirectory
Get-ADUser -Filter *
Get-ADUser возвращает только базовый набор свойств.-Properties. Например, посмотреть все свойства пользователя:
Get-ADUser -Identity "petrov" -Properties *
Get-ADUser -Identity "petrov" `
-Properties Company,Department,Title,Mail |
Select-Object Name,Company,Department,Title,Mail
Get-ADUser -Filter {
Enabled -eq $true -and Mail -notlike "*"
} -Properties Mail |
Select-Object Name,SamAccountName,Mail
Get-ADUser -Filter {
Enabled -eq $true
} -Properties PasswordExpired |
Where-Object PasswordExpired |
Select-Object Name,SamAccountName,PasswordExpired
Get-ADUser -Filter {
Department -eq "IT"
} -Properties Department,Title |
Select-Object Name,Department,Title
Get-ADUser -Filter * `
-Properties Mail,Department,Title |
Select-Object Name,SamAccountName,Mail,Department,Title |
Export-Csv C:\Temp\ad-users.csv -NoTypeInformation -Encoding UTF8
🔎 TCP keepalive: как находить мертвые соединения до того, как они создадут проблему
Иногда TCP-соединение выглядит живым, хотя в реальности удаленная сторона уже давно недоступна.
Например:
клиент выключился;
оборвался VPN;
пропал маршрут;
firewall удалил state;
NAT-сессия протухла;
сервер завис без корректного закрытия соединения.
sysctl net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_intvl
sysctl net.ipv4.tcp_keepalive_probes
tcp_keepalive_time - сколько ждать простоя до первой проверкиtcp_keepalive_intvl - интервал между проверкамиtcp_keepalive_probes - сколько неудачных попыток сделать
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=5
cat > /etc/sysctl.d/99-tcp-keepalive.conf <<'EOF'
net.ipv4.tcp_keepalive_time=300
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=5
EOF
sysctl --system
ss -nto
ss -ti
SO_KEEPALIVE. То есть одной настройки sysctl иногда недостаточно. Например, nginx, PostgreSQL, HAProxy, SSH и различные runtime могут иметь собственные keepalive-параметры.
ServerAliveInterval 30
ServerAliveCountMax 3
💻 Как жестко перезагрузить linux, когда обычный reboot уже не помогает
Иногда сервер зависает настолько неприятно, что обычные команды:
reboot
shutdown -r now
systemctl reboot
echo b > /proc/sysrq-trigger
/proc/sysrq-trigger может сработать даже в довольно поврежденной системе.
cat /proc/sys/kernel/sysrq
echo h > /proc/sysrq-trigger
journalctl -k
dmesg
echo s > /proc/sysrq-trigger
echo u > /proc/sysrq-trigger
echo b > /proc/sysrq-trigger
👌 Firewall default deny: как внедрять без внезапного отрезания доступа
Идея простая: разрешаем только то, что действительно нужно, все остальное блокируем. На бумаге это выглядит идеально. На практике одна неправильная команда - и SSH-сессия заканчивается вместе с доступом к серверу.
Поэтому default deny лучше внедрять не одной командой, а поэтапно.
▪️ Для nftables базовая политика может выглядеть так:
table inet filter {
chain input {
type filter hook input priority 0;
policy drop;
iif lo accept
ct state established,related accept
tcp dport 22 ip saddr 10.20.0.0/16 accept
tcp dport { 80, 443 } accept
}
}
iif lo accept
ct state established,related accept
policy drop сначала выпишите все, что сервер реально принимает:
ss -lntup
ss -nt
SSH / RDP
мониторинг
бэкап
DNS
NTP
балансировщики
кластеры
drop.
nft -c -f /etc/nftables.conf
-c проверит синтаксис, не применяя правила.
echo "nft flush ruleset" | at now + 5 minutes
atq
atrm <job_id>
🌲 Как посмотреть дерево процессов в Linux: htop, ps и pstree
Когда нужно понять, какой процесс кого запустил, обычного списка ps часто недостаточно. Намного удобнее посмотреть процессы в виде дерева: родительский процесс -> дочерние процессы -> подпроцессы. Есть несколько простых способов.
1️⃣ Дерево процессов в htop. Если htop уже установлен, нажмите: t. Это переключит список в режим Tree View. Так удобно быстро посмотреть структуру процессов прямо в интерактивном интерфейсе: например, какие worker-процессы запустил nginx, systemd или приложение.
Но если процессов много и вывод нужно спокойно изучить, интерактивный интерфейс бывает не самым удобным.
2️⃣ Команда ps axf Консольный вариант:
ps axf
f показывает процессы в виде ASCII-дерева. Если вывод большой, его можно сохранить в файл:
ps axf > ~/process-tree.txt
ps -eo user,pid,ppid,stat,lstart,cmd --forest
pstree входит в пакет psmisc, который часто уже установлен в системе.
apt install psmisc
pstree
pstree -p
pstree -a
pstree -p 1234
pstree -p username
-p- показывает PID-a- показывает аргументы командной строки-n- сортирует процессы по PID-u- показывает смену пользователя-s- показывает родителей указанного процесса-c- не объединяет одинаковые ветки
pstree -p -a -u
💚 Bonding в Linux: active-backup, LACP и типовые ошибки настройки
Bonding объединяет несколько сетевых интерфейсов в один логический bond0. Обычно его используют для:
• резервирования сетевого подключения
• распределения нагрузки
• защиты от отказа кабеля, порта или сетевой карты
• увеличения суммарной пропускной способности
Два самых популярных режима - active-backup и 802.3ad.
▪️ Active-backup. В каждый момент работает только один интерфейс. Второй находится в резерве и включается при отказе основного.
[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=active-backup
MIIMonitorSec=100ms
Primary=eno1
[Bond]
Mode=802.3ad
MIIMonitorSec=100ms
LACPTransmitRate=fast
TransmitHashPolicy=layer3+4
cat /proc/net/bonding/bond0
текущий активный интерфейс
состояние каждого slave
скорость и duplex
количество переключений
состояние LACP
ip -br link
ip -s link show bond0
ethtool eno1
• включили802.3ad, но не настроили LAG на коммутаторе
• порты подключены к разным независимым коммутаторам без MLAG/stack
• IP назначен одновременно наbond0и физические интерфейсы
• интерфейсы имеют разную скорость или MTU
• забыли удалить старые маршруты и конфигурации slave-интерфейсов
• считают, что LACP удвоит скорость одного соединения
• проверяют толькоlink up, хотя трафик через порт не проходит
📁 Логирование скриптов в Windows Event Viewer
Для логов PowerShell и BAT-скриптов необязательно создавать отдельные текстовые файлы. Важные события можно записывать прямо в Event Viewer. Это удобно, потому что такие записи проще искать, фильтровать и собирать централизованно через WEF, SIEM или систему мониторинга.
▪️ Сначала создадим отдельный источник событий:
New-EventLog -LogName Application -Source "MyScript"
Write-EventLog `
-LogName Application `
-Source "MyScript" `
-EntryType Information `
-EventID 1 `
-Message "Запущен PowerShell-скрипт проверки состояния сервера"
Write-EventLog `
-LogName Application `
-Source "MyScript" `
-EntryType Error `
-EventID 1001 `
-Message "Не удалось подключиться к серверу"
1 -запуск скрипта
2 - успешное завершение
100 - предупреждение
1001 - ошибка выполнения
New-EventLog -LogName CustomPSLog -Source "PS1Script"
Write-EventLog `
-LogName CustomPSLog `
-Source "PS1Script" `
-EntryType Information `
-EventID 1 `
-Message "Скрипт запущен"
eventcreate /t information /l application /id 1 /d "BAT script started"
eventcreate /t error /l application /id 1001 /d "BAT script failed"
⏰ Точное время до запуска сервисов: одноразовая синхронизация через chrony
Обычно синхронизация времени в Linux работает незаметно: установили chrony, systemd-timesyncd или другой NTP-клиент - и забыли. Но после загрузки виртуальной машины системное время иногда отличается на несколько минут. Служба синхронизации исправит его, однако часть сервисов к этому моменту уже может успеть запуститься.
В результате появляются:
• события в логах с неправильным временем
• ошибки проверки сертификатов
• проблемы с Kerberos и токенами
• некорректный порядок событий
• странности в распределенных системах и мониторинге
Для обычной работы постепенная коррекция времени подходит. Но на старте иногда нужно сначала выставить часы, а уже потом запускать приложение. Для этого можно создать одноразовый systemd-unit с chronyd -q.
▪️ Устанавливаем chrony:
apt install chrony
systemctl edit --force --full chrony-once-sync.service
[Unit]
Description=Initial time synchronization with chrony
Wants=network-online.target
After=network-online.target
Before=myapp.service
[Service]
Type=oneshot
ExecStart=/usr/sbin/chronyd -q -t 10
[Install]
WantedBy=multi-user.target
-q - один раз выставить время и завершить работу -t 10 - прекратить попытку через 10 секунд After=network-online.target - запускать после готовности сети Before=myapp.service - выполнить синхронизацию раньше критичного приложения
systemctl daemon-reload
systemctl enable chrony-once-sync.service
systemctl status chrony-once-sync.service
journalctl -u chrony-once-sync.service -b
systemd-analyze critical-chain myapp.service
😩 systemd-analyze: почему сервер долго загружается и кто виноват
Иногда сервер после reboot поднимается подозрительно долго. Вроде железо нормальное, диск живой, сервисов не так много, но до нормального состояния система доходит через минуту, две или даже дольше.
В systemd для такого разбора есть удобная утилита:
systemd-analyze
Startup finished in 5.2s (kernel) + 28.4s (userspace) = 33.6s
systemd-analyze blame
12.834s docker.service
8.421s NetworkManager-wait-online.service
6.102s postgresql.service
3.451s nginx.service
blame показывает длительность запуска юнитов, но не всегда показывает реального виновника. Сервисы могут запускаться параллельно, и длинный сервис не обязательно блокировал всю загрузку.
systemd-analyze critical-chain
systemd-analyze critical-chain docker.service
ожидание сети
зависший mount из /etc/fstab
медленный DNS
NFS/SMB mount без `nofail`
долгий старт базы данных
Docker/container runtime
cloud-init
некорректные зависимости в юнитах
таймауты несуществующих устройств
systemctl --failed
journalctl -b
journalctl -b -1
systemd-analyze plot > boot.svg
boot.svg можно открыть в браузере и визуально посмотреть, какие сервисы когда стартовали и сколько длились.
systemd-analyze verify /etc/systemd/system/myapp.service
👀 inotifywait: реакция на изменения файлов без cron
Иногда нужно выполнить действие сразу после изменения файла или каталога. Например:
• изменился конфиг - перезапустить сервис
• появился новый файл - обработать его
• загрузили архив - распаковать
• изменился сертификат - перечитать nginx
• в каталог упал лог - отправить уведомление
Первое решение, которое часто приходит в голову - cron. Но cron работает по расписанию. Он не реагирует на событие сразу, а просто периодически проверяет состояние. Для событий в файловой системе удобнее использовать inotifywait.
▪️ Установка:
apt install inotify-tools
inotifywait -m /etc/nginx/nginx.conf
-m включает постоянное наблюдение.
/etc/nginx/nginx.conf MODIFY
inotifywait -m /var/www
inotifywait -m -r /var/www
inotifywait -m -e create,modify,delete /var/www
while inotifywait -e modify /etc/nginx/nginx.conf; do
nginx -t && systemctl reload nginx
done
inotifywait -m -e close_write --format '%w%f' /data/incoming |
while read -r file; do
echo "new file: $file"
/opt/scripts/process-file.sh "$file"
done
sysctl fs.inotify.max_user_watches
sysctl fs.inotify.max_user_instances
📂 sshfs: монтируем удаленный каталог через SSH и systemd
sshfs позволяет монтировать удаленную файловую систему через обычное SSH-соединение. То есть если у вас есть SSH-доступ к серверу, можно подключить его каталог как локальную директорию. Это не самый быстрый способ: SSHFS работает через FUSE в user space, плюс само SSH-соединение добавляет накладные расходы. Но для некоторых задач это очень удобно. Особенно когда: SSH уже открыт; NFS/SMB поднимать не хочется; нужен быстрый доступ к отдельному каталогу или нужно временно подключить данные
▪️ Установка:
apt install sshfs
ssh-keygen -t ed25519
ssh-copy-id root@10.20.1.6
root@10.20.1.6:/etc/letsencrypt
/mnt/letsencrypt
mkdir -p /mnt/letsencrypt
sshfs root@10.20.1.6:/etc/letsencrypt /mnt/letsencrypt
df -h | grep 10.20.1.6
fusermount -u /mnt/letsencrypt
systemctl edit --force --full sshfs-letsencrypt.service
[Unit]
Description=Mount /etc/letsencrypt over SSHFS
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/sshfs root@10.20.1.6:/etc/letsencrypt /mnt/letsencrypt -o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3
ExecStop=/usr/bin/fusermount -u /mnt/letsencrypt
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start sshfs-letsencrypt.service
systemctl enable sshfs-letsencrypt.service
systemctl stop sshfs-letsencrypt.service
reconnect - Пытаться восстановить подключение при обрыве.ServerAliveInterval=15 - Периодически проверять, живо ли SSH-соединение.ServerAliveCountMax=3 - После нескольких неудачных проверок считать соединение мертвым.
User=sftp-user
Group=sftp-user