В windows server есть встроенный механизм объединения дисков - Storage Spaces. По сути, это программное хранилище, которое позволяет собрать несколько физических дисков в пул, а поверх него создать виртуальный диск с нужным типом отказоустойчивости. То есть вместо классического аппаратного RAID-контроллера можно использовать возможности самой windows.
Базовая схема: Physical disks -> Storage Pool -> Virtual Disk -> Volume
В пул добавляются физические диски, а дальше из этого пула создается виртуальный диск.
• Simple. Без отказоустойчивости. Аналог striping. Быстро, но при потере диска теряются данные.
• Mirror. Зеркалирование данных. Похоже на RAID1 или RAID10.
• Parity. Данные + контроль четности. Похоже на RAID5/RAID6 по идее, но не всегда по производительности.
• файловый сервер;
• backup-хранилище;
• сервер с большим количеством локальных дисков;
• недорогая замена аппаратному RAID для не самых критичных задач;
• сценарии, где нужна гибкость, а не максимальная производительность.
Get-PhysicalDisk
Создать storage pool:
New-StoragePool `
-FriendlyName "DataPool" `
-StorageSubsystemFriendlyName "Windows Storage*" `
-PhysicalDisks (Get-PhysicalDisk -CanPool $true)
Создать mirror virtual disk:
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"
• не нужен отдельный RAID-контроллер;
• проще переносить диски между совместимыми windows-системами;
• управление через PowerShell;
• можно гибко добавлять диски в пул;
• нет зависимости от конкретной модели RAID-контроллера;
• хорошо подходит для типовых windows-хранилищ.
Но есть нюансы. Storage Spaces - это не "бесплатный аппаратный RAID лучше во всем". У parity-сценариев может быть слабая производительность на записи, особенно на обычных HDD. Для баз данных, виртуализации и высоконагруженных задач нужно тщательно тестировать.
Проверять состояние можно так:
Get-StoragePool
Get-VirtualDisk
Get-PhysicalDisk
Если диск начал сыпаться, это нужно увидеть не тогда, когда уже умер второй.
#windowsserver #storagespaces
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🫡2❤1👌1
Когда сервис не открывается, то первое желание часто такое: сразу лезть в конфиги приложения, firewall, nginx, systemd и логи. Но иногда полезнее начать с более простого вопроса: а пакеты вообще доходят до сервера? Для этого есть старый добрый
tcpdump. Он позволяет посмотреть сетевой трафик прямо на интерфейсе и быстро понять, видит ли сервер входящие пакеты. Например, пользователь говорит: "Не открывается сайт на 443 порту".
tcpdump -i any port 443
И просим пользователя повторить подключение. Если в выводе появились пакеты - до сервера что-то доходит. Если тишина - проблема может быть раньше:
• firewall перед сервером;
• security group;
• маршрутизация;
• NAT;
• балансировщик;
• неправильный IP;
• провайдерская фильтрация;
• подключение вообще идет не туда.
tcpdump -i any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
SYN - это начало TCP-подключения. Если SYN приходит, значит клиент хотя бы пытается установить соединение с сервером. Можно сразу фильтровать по IP клиента:
tcpdump -i any host 203.0.113.10 and port 443
Так удобнее, если на сервере много трафика и общий вывод превращается в кашу.
Если нужно проверить SSH:
tcpdump -i any port 22
Если HTTP:
tcpdump -i any port 80
Если DNS:
tcpdump -i any port 53
Для UDP-сервисов тоже работает:
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.]
Если входящий SYN есть, но ответа нет - нужно смотреть локальный firewall, сервис, listen-порт или routing обратно. Проверяем, слушает ли порт:
ss -lntp | grep ':443'
Проверяем firewall:
iptables -S
nft list ruleset
Если SYN приходит и SYN-ACK уходит, но клиент все равно не подключается - возможно, проблема на обратном пути.
ip a
tcpdump -i eth0 -nn port 443
any удобен для быстрой диагностики, но конкретный интерфейс помогает понять, через какую сетевую карту реально идет трафик.
tcpdump -i any -nn host 203.0.113.10 -w capture.pcap
Это удобно, если проблему нужно передать сетевикам или разобрать позже.
#linux #tcpdump #network
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2🔥1
Одна из классических проблем в 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.
• Указываем, какую локальную учетку админа обслуживать.
• Задаем параметры пароля и срок жизни.
• Проверяем, что пароль появился у объекта компьютера.
Get-LapsADPassword -Identity "PC-001" -AsPlainText
Так можно получить пароль локального администратора для конкретной машины, если у учетной записи есть права.
Посмотреть параметры LAPS на клиенте:
Get-LapsDiagnostics
Принудительно обновить пароль:
Reset-LapsPassword
• имя локальной admin-учетки;
• длину пароля;
• сложность пароля;
• срок действия пароля;
• место хранения пароля;
• права на чтение пароля;
• действия после использования пароля.
Например, можно сделать так, чтобы пароль менялся каждые 30 дней. Или сбрасывался сразу после того, как админ его использовал.
Главная польза LAPS: компрометация одной машины не дает автоматический доступ ко всем остальным. Даже если пароль локального администратора слили с одного ПК, на другом компьютере он будет другим. Это резко снижает риск распространения атаки внутри сети.
#windows #security
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2
В systemd часто нужно чуть-чуть изменить стандартный unit, который приехал из пакета. Например:
• добавить автоматический рестарт;
• изменить переменные окружения;
• переопределить ExecStart;
• добавить лимиты;
• поменять рабочий каталог;
• настроить зависимости.
Плохая идея - править vendor-unit напрямую где-нибудь в:
/lib/systemd/system/
или:
/usr/lib/systemd/system/
После обновления пакета такие изменения могут потеряться или конфликтовать с новой версией юнита.Правильнее использовать override. Покажу на примере nginx.service.
systemctl cat nginx.service
Это очень удобная команда. Она показывает не только содержимое unit-файла, но и путь, откуда он загружен. Если для сервиса уже есть override-файлы, они тоже будут показаны в этом же выводе.
systemctl edit nginx.service
[Service]
Restart=always
RestartSec=5s
/etc/systemd/system/nginx.service.d/override.conf
systemctl cat nginx.service
Теперь в выводе будет видно и исходный unit, и наш override.
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, systemd может выдать ошибку или оставить некорректную конфигурацию. То же часто касается параметров семейства:
ExecStart=
ExecStartPre=
ExecStartPost=
ExecReload=
ExecStop=
systemctl cat nginx.service
И затем:
systemd-analyze verify /etc/systemd/system/nginx.service.d/override.conf
Еще полезная команда:
systemctl revert nginx.service
Она удалит локальные override и вернет unit к vendor-состоянию.
#linux #systemd
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
У Microsoft Sysinternals есть старая, но до сих пор полезная утилита - BgInfo. Она выводит системную информацию прямо поверх обоев рабочего стола. На фоне можно показать:
• имя компьютера
• домен
• пользователя
• IP-адреса
• версию Windows
• uptime
• свободное место на дисках
• AD site
• любые дополнительные поля
Для HelpDesk это удобно: пользователь просто смотрит на рабочий стол и диктует нужные данные. Для админа тоже полезно, особенно когда открыто много RDP-сессий на разные серверы. Сразу видно, где именно ты находишься, и меньше шансов перепутать тестовый сервер с боевым.
BgInfo достаточно гибкий. Кроме стандартных полей, можно добавлять данные через:
• WMI
• registry
• environment variables
• VBS
• PowerShell-скрипты
bg_config.bgi
\\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
• заранее принимаем EULA для пользователя
• запускаем BgInfo из NETLOGON
• применяем готовый .bgi шаблон
• скрываем окно запуска
• не показываем license prompt
• сразу обновляем фон без ожидания таймера
После входа пользователя на рабочий стол автоматически наносится нужная системная информация.
Отдельный плюс - возможность стандартизировать внешний вид. Например, на серверах можно крупно выводить:
SERVER: SRV-APP-01
ENV: PROD
IP: 10.10.20.15
А на рабочих станциях - имя ПК, пользователь, IP и версию ОС.
#windows #bginfo
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Многие Bash-скрипты сначала выглядят просто:
./backup.sh /data /backupА потом появляются опции: путь к конфигу, имя окружения, количество попыток, режим работы и т.д. И скрипт быстро превращается в набор странных if, где $1, $2, $3 уже никто нормально не понимает.
SOURCE="$1"
DEST="$2"
MODE="$3"
Работает, пока аргументов мало. Но как только нужно добавить флаги, порядок начинает ломать все. Для нормального разбора коротких опций в bash есть встроенный механизм getopts.
#!/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
Переменная OPTARG содержит аргумент текущей опции. Например, для:
-c /etc/backup.conf
внутри case будет:
CONFIG="$OPTARG"
После обработки флагов важна команда:
shift $((OPTIND - 1))
Она убирает уже разобранные опции из списка аргументов. После этого в
$1, $2 остаются обычные позиционные аргументы: например source и dest.#bash #scripting
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Иногда приложение вроде бы работает, CPU нормальный, память есть, база живая, но пользователи жалуются: "все медленно". И начинается классика: смотрим логи приложения, nginx, базу, systemd, load average. А причина может быть ниже - на сетевом уровне. Один из важных признаков сетевых проблем - TCP retransmits.
TCP - надежный протокол. Если пакет потерялся по дороге, получатель его не подтвердил, и отправитель через время отправит этот сегмент заново. Это и есть retransmission. Небольшое количество повторных передач в сети бывает всегда. Но если их много - это уже симптом:
• перегруженный канал;
• проблемы на интерфейсе;
• плохой Wi-Fi или VPN;
• перегруженный firewall/NAT;
• проблемы у провайдера.
Снаружи это часто выглядит не как "сеть упала", а как странная деградация: страницы открываются медленно, API иногда отвечает долго, SSH подвисает, загрузка файлов идет рывками и т.д.
Первое, что можно посмотреть на linux:
netstat -s | grep -i retrans
или через ss:
ss -ti
В выводе
ss -ti можно увидеть детали по TCP-соединениям, включая retrans, rtt, cwnd и другие параметры.Для конкретного направления лучше использовать
tcpdump. Например, смотрим трафик между сервером и клиентом:
tcpdump -i any -nn host 203.0.113.10 and port 443
Если нужно сохранить дамп для Wireshark:
tcpdump -i any -nn host 203.0.113.10 and port 443 -w retrans.pcap
В wireshark потом удобно фильтровать:
tcp.analysis.retransmission
Также полезные фильтры:
tcp.analysis.fast_retransmission
tcp.analysis.lost_segment
tcp.analysis.duplicate_ack
Если видите много retransmission, duplicate ACK и lost segment - это уже повод смотреть сеть, а не только приложение.
Быстрая проверка маршрута:
mtr -rw -c 100 203.0.113.10
Но тут важно помнить: mtr показывает потери по ICMP/UDP/TCP-проверкам, а не всегда идеально отражает конкретный TCP-трафик приложения. Зато помогает понять, где примерно начинаются проблемы.
Еще полезно проверить ошибки на сетевом интерфейсе:
ip -s link
или:
ethtool -S eth0
#linux #network
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2
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
Можно подключаться и по паролю, но для systemd-автомонтирования это неудобно: пароль придется вводить интерактивно. С ключом все проще и надежнее.
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-файла:
[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
Перечитываем systemd:
systemctl daemon-reload
Запускаем:
systemctl start sshfs-letsencrypt.service
Добавляем в автозагрузку:
systemctl enable sshfs-letsencrypt.service
Если нужно размонтировать каталог:
systemctl stop sshfs-letsencrypt.service
•
reconnect - Пытаться восстановить подключение при обрыве.•
ServerAliveInterval=15 - Периодически проверять, живо ли SSH-соединение.•
ServerAliveCountMax=3 - После нескольких неудачных проверок считать соединение мертвым.В примере все сделано от root для простоты. Для постоянной схемы лучше использовать отдельного пользователя с минимальными правами. В systemd можно указать:
User=sftp-user
Group=sftp-user
Но тогда важно, чтобы у этого пользователя были права на точку монтирования и SSH-ключи.
#linux #sshfs
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1
В Windows-скриптах часто делают логирование в обычные текстовые файлы:
C:\Scripts\Logs\script.log
Это рабочий вариант, но не всегда удобный. Логи могут лежать в разных папках, забываться при переносе скрипта, не попадать в централизованный сбор и быстро превращаться в зоопарк форматов. Иногда удобнее писать важные события прямо в Event Viewer.
• события видны в стандартном журнале Windows;
• их можно собирать через WEF, SIEM или агент мониторинга;
• проще фильтровать по источнику, Event ID и уровню;
• не нужно отдельно искать лог-файл скрипта;
• события попадают в привычный механизм аудита и диагностики.
New-EventLog -LogName Application -Source "MyScript"
После этого можно писать события в журнал Application:
Write-EventLog `
-LogName Application `
-Source "MyScript" `
-EntryType Information `
-EventID 1 `
-Message "Запущен PowerShell-скрипт опроса состояния сервера"
В Event Viewer появится событие с источником MyScript.
Тип события можно менять:
-EntryType Information
-EntryType Warning
-EntryType Error
Например, если скрипт завершился с ошибкой:
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"
Event Viewer удобен не вместо всех логов, а как место для важных событий, которые должны быть видны системе мониторинга и администратору. Если скрипт делает что-то важное, он должен не просто молча выполниться. Он должен оставить понятный след: когда стартовал, чем закончился и где сломался.
#windows #powershell #eventviewer
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Иногда нужно выполнить действие сразу после изменения файла или каталога. Например:
• изменился конфиг - перезапустить сервис
• появился новый файл - обработать его
• загрузили архив - распаковать
• изменился сертификат - перечитать 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
Смысл простой:
• ждем изменение файла
• проверяем конфиг
• если всё нормально - reload nginx
• снова ждем следующее изменение
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
Почему close_write, а не просто create? Потому что файл может появиться, но запись в него еще не закончилась. close_write срабатывает, когда файл уже записан и закрыт.
sysctl fs.inotify.max_user_watches
sysctl fs.inotify.max_user_instances
#linux #inotify
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Иногда на сервере возникает странная ситуация. Проверяем диск:
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:
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,'
#linux #filesystem #storage
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Иногда сервер после reboot поднимается подозрительно долго. Вроде железо нормальное, диск живой, сервисов не так много, но до нормального состояния система доходит через минуту, две или даже дольше.
В systemd для такого разбора есть удобная утилита:
systemd-analyze
Она покажет общее время загрузки:
Startup finished in 5.2s (kernel) + 28.4s (userspace) = 33.6s
Здесь видно, сколько заняло ядро и сколько - userspace, то есть запуск systemd-сервисов.
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
Эта команда показывает критический путь загрузки - что действительно задерживало достижение нужного target.
systemd-analyze critical-chain docker.service
ожидание сети
зависший mount из /etc/fstab
медленный DNS
NFS/SMB mount без `nofail`
долгий старт базы данных
Docker/container runtime
cloud-init
некорректные зависимости в юнитах
таймауты несуществующих устройств
systemctl --failed
journalctl -b
Если проблема была на предыдущем boot:
journalctl -b -1
systemd-analyze plot > boot.svg
Файл
boot.svg можно открыть в браузере и визуально посмотреть, какие сервисы когда стартовали и сколько длились.
systemd-analyze verify /etc/systemd/system/myapp.service
Это помогает поймать неправильные директивы, опечатки и странности в конфигурации.
#linux #systemd
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2
Падение сервиса обычно видно сразу. Мониторинг красный, пользователи жалуются, в логах ошибка. Перезапустили, откатили, восстановили. А вот один неверный
chmod -R может сломать прод намного тише и неприятнее. Классический сценарий:
chmod -R 777 /var/www
или еще хуже:
chmod -R 755 /
Хотели быстро пофиксить права, а получили хаос.
Права в linux - это не просто можно читать или нельзя.
От них зависит работа сервисов, безопасность, SSH, sudo, systemd, базы данных, веб-приложения и приватные ключи.
• 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
А не открывать все через 777.
777 - это почти всегда сигнал, что проблему не поняли, а просто выключили защиту.
Для диагностики полезно смотреть текущие права:
ls -la
namei -l /var/www/app/storage/file.log
stat /var/www/app/storage
namei -l особенно удобен: он показывает права на каждом уровне пути. Иногда файл доступен, но один из родительских каталогов не дает пройти дальше.
#linux #chmod
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4
Обычно синхронизация времени в Linux работает незаметно: установили
chrony, systemd-timesyncd или другой NTP-клиент - и забыли. Но после загрузки виртуальной машины системное время иногда отличается на несколько минут. Служба синхронизации исправит его, однако часть сервисов к этому моменту уже может успеть запуститься.В результате появляются:
• события в логах с неправильным временем
• ошибки проверки сертификатов
• проблемы с Kerberos и токенами
• некорректный порядок событий
• странности в распределенных системах и мониторинге
Для обычной работы постепенная коррекция времени подходит. Но на старте иногда нужно сначала выставить часы, а уже потом запускать приложение. Для этого можно создать одноразовый systemd-unit с
chronyd -q.
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
#linux #systemd #chrony
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Для логов 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 "Не удалось подключиться к серверу"
Полезно заранее определить свою схему Event ID:
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"
Подробный debug-вывод удобнее оставлять в обычном текстовом логе. Хорошая схема выглядит так: детали — в файл, важные события — в Event Viewer.
#windows #eventviewer
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤1
Обычные логи не всегда отвечают на главный вопрос: кто изменил конфигурацию и какой процесс это сделал? Для таких задач в 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
Ищем изменения, например, SSH-конфига:
ausearch -k ssh_config -i
Посмотреть события за сегодня:
ausearch -k sudoers -ts today -i
Краткий отчет по измененным файлам:
aureport -f -i
какой файл изменили
UID и реального пользователя
PID процесса
исполняемую команду
успешность операции
точное время
#linux #auditd
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🔥1
Bonding объединяет несколько сетевых интерфейсов в один логический
bond0. Обычно его используют для:• резервирования сетевого подключения
• распределения нагрузки
• защиты от отказа кабеля, порта или сетевой карты
• увеличения суммарной пропускной способности
Два самых популярных режима -
active-backup и 802.3ad.
[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=active-backup
MIIMonitorSec=100ms
Primary=eno1
Главный плюс - простота. Специальная настройка коммутатора обычно не требуется. Подходит, когда нужна прежде всего отказоустойчивость.
[Bond]
Mode=802.3ad
MIIMonitorSec=100ms
LACPTransmitRate=fast
TransmitHashPolicy=layer3+4
Но на коммутаторе порты должны быть объединены в один LAG с поддержкой LACP.
Важно понимать: одно TCP-соединение обычно не получит скорость двух интерфейсов. Трафик распределяется по хешу между разными потоками.
Проверить состояние bonding:
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, хотя трафик через порт не проходит
#linux #bonding #network
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6
Когда нужно понять, какой процесс кого запустил, обычного списка
ps часто недостаточно. Намного удобнее посмотреть процессы в виде дерева: родительский процесс -> дочерние процессы -> подпроцессы. Есть несколько простых способов.t. Это переключит список в режим Tree View. Так удобно быстро посмотреть структуру процессов прямо в интерактивном интерфейсе: например, какие worker-процессы запустил nginx, systemd или приложение.Но если процессов много и вывод нужно спокойно изучить, интерактивный интерфейс бывает не самым удобным.
ps axf
Ключ
f показывает процессы в виде ASCII-дерева. Если вывод большой, его можно сохранить в файл:
ps axf > ~/process-tree.txt
После этого список удобно открыть в редакторе, искать по нему и прикладывать к разбору инцидента.
Более информативный вариант:
ps -eo user,pid,ppid,stat,lstart,cmd --forest
Здесь дополнительно видны пользователь, PID, PPID, статус, время запуска и полная команда.
pstree входит в пакет psmisc, который часто уже установлен в системе.Установка:
apt install psmisc
Базовый запуск:
pstree
Показать PID:
pstree -p
Показать аргументы команд:
pstree -a
Вывести дерево для конкретного процесса:
pstree -p 1234
Или для пользователя:
pstree -p username
Полезные параметры:
-p- показывает PID-a- показывает аргументы командной строки-n- сортирует процессы по PID-u- показывает смену пользователя-s- показывает родителей указанного процесса-c- не объединяет одинаковые ветки
Например:
pstree -p -a -u
#linux #terminal #processes
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5