4722
Авторский блог про сетевое и системное администрирование. Сайт: networkadmin.ru Реклама: @dad_admin Биржа: https://telega.in/c/networkadminru
📎 TCP retransmits: как понять, что сеть теряет пакеты, а не тормозит приложение
Иногда приложение вроде бы работает, CPU нормальный, память есть, база живая, но пользователи жалуются: "все медленно". И начинается классика: смотрим логи приложения, nginx, базу, systemd, load average. А причина может быть ниже - на сетевом уровне. Один из важных признаков сетевых проблем - TCP retransmits.
TCP - надежный протокол. Если пакет потерялся по дороге, получатель его не подтвердил, и отправитель через время отправит этот сегмент заново. Это и есть retransmission. Небольшое количество повторных передач в сети бывает всегда. Но если их много - это уже симптом:
• перегруженный канал;
• проблемы на интерфейсе;
• плохой Wi-Fi или VPN;
• перегруженный firewall/NAT;
• проблемы у провайдера.
Снаружи это часто выглядит не как "сеть упала", а как странная деградация: страницы открываются медленно, API иногда отвечает долго, SSH подвисает, загрузка файлов идет рывками и т.д.
Первое, что можно посмотреть на linux:
netstat -s | grep -i retrans
ss -ti
ss -ti можно увидеть детали по TCP-соединениям, включая retrans, rtt, cwnd и другие параметры.tcpdump. Например, смотрим трафик между сервером и клиентом:
tcpdump -i any -nn host 203.0.113.10 and port 443
tcpdump -i any -nn host 203.0.113.10 and port 443 -w retrans.pcap
tcp.analysis.retransmission
tcp.analysis.fast_retransmission
tcp.analysis.lost_segment
tcp.analysis.duplicate_ack
mtr -rw -c 100 203.0.113.10
ip -s link
ethtool -S eth0
🆘 BgInfo: системная информация прямо на рабочем столе Windows
У Microsoft Sysinternals есть старая, но до сих пор полезная утилита - BgInfo. Она выводит системную информацию прямо поверх обоев рабочего стола. На фоне можно показать:
• имя компьютера
• домен
• пользователя
• IP-адреса
• версию Windows
• uptime
• свободное место на дисках
• AD site
• любые дополнительные поля
Для HelpDesk это удобно: пользователь просто смотрит на рабочий стол и диктует нужные данные. Для админа тоже полезно, особенно когда открыто много RDP-сессий на разные серверы. Сразу видно, где именно ты находишься, и меньше шансов перепутать тестовый сервер с боевым.
BgInfo достаточно гибкий. Кроме стандартных полей, можно добавлять данные через:
• WMI
• registry
• environment variables
• VBS
• PowerShell-скрипты
▪️ Базовая схема внедрения простая.
1️⃣ Создаем шаблон BgInfo. В GUI настраиваем: какие поля показывать, шрифт и цвет, расположение блока, формат вывода, фон и поведение. После этого сохраняем конфигурацию в файл, например: bg_config.bgi
2️⃣ Кладем файлы в SYSVOL / NETLOGON. Например:
\\domain.local\NETLOGON\Bginfo\
Bginfo.exe
bg_config.bgi
reg add HKEY_CURRENT_USER\Software\Sysinternals\BGInfo /v EulaAccepted /t REG_DWORD /d 1 /f
%logonserver%\NETLOGON\Bginfo\Bginfo.exe %logonserver%\NETLOGON\Bginfo\bg_config.bgi /silent /timer:00 /nolicprompt
SERVER: SRV-APP-01
ENV: PROD
IP: 10.10.20.15
Надо наказывать, получается
#юмор
🧑💻 NetworkAdmin
👌 tcpdump: как быстро проверить, доходят ли пакеты до сервера
Когда сервис не открывается, то первое желание часто такое: сразу лезть в конфиги приложения, firewall, nginx, systemd и логи. Но иногда полезнее начать с более простого вопроса: а пакеты вообще доходят до сервера? Для этого есть старый добрый tcpdump. Он позволяет посмотреть сетевой трафик прямо на интерфейсе и быстро понять, видит ли сервер входящие пакеты. Например, пользователь говорит: "Не открывается сайт на 443 порту".
▪️ На сервере запускаем:
tcpdump -i any port 443
tcpdump -i any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
tcpdump -i any host 203.0.113.10 and port 443
tcpdump -i any port 22
tcpdump -i any port 80
tcpdump -i any port 53
tcpdump -i any udp port 1194
-n -Не резолвить имена. Вывод будет быстрее и чище.-nn - Не резолвить ни имена, ни порты. Вместо https будет 443.-v - Более подробный вывод.-c 20 - Поймать 20 пакетов и завершиться.
tcpdump -i any -nn -c 20 host 203.0.113.10 and port 443
203.0.113.10.53044 > 10.0.0.5.443: Flags [S]
10.0.0.5.443 > 203.0.113.10.53044: Flags [S.]
ss -lntp | grep ':443'
iptables -S
nft list ruleset
ip a
tcpdump -i eth0 -nn port 443
any удобен для быстрой диагностики, но конкретный интерфейс помогает понять, через какую сетевую карту реально идет трафик.
tcpdump -i any -nn host 203.0.113.10 -w capture.pcap
👁 Conntrack в Linux: как stateful firewall может стать узким местом
Когда на linux работает NAT или stateful firewall, почти всегда где-то рядом есть conntrack. Conntrack - это механизм ядра, который отслеживает сетевые соединения. Он нужен, чтобы firewall понимал не только отдельный пакет, но и его состояние:
• это новое соединение;
• это ответ на уже разрешенное соединение;
• это часть существующей сессии;
• это странный или неожиданный пакет.
Именно поэтому в iptables/nftables часто встречается логика:
-m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ct state established,related accept
sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count
nf_conntrack_count регулярно подходит к nf_conntrack_max, система близка к проблемам.
dmesg | grep -i conntrack
nf_conntrack: table full, dropping packet. Это уже прямой сигнал: таблица заполнена, новые пакеты начинают отбрасываться.
conntrack -L
conntrack -S
sysctl -w net.netfilter.nf_conntrack_max=262144
echo "net.netfilter.nf_conntrack_max=262144" > /etc/sysctl.d/99-conntrack.conf
sysctl --system
sysctl net.netfilter.nf_conntrack_tcp_timeout_established
sysctl net.netfilter.nf_conntrack_udp_timeout
sysctl net.netfilter.nf_conntrack_udp_timeout_stream
📎 rsync: полезные ключи для бэкапов и аккуратной синхронизацииrsync - одна из тех утилит, которые годами живут в админских скриптах и не теряют актуальности. Ее любят за простую идею: сравнить источник и приемник, а потом скопировать только то, что реально изменилось. Особенно хорошо rsync показывает себя на каталогах с большим количеством файлов. Если нужно синхронизировать два хранилища с сотнями тысяч или миллионами объектов, обычное копирование быстро превращается в боль. У rsync есть минусы. Главный - он не становится магически многопоточным. Но для задач, где нужно копировать файлы как есть, без упаковки, дедупликации и сложных backup-форматов, это все еще очень удобный инструмент. Ниже несколько ключей, которые полезно помнить.
▪️ --backup и --backup-dir. Обычно при синхронизации мы хотим привести приемник к состоянию источника. Например:
rsync -av --delete source/ dest/
--backup
--backup-dir=/path/to/old-files
rsync -av --delete --backup \
--backup-dir="/mnt/data/backup/bases_increment/$(date +%F)/" \
back_user@10.20.5.22:/var/lib/pgpro/backup/ \
/mnt/data/backup/bases/ \
>> "/var/log/rsync/1Csrv-$(date +%F).log"
rsync -av --progress source/ dest/
--progress может сильно засорить вывод. В таких случаях лучше использовать более спокойный режим:
rsync -av --info=progress2 source/ dest/
/var/www, а мы хотим вернуть недостающее из бэкапа:
rsync -av --ignore-existing \
back_user@10.30.7.5:/mnt/backup/www/ \
/var/www/
rsync -av --update \
back_user@10.30.7.5:/mnt/backup/www/ \
/var/www/
rsync -av --delete --dry-run source/ dest/
rsync -avn --delete source/ dest/
--dry-run показывает, что rsync сделал бы, но ничего реально не меняет. Это спасает от классической ошибки: перепутали источник и приемник - и удалили не там. Перед первой настройкой бэкапа или синхронизации лучше всегда запускать тестовый прогон.
rsync -av /data/source/ /backup/source/
rsync -av /data/source /backup/
/backup. На первый взгляд мелочь, но из-за этого часто получают не ту структуру директорий.
▶️ systemd socket activation: запуск сервиса только при реальном запросе
Обычно сервис в linux запускается заранее и постоянно висит в памяти:
systemctl start myapp
systemctl list-sockets
systemctl status myapp.socket
/etc/systemd/system/myapp.socket:
[Unit]
Description=MyApp socket
[Socket]
ListenStream=8080
[Install]
WantedBy=sockets.target
И сервис /etc/systemd/system/myapp.service:
[Unit]
Description=MyApp service
[Service]
ExecStart=/usr/local/bin/myapp
systemctl daemon-reload
systemctl enable --now myapp.socket
ss -lntp | grep 8080
systemctl status myapp.service
[Socket]
ListenStream=/run/myapp.sock
⚙️ MBR2GPT: как перевести Windows с Legacy BIOS на UEFI без переустановки
Иногда windows на современном железе оказывается установленной в режиме Legacy BIOS / CSM. Работает и ладно. Но есть нюанс: для нормальной UEFI-загрузки нужен диск с таблицей разделов GPT, а не старый MBR. Почему вообще стоит переходить на UEFI + GPT:
• поддержка дисков больше 2 ТБ;
• больше 4 основных разделов без костылей;
• современный механизм загрузки;
• поддержка Secure Boot;
• меньше зависимости от режима совместимости CSM.
Secure Boot особенно важен: он помогает защититься от подмены загрузчика и запуска вредоносного кода до старта ОС. Если Windows уже установлена в legacy-режиме, не всегда нужно переустанавливать систему. Начиная с Windows 10 1703, есть встроенная утилита:
mbr2gpt
$env:firmware_type
Get-Disk | Get-Partition
mbr2gpt /validate /allowFullOS
mbr2gpt /convert /allowFullOS
$env:firmware_type
🔖 DNS TTL: почему запись поменяли, а пользователи всё еще идут на старый IP
Классическая ситуация при миграции сервиса: DNS-запись уже поменяли. На авторитативном DNS новый IP виден. А часть пользователей все равно попадает на старый сервер.
Первое желание - это сказать: "DNS не обновился." Но чаще всего DNS как раз работает правильно. Просто сработал TTL. TTL - это Time To Live, время жизни DNS-записи в кэше. Когда резолвер получил ответ, он имеет право хранить его указанное количество секунд и не спрашивать авторитативный DNS заново. Например:
app.networkadmin.ru. 3600 IN A 203.0.113.10
dig app.networkadmin.ru
dig @8.8.8.8 app.networkadmin.ru
dig @1.1.1.1 app.networkadmin.ru
dig NS networkadmin.ru
dig @ns1.networkadmin.ru app.networkadmin.ru
app.networkadmin.ru. 1842 IN A 203.0.113.10
С ДНЕМ СИСАДМИНА! 👍
По традиции в этот великий день мы смотрим классику 🎬
😎 localhost › IT-юмор
👍 Sysinternals без скачивания: подключаем как сетевой диск
Короткая, но полезная штука для админов Windows. У Sysinternals есть live-каталог, который можно подключить как сетевой диск и запускать утилиты напрямую, без ручного скачивания архива. Команда простая:
net use S: http://live.sysinternals.com/tools
S:
procexp64.exe
procexp64.exe
tcpview.exe
Autoruns.exe
PsExec.exe
handle.exe
net use S: /delete
😑 tmpfs: где ускоряет систему, а где создает проблемы
tmpfs - это файловая система, которая хранит данные в оперативной памяти. Проще говоря, вы монтируете каталог как обычную файловую систему, но файлы физически лежат не на диске, а в RAM. При необходимости часть данных может быть вытеснена в swap, если он включен.
▪️ Посмотреть текущие tmpfs:
df -h -t tmpfs
/run
/dev/shm
/tmp
mkdir -p /mnt/ramtmp
mount -t tmpfs -o size=2G tmpfs /mnt/ramtmp
/mnt/ramtmp будет tmpfs с лимитом 2 ГБ./etc/fstab:
tmpfs /mnt/ramtmp tmpfs defaults,size=2G,noatime 0 0
df -h /mnt/ramtmp
free -h
/tmp на серверах с непредсказуемыми задачами;
[Service]
PrivateTmp=true
/tmp и /var/tmp, чтобы он не мешал другим процессам. А если нужен runtime-каталог:
[Service]
RuntimeDirectory=myapp
/run, который обычно тоже находится на tmpfs.
Этот мир уже не будет прежним
#юмор
🧑💻 NetworkAdmin
💚 AppArmor vs SELinux: что проще внедрять в обычной инфраструктуре
Когда говорят про безопасность в linux, часто вспоминают SELinux и AppArmor. Оба инструмента решают похожую задачу: ограничивают, что процесс может делать в системе, даже если у него уже есть обычные Unix-права.
То есть если приложение скомпрометировали, оно не должно автоматически получить возможность читать все подряд, писать куда угодно и трогать чужие файлы. Это дополнительный слой защиты поверх пользователей, групп и прав доступа. Но подход у них разный.
▪️ SELinux работает через labels и security contexts. У файлов, процессов, портов и других объектов есть контексты, а политики описывают, кому с чем можно взаимодействовать.
Проверить статус:
sestatus
ls -Z
ps auxZ
ausearch -m avc -ts recent
audit2why
audit2allow
aa-status
aa-complain /etc/apparmor.d/usr.sbin.nginx
aa-enforce /etc/apparmor.d/usr.sbin.nginx
setenforce 0
setenforce 0
aa-complain /etc/apparmor.d/profile-name
📱 getopts в bash: как нормально разбирать аргументы скрипта
Многие Bash-скрипты сначала выглядят просто: ./backup.sh /data /backup
А потом появляются опции: путь к конфигу, имя окружения, количество попыток, режим работы и т.д. И скрипт быстро превращается в набор странных if, где $1, $2, $3 уже никто нормально не понимает.
🤩 Плохой вариант:
SOURCE="$1"
DEST="$2"
MODE="$3"
#!/usr/bin/env bash
set -euo pipefail
VERBOSE=0
DRY_RUN=0
CONFIG=""
usage() {
echo "Usage: $0 [-v] [-n] [-c config] source dest"
}
while getopts ":vnc:" opt; do
case "$opt" in
v)
VERBOSE=1
;;
n)
DRY_RUN=1
;;
c)
CONFIG="$OPTARG"
;;
🙂
echo "option -$OPTARG requires an argument" >&2
usage
exit 1
;;
\?)
echo "unknown option: -$OPTARG" >&2
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
SOURCE="${1:-}"
DEST="${2:-}"
if [[ -z "$SOURCE" || -z "$DEST" ]]; then
usage
exit 1
fi
echo "source: $SOURCE"
echo "dest: $DEST"
echo "config: $CONFIG"
echo "verbose: $VERBOSE"
echo "dry-run: $DRY_RUN"
./backup.sh -v -n -c /etc/backup.conf /data /backup
./backup.sh -c /etc/backup.conf -v /data /backup
while getopts ":vnc:" opt; dov - флаг без значенияn - флаг без значенияc: - опция -c требует аргумент: включает более удобную обработку ошибок-v и -n просто включают режимы, а -c ожидает значение:
-c /etc/backup.conf
-c /etc/backup.conf
CONFIG="$OPTARG"
shift $((OPTIND - 1))
$1, $2 остаются обычные позиционные аргументы: например source и dest.
❤️ systemctl edit: как правильно переопределять юниты без правки vendor-файлов
В systemd часто нужно чуть-чуть изменить стандартный unit, который приехал из пакета. Например:
• добавить автоматический рестарт;
• изменить переменные окружения;
• переопределить ExecStart;
• добавить лимиты;
• поменять рабочий каталог;
• настроить зависимости.
Плохая идея - править vendor-unit напрямую где-нибудь в:
/lib/systemd/system/
/usr/lib/systemd/system/
systemctl cat nginx.service
systemctl edit nginx.service
[Service]
Restart=always
RestartSec=5s
/etc/systemd/system/nginx.service.d/override.conf
systemctl cat nginx.service
systemctl daemon-reload
systemctl restart nginx.service
systemctl status nginx.service
[Service]
Restart=always
RestartSec=5s
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
[Service]
ExecStart=
ExecStart=/usr/sbin/nginx -g 'daemon off; master_process off;'
ExecStart=
ExecStartPre=
ExecStartPost=
ExecReload=
ExecStop=
systemctl cat nginx.service
systemd-analyze verify /etc/systemd/system/nginx.service.d/override.conf
systemctl revert nginx.service
🔐 Windows LAPS: как перестать хранить один локальный admin-пароль на всех машинах
Одна из классических проблем в windows-инфраструктуре: на всех рабочих станциях один и тот же пароль локального администратора. Выглядит удобно. Админу легко подключиться к любой машине. Пароль можно держать для экстренных случаев. Техподдержка знает, что делать, если доменная авторизация не работает. Но с точки зрения безопасности это очень плохая идея. Если пароль локального администратора утек с одной машины, атакующий фактически получает доступ ко всем хостам, где этот пароль такой же. Именно для решения этой проблемы существует Windows LAPS.
Идея простая: у каждой машины должен быть свой уникальный пароль локального администратора, который регулярно меняется автоматически. Не один общий пароль на весь офис. Не excel-файл с паролями. А отдельный пароль для каждого компьютера.
▪️ Как это работает:
• на компьютере есть локальная admin-учетка;
• LAPS генерирует для нее уникальный пароль;
• пароль сохраняется в Active Directory или Entra ID;
• доступ к паролю получают только разрешенные админы;
• пароль автоматически меняется по политике;
• после использования пароль можно сбросить повторно.
Раньше часто использовали microsoft LAPS как отдельный компонент. Сейчас есть windows LAPS, встроенный в современные версии windows. Он поддерживает хранение паролей в active directory и microsoft entra ID.
▪️ Базовый сценарий для доменной инфраструктуры:
• Включаем поддержку Windows LAPS.
• Настраиваем права в Active Directory.
• Создаем Group Policy.
• Указываем, какую локальную учетку админа обслуживать.
• Задаем параметры пароля и срок жизни.
• Проверяем, что пароль появился у объекта компьютера.
▪️ Пример PowerShell-команд для проверки:
Get-LapsADPassword -Identity "PC-001" -AsPlainText
Get-LapsDiagnostics
Reset-LapsPassword
💿 Storage Spaces: когда можно использовать вместо аппаратного RAID
В windows server есть встроенный механизм объединения дисков - Storage Spaces. По сути, это программное хранилище, которое позволяет собрать несколько физических дисков в пул, а поверх него создать виртуальный диск с нужным типом отказоустойчивости. То есть вместо классического аппаратного RAID-контроллера можно использовать возможности самой windows.
Базовая схема: Physical disks -> Storage Pool -> Virtual Disk -> Volume
В пул добавляются физические диски, а дальше из этого пула создается виртуальный диск.
▪️ Основные варианты отказоустойчивости:
• Simple. Без отказоустойчивости. Аналог striping. Быстро, но при потере диска теряются данные.
• Mirror. Зеркалирование данных. Похоже на RAID1 или RAID10.
• Parity. Данные + контроль четности. Похоже на RAID5/RAID6 по идее, но не всегда по производительности.
▪️ Где Storage Spaces может быть полезен:
• файловый сервер;
• backup-хранилище;
• сервер с большим количеством локальных дисков;
• недорогая замена аппаратному RAID для не самых критичных задач;
• сценарии, где нужна гибкость, а не максимальная производительность.
▪️ Например, можно собрать несколько HDD в пул и создать mirror-том для файлового хранилища. Посмотреть диски, доступные для пула:
Get-PhysicalDisk
New-StoragePool `
-FriendlyName "DataPool" `
-StorageSubsystemFriendlyName "Windows Storage*" `
-PhysicalDisks (Get-PhysicalDisk -CanPool $true)
New-VirtualDisk `
-StoragePoolFriendlyName "DataPool" `
-FriendlyName "DataMirror" `
-ResiliencySettingName Mirror `
-UseMaximumSize
Get-VirtualDisk -FriendlyName "DataMirror" | Get-Disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter D |
Format-Volume -FileSystem NTFS -NewFileSystemLabel "Data"
Get-StoragePool
Get-VirtualDisk
Get-PhysicalDisk
📺 Скриншот рабочего стола пользователя через PowerShell и PsExec
Иногда техподдержке нужно быстро понять, что происходит на рабочем месте пользователя. Например:
• пользователь не может нормально описать ошибку;
• окно с сообщением быстро исчезает;
• приложение зависло в нестандартном состоянии;
• нужно увидеть текущий экран без полноценного подключения по RDP/AnyDesk;
• удаленный просмотр экрана в компании не используется или ограничен.
В таких случаях можно сделать простой механизм: по заявке и с согласия пользователя получить скриншот его текущего рабочего стола и сохранить PNG-файл в сетевую папку. Один из вариантов - PowerShell-скрипт, который делает снимок экрана в интерактивной сессии пользователя, и удаленный запуск через PsExec. Пример запуска:
.\PsExec.exe -s -i 1 \\pk-ww01 powershell.exe `
-ExecutionPolicy Bypass `
-WindowStyle Hidden `
-File "\\fs01\scripts\PS-Capture-Local-Screen.ps1"
\\pk-ww01 - удаленная рабочая станция-s - запуск от имени Local System-i 1 - запуск в интерактивной сессии пользователяpowershell.exe - выполнение PowerShell-скрипта\\fs01\scripts\... - путь к скрипту на файловом сервере\\fs01\support\screenshots\. И дальше сотрудник техподдержки может открыть PNG-файл и посмотреть, что было на экране в момент обращения.
🌀 Retry-логика в bash: как аккуратно повторять нестабильные операции
В админских скриптах не все ошибки означают, что все окончательно сломалось. Иногда команда падает из-за временной проблемы:
• сеть моргнула;
• API вернул timeout;
• DNS не ответил с первого раза;
• файл еще не появился;
• сервис еще не успел подняться;
• удаленный хост временно недоступен.
В таких случаях полезна retry-логика - аккуратный повтор операции несколько раз перед тем, как считать задачу проваленной.
🤩 Плохой вариант:
curl -fsS https://api.networkadmin.ru/deploy
for i in {1..5}; do
if curl -fsS https://api.networkadmin.ru/deploy; then
echo "success"
break
fi
echo "attempt $i failed, retrying..."
sleep 5
done
retry() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
((attempt++))
done
}
retry 5 3 curl -fsS https://api.networkadmin.ru/health
retry 10 2 nc -z 127.0.0.1 5432
retry_backoff() {
local max_attempts="$1"
local delay="$2"
shift 2
local attempt=1
until "$@"; do
if (( attempt >= max_attempts )); then
echo "command failed after $attempt attempts: $*" >&2
return 1
fi
echo "attempt $attempt failed, retrying in ${delay}s..." >&2
sleep "$delay"
delay=$((delay * 2))
((attempt++))
done
}
retry_backoff 5 2 curl -fsS https://api.networkadmin.ru/status
За пачку вискаса все настрою 😮
#юмор
🧑💻 NetworkAdmin
🔥 Короткий вывод IP-адресов без простыни
В linux давно уже привычнее смотреть сетевые настройки через ip, а не через старый ifconfig. Обычно для просмотра адресов используют:
ip a
ip -br a
-br означает brief, то есть краткий вывод.
ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 172.18.107.235/20 fe80::215:5dff:fe0d:7101/64
eth1 UP 192.168.101.2/24 fe80::215:5dff:fe0d:7105/64
docker0 DOWN 172.17.0.1/16
ip -br -4 a
lo UNKNOWN 127.0.0.1/8
eth0 UP 172.18.107.235/20
eth1 UP 192.168.101.2/24
docker0 DOWN 172.17.0.1/16
ip -br -6 a
ip -br link
ip -br l
ip -br neigh
ip -br n
ip r
ip route get 8.8.8.8
ip -br a
ip -br -4 a
ip -br -6 a
ip -br l
ip -br n
ip r
ip route get 8.8.8.8
💚 Linux capabilities: как дать процессу нужные права без полного root
Одна из старых проблем linux- приложение либо работает от обычного пользователя, либо получает полный root. Но на практике многим сервисам нужен всего один привилегированный доступ. Например:
• открыть порт ниже 1024;
• работать с raw-сокетами;
• менять сетевые настройки;
• выполнять отдельные системные операции.
Давать ради этого полный root - не лучшая идея. Для таких случаев в Linux существуют capabilities. Они разбивают привилегии суперпользователя на отдельные возможности, которые можно выдавать выборочно. К примеру, веб-серверу нужен только доступ к 80 порту. Без root обычный пользователь не сможет открыть этот порт:
python3 -m http.server 80
setcap cap_net_bind_service=+ep /usr/bin/python3
getcap /usr/bin/python3
/usr/bin/python3 cap_net_bind_service=ep
CAP_NET_BIND_SERVICE - порты ниже 1024CAP_NET_RAW - raw sockets, ping и подобные инструментыCAP_SYS_TIME - изменение системного времениCAP_NET_ADMIN - управление сетьюCAP_SYS_ADMIN - очень широкие административные возможности (почти mini-root)
cat /proc/<PID>/status | grep Cap
capsh --print
setcap -r /usr/bin/python3
[Service]
User=nginx
AmbientCapabilities=CAP_NET_BIND_SERVICE
CAP_SYS_ADMIN настолько мощная, что ее часто называют новым root. Поэтому принцип тот же, что и с правами пользователей: выдаем минимум необходимого.CAP_NET_BIND_SERVICE. Не нужно на всякий случай раздавать весь набор возможностей.
С днём системного администратора! 🏆
Пусть серверы не падают, бэкапы восстанавливаются, мониторинг молчит, а пользователи хотя бы иногда пробуют перезагрузить компьютер до обращения в поддержку.
Желаю стабильного аптайма, спокойных дежурств, крепких нервов и достойной зарплаты. За localhost! 🍻🍷
🧑💻 NetworkAdmin
❓ SSHFS-Win: подключаем Linux-каталог как диск в Windows
В Windows можно подключать каталоги с удаленного linux/unix-сервера как обычный сетевой диск. Не через SMB, не через FTP и не через WebDAV, а по защищенному SSH-соединению. Для этого есть SSHFS-Win - порт SSHFS-клиента для Windows. Он позволяет монтировать удаленную файловую систему по SSH так, будто это обычный диск в Проводнике.
После установки SSHFS-Win каталог можно подключить прямо из Проводника Windows. Например, UNC-путь:
\\sshfs.r\administrator@192.168.158.100\remote_folder
sshfs.r - тип подключенияadministrator - пользователь на удаленном сервере192.168.158.100 - адрес сервераremote_folder - удаленный каталог
net use M: \\sshfs.r\administrator@192.168.158.100\ps /user:administrator
\\sshfs.k\administrator@192.168.158.100\remote_folder
sshfs.k говорит SSHFS-Win использовать ключевую аутентификацию. Это удобнее и безопаснее, чем постоянно вводить пароль, особенно если доступ нужен регулярно.
net use M: \\sshfs.k\administrator@192.168.158.100\remote_folder
net use M: /delete
/var/log или /etc;
🌟 psmisc toolkit: fuser, pstree, killall в реальной админке
psmisc - небольшой набор утилит, которые часто оказываются полезнее, чем кажутся на первый взгляд. Обычно пакет ставят ради трех команд: fuser, pstree, killall
▪️ Установка:
apt install psmisc
# или:
yum install psmisc
umount /mnt/backup
target is busy
fuser -vm /mnt/backup
fuser -k /mnt/backup
-k лучше не спешить. Сначала посмотреть, потом убивать.
fuser -v 8080/tcp
fuser -v 53/udp
ps aux часто превращается в простыню. pstree показывает процессы в виде дерева: кто кого запустил и где родительский процесс.
pstree
pstree -p
pstree -u username
pstree -p 1234
Это очень удобно, когда нужно понять:
• какой процесс породил дочерние
• кто держит worker’ы
• почему после остановки сервиса остались потомки
• откуда запущен странный процесс
• что происходит внутри shell-сессии или скрипта
sshd───bash───deploy.sh───rsync
killall nginx
killall -TERM nginx
killall -KILL nginx
pgrep -a nginx
killall работает по имени процесса. Если на сервере есть несколько процессов с одинаковым именем, можно задеть лишнее.
fuser -vm /mnt/backup
pstree -p
pgrep -a process_name
killall -TERM process_name
⚙️ Windows предпочитает IPv6: почему старые сервисы могут ломаться
Если для удаленного хоста доступны и IPv4, и IPv6, Windows по умолчанию может выбрать IPv6. То есть если DNS или mDNS в локальной сети вернул сразу две записи:
A -> IPv4-адрес
AAAA -> IPv6-адрес
Симптомы могут выглядеть так:
по IP 192.168.x.x все открывается
по имени хоста - ошибка
соседний компьютер виден, но сервис не отвечает
приложение пишет timeout
в логах видно попытку подключения к IPv6
netsh interface ipv6 show prefixpolicies
netsh interface ipv6 set prefix ::ffff:0:0/96 55 4
netsh interface ipv6 set prefix ::/96 60 3
netsh interface ipv6 show prefixpolicies
nslookup hostname
Test-NetConnection hostname -Port 445
📱 Nginx map: отдельные логи для 404 и 5xx без костылей
Иногда нужно не просто писать общий access log, а отдельно сохранять конкретные типы запросов. Например: все 404, все 5xx, запросы от конкретных ботов, отдельные URI, нестандартные методы, трафик из определенных стран. Можно потом парсить общий лог через grep, awk или SIEM. Но в Nginx часто есть более аккуратный способ - использовать map.
map позволяет создать переменную на основе другой переменной Nginx. А потом использовать эту переменную в логах, блокировках, редиректах и другой логике.
▪️ Пример: пишем 404 и 5xx в отдельные файлы. В секции http добавляем:
map $status $to404log {
404 1;
default 0;
}
map $status $to5xxlog {
~^5 1;
default 0;
}
access_log /var/log/nginx/404.log combined if=$to404log;
access_log /var/log/nginx/5xx.log combined if=$to5xxlog;
access_log /var/log/nginx/access.log combined;
map $http_user_agent $block_useragent {
default 0;
~*semrushbot 1;
~*ahrefs 1;
~*rss2tg 1;
~*seznambot 1;
~*AspiegelBot 1;
~*BLEXBot 1;
~*MASHIAH 1;
}
if ($block_useragent) {
return 403;
}
$request_method
$request_uri
$remote_addr
$host
$geoip_country_code
$http_referer
👾 Policy Based Routing: несколько шлюзов без хаоса
Обычная маршрутизация отвечает на вопрос: куда отправить пакет по адресу назначения? Но иногда этого мало. Например, на linux-сервере есть два провайдера, два интерфейса или несколько VPN. И нужно, чтобы часть трафика шла через один шлюз, а часть - через другой.
Вот здесь появляется Policy Based Routing. PBR позволяет маршрутизировать трафик не только по destination IP, но и по дополнительным условиям:
• source IP
• интерфейс
• fwmark
• отдельная таблица маршрутизации
• правила из ip rule
▪️ Классический пример:
eth0 -> 192.168.1.10/24 -> gateway 192.168.1.1
eth1 -> 10.10.10.10/24 -> gateway 10.10.10.1
echo "100 isp2" >> /etc/iproute2/rt_tables
ip route add 10.10.10.0/24 dev eth1 src 10.10.10.10 table isp2
ip route add default via 10.10.10.1 dev eth1 table isp2
ip rule add from 10.10.10.10/32 table isp2
ip rule show
ip route show table isp2
ip route get 8.8.8.8 from 10.10.10.10
iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 10
ip rule add fwmark 10 table isp2
ip route # маршруты
ip rule # правила