NetworkAdmin.ru
4.73K subscribers
240 photos
32 videos
2 files
605 links
Авторский блог про сетевое и системное администрирование.

Сайт: networkadmin.ru
Реклама: @dad_admin
Биржа: https://telega.in/c/networkadminru
Download Telegram
📘 На платформе Mentorix вышел курс — «DevOps-инженер: от основ до продакшена»

Если вы хотите не просто изучить инструменты, а понять, как собирается реальная DevOps-инфраструктура — этот курс даёт полный системный подход.

🔧 Что внутри:
• Linux, администрирование и bash
• Docker и Kubernetes (реальная оркестрация)
• Terraform и Ansible (Infrastructure as Code)
• CI/CD: GitLab CI, GitHub Actions, Jenkins
• мониторинг и логирование: Prometheus, Grafana, ELK
• безопасность, сети, балансировка нагрузки
• облака (AWS/GCP/Azure)

📊 Формат:
— 82 урока и 784 шага
— 320 теорий, 325 тестов, 139 задач практических задач
— практика в каждом блоке

💡 Важно:
вы не просто изучаете инструменты — вы собираете end-to-end инфраструктуру, которую можно положить в портфолио и показывать на собеседованиях.

💰 скидка 40%, действует 24 часа

👉 Пройти курс
2👍1
📱 Bash как DSL: пишем читаемые админские скрипты

Многие админские bash-скрипты со временем превращаются в свалку из if, grep, awk, sed и случайных команд, склеенных по принципу: работает - не трогай. Проблема в том, что через месяц такой скрипт уже тяжело читать. Через полгода - страшно менять. А если его откроет другой админ, он вообще решит, что это археология, а не автоматизация.

Один из рабочих подходов - писать bash не как набор команд, а как маленький DSL: domain-specific language, то есть мини-язык под свою задачу.

Идея простая: вместо простыни команд вы собираете скрипт из понятных функций с говорящими именами.

Например, не так:


useradd -m -s /bin/bash "$name"
mkdir -p "/home/$name/.ssh"
cp ./authorized_keys "/home/$name/.ssh/authorized_keys"
chown -R "$name:$name" "/home/$name/.ssh"
chmod 700 "/home/$name/.ssh"
chmod 600 "/home/$name/.ssh/authorized_keys"


А так:


create_user "$name"
install_ssh_keys "$name"
harden_ssh_dir "$name"


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

Например:


create_user() {
useradd -m -s /bin/bash "$1"
}

install_ssh_keys() {
local user="$1"
mkdir -p "/home/$user/.ssh"
cp ./authorized_keys "/home/$user/.ssh/authorized_keys"
chown -R "$user:$user" "/home/$user/.ssh"
}

harden_ssh_dir() {
local user="$1"
chmod 700 "/home/$user/.ssh"
chmod 600 "/home/$user/.ssh/authorized_keys"
}


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


create_user "$name"
install_ssh_keys "$name"
harden_ssh_dir "$name"


👍 Что это дает на практике:

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

Еще один полезный прием - делать функции в стиле команд:


require_root
check_dependencies
backup_config "/etc/nginx/nginx.conf"
deploy_new_config "./nginx.conf" "/etc/nginx/nginx.conf"
test_nginx_config
reload_nginx


Такой bash уже напоминает не набор shell-команд, а язык операций для конкретной задачи.

Пример плохого Bash-скрипта:


cp "$src" "$dst" &&
nginx -t &&
systemctl reload nginx ||
echo "something failed"


Пример более читаемого подхода:


deploy_config "$src" "$dst"
validate_nginx
reload_service nginx


Да, bash не станет от этого python. Но даже в shell можно писать так, чтобы скрипт был похож на понятную инструкцию, а не на клубок из условий, пайпов и боли.

#bash #scripting

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍9💩2
Делая ремонт, не забудьте в инсталляцию добавить самое нужное

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁11
🦖 ECMP: балансировка трафика на уровне маршрутизации

Когда говорят о балансировке, то чаще вспоминают L4/L7-балансировщики. Но распределять трафик можно и ниже - прямо на уровне маршрутизации. Для этого существует ECMP - Equal-Cost Multi-Path.

Суть простая: если до одной и той же сети есть несколько маршрутов с одинаковой метрикой, роутер может использовать их параллельно, а не держать один основным, а остальные про запас.

Что это дает:

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

Важный момент: ECMP обычно балансирует не каждый пакет как попало, а по хэшу потока. Например, учитываются source IP, destination IP, порты, протокол и весь конкретный flow идет по одному пути.

Это нужно, чтобы не получить reordering пакетов и не сломать TCP-сессии.

То есть два клиента могут уйти разными маршрутами, но один и тот же TCP-flow обычно будет идти стабильно по одному next-hop.

🤩 Где часто ошибаются:

▪️ думают, что ECMP всегда делит трафик идеально 50/50. На деле распределение зависит от числа flow и алгоритма хэширования.

▪️ путают ECMP с failover. ECMP - это не только резервирование, а именно одновременное использование нескольких равных путей.

▪️ забывают про asymmetry. В одну сторону трафик может пойти одним путем, в другую - другим. Для stateful-устройств это иногда становится проблемой.

ECMP хорошо работает там, где сеть и маршрутизация изначально под это спроектированы. Если просто включить ради баланса, можно получить странное распределение, проблемы с firewall state tracking и сложную диагностику.

#network #routing

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72
⭐️ QoS в Linux

Как только в linux заходит разговор про QoS, shaping и управление трафиком, у многих сразу одна реакция: tc - это боль, страдание и странные команды из 2009 года. И это недалеко от правды. Утилита мощная, но синтаксис у нее такой, будто она не хочет, чтобы ей пользовались. При этом tc - это стандартный инструмент linux для управления очередями, задержками, полосой и приоритетами трафика.

Что с его помощью обычно делают:

ограничивают скорость;
дают приоритет важному трафику;
режут шумные сервисы;
эмулируют плохую сеть: delay, loss, jitter;
наводят порядок на WAN-линках и VPN.


Самое главное, что нужно понять:

QoS в linux почти всегда про исходящий трафик (egress). Входящий поток контролировать сложнее, обычно его либо полируют через IFB, либо ограничивают уже на стороне отправителя.

▪️ Самый простой пример - ограничить скорость интерфейса до 50 Мбит/с:


tc qdisc add dev eth0 root tbf rate 50mbit burst 32kbit latency 400ms


tbf - Token Bucket Filter
rate - лимит скорости
burst - допустимый всплеск
latency - максимальная задержка очереди

▪️ Удалить правило:


tc qdisc del dev eth0 root


Если нужен вариант без магии, для большинства случаев, чаще смотрят в сторону fq_codel или cake. Например:


tc qdisc add dev eth0 root fq_codel


fq_codel хорош тем, что помогает бороться с bufferbloat и в целом делает очередь более адекватной без сложной ручной настройки.

▪️ Если нужно не просто сделать лучше, а именно ограничить канал и при этом сохранить нормальную отзывчивость, часто используют cake:


tc qdisc add dev eth0 root cake bandwidth 100mbit


Почему tc кажется страшным:

qdisc
class
filter
parent
handle
flowid


На первый взгляд это выглядит как отдельная религия. Но на практике часто хватает 3 сценариев:

ограничить скорость
сделать очередь адекватной
эмулировать плохую сеть для тестов

Например, добавить задержку в 100 мс:


tc qdisc add dev eth0 root netem delay 100ms


Или сделать "плохую" сеть с потерями:


tc qdisc add dev eth0 root netem delay 100ms loss 2%


Это уже очень полезно для тестирования приложений, API, VoIP, VPN и всего, что в локалке работает идеально, а в реальной сети нет.

#tc #network

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72
🆗 httpie: удобная замена curl для API

curl знает почти каждый админ. Но как только нужно не просто дернуть URL, а нормально поработать с API, команды быстро превращаются в нечитаемую строку из флагов, кавычек и JSON в одну линию. В таких случаях очень выручает HTTPie - более удобный CLI-клиент для HTTP-запросов. Он не заменяет curl полностью, но для работы с REST API часто оказывается проще, нагляднее и быстрее.

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


apt install httpie


или:


pip install httpie


▪️ Самый простой GET-запрос:


http GET https://api.netwrokadmin.ru/users


Можно даже короче:


http https://api.netwrokadmin.ru/users


Ответ HTTPie показывает в читаемом виде:

статус
заголовки
JSON с форматированием

Именно это делает его удобным при ручной диагностике API.

▪️ POST-запрос с JSON выглядит очень аккуратно:


http POST https://api.netwrokadmin.ru/users name=alice role=admin


HTTPie сам соберет JSON и выставит правильный Content-Type.

Если нужен явный raw JSON:


http POST https://api.netwrokadmin.ru/users <<< '{"name":"alice","role":"admin"}'


▪️ Заголовки добавляются тоже проще, чем в curl:


http GET https://api.netwrokadmin.ru/users Authorization:"Bearer TOKEN"


▪️ Отправка файла:


http -f POST https://api.netwrokadmin.ru/upload file@backup.tar.gz


Для скриптов и старых automation-цепочек curl по-прежнему часто остается стандартом. А вот для ручной работы с API в терминале httpie обычно приятнее.

#httpie #api

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥5
Ну это база, когда дело дошло до настройки

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10
📷 Кто, когда и какой файл трогал

Кто изменил файл? Кто трогал /etc/passwd, кто переписал конфиг, кто удалил файл, и когда это произошло.

Если обычные логи тут не помогают, то на помощь идет auditd - подсистема аудита в linux, которая умеет фиксировать действия с файлами, процессами, системными вызовами и пользователями. Для админа это один из самых полезных инструментов, когда нужно не гадать, а точно увидеть факт доступа или изменения.

▪️ Что умеет auditd:

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

▪️ Установка обычно такая:


apt install auditd audispd-plugins


или:


yum install audit


▪️ Работа с auditd. После установки сервис нужно запустить и добавить в автозагрузку:


systemctl enable --now auditd


Теперь самое полезное - можно поставить правило на конкретный файл или каталог. Например, хотим отслеживать изменения файла /etc/ssh/sshd_config:


auditctl -w /etc/ssh/sshd_config -p wa -k sshd_config_watch


-w - watch, следить за файлом
-p wa - отслеживать запись (w) и изменение атрибутов (a)
-k sshd_config_watch - удобный ключ для поиска событий

После этого все изменения файла начнут попадать в audit log.

Посмотреть события можно так:


ausearch -k sshd_config_watch


Если нужен более читаемый вывод:


ausearch -k sshd_config_watch -i


Здесь можно увидеть, например, что файл менял vim, sed, ansible, echo >>, или какой-нибудь скрипт деплоя.

Если нужно следить не за одним файлом, а за каталогом:


auditctl -w /etc/nginx/ -p wa -k nginx_conf_watch


Теперь можно быстро искать все события по конфигам Nginx:


ausearch -k nginx_conf_watch -i


▪️ Еще полезный инструмент - aureport. Например, краткий отчет по событиям:


aureport -f -i


Он показывает сводку по файловым операциям. Здесь важно учесть: правила через auditctl обычно неперсистентны. То есть после перезагрузки они исчезнут. Чтобы сохранить их постоянно, добавляют правила в конфиг auditd, например:


/etc/audit/rules.d/audit.rules


или отдельным файлом в rules.d, например:


-w /etc/ssh/sshd_config -p wa -k sshd_config_watch
-w /etc/nginx/ -p wa -k nginx_conf_watch


А потом загружают правила:


augenrules --load


или перезапускают auditd.

#linux #auditd

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
12
💚 SSH bastion host: безопасный вход в инфраструктуру

В небольших инфраструктурах часто делают просто: открывают SSH на всех серверах и заходят напрямую. Пока серверов 2-3 - это еще терпимо. Но когда инфраструктура растет, такой подход превращается в проблему безопасности.

Один из классических способов навести порядок: использовать bastion host (jump host).

Идея простая: внешний доступ по SSH есть только к одному серверу, а уже с него можно попасть во внутреннюю инфраструктуру.

Схема обычно выглядит так:


Internet
|
v
[Bastion Host]
|
+---- app01
+---- db01
+---- k8s-node01
+---- internal services


▪️ Что это дает на практике:

одна точка входа в инфраструктуру;
проще контролировать доступ;
легче логировать действия админов;
внутренние серверы вообще не торчат в интернет;
проще внедрять MFA, audit и ограничения.

Вместо подключения напрямую:


ssh app01.internal


подключение идет через bastion.

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


ssh -J bastion user@app01.internal


Ключ -J - это ProxyJump. То есть SSH сначала подключается к bastion, а уже через него к целевому серверу.

Чтобы не писать длинные команды, обычно добавляют конфиг в ~/.ssh/config:


Host bastion
HostName bastion.example.com
User admin

Host *.internal
ProxyJump bastion
User admin


После этого можно подключаться так:


ssh app01.internal


SSH сам пройдет через bastion.

▪️ На bastion часто дополнительно включают:

жесткую аутентификацию;
MFA;
ограничение по IP;
audit логирование;
запрет прямого root-доступа.

Хороший bastion - это не просто сервер-посредник. Это контрольная точка безопасности, через которую проходит весь административный доступ к инфраструктуре. Именно поэтому в серьезных средах SSH на внутренние серверы часто вообще не открыт извне, только через jump host.

#ssh #security

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥31
Так и живем

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🔒 Альтернатива GPG для шифрования файлов

gpg - хороший инструмент, но многие админы сталкивались с его обратной стороной: сложная модель ключей, непонятные ошибки, длинные команды и постоянная борьба с keyring. Если задача простая - зашифровать файл и безопасно передать его, то вся эта сложность часто избыточна.

Для таких случаев существует age - минималистичный инструмент для шифрования файлов. Его идея очень простая: никаких keyserver, trust model и сложной криптоэкосистемы - только шифрование.

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


apt install age


▪️ Создадим ключ:


age-keygen -o key.txt


В файле будет примерно такое:


# public key: age1...
AGE-SECRET-KEY-1...


public key используется для шифрования
secret key для расшифровки

▪️ Зашифровать файл:


age -r age1xxxxx -o backup.tar.gz.age backup.tar.gz


▪️ Расшифровать:


age -d -i key.txt backup.tar.gz.age > backup.tar.gz


▪️ Можно шифровать и нескольким получателям:


age -r key1 -r key2 -o secrets.txt.age secrets.txt


Каждый из владельцев ключа сможет расшифровать файл.

▪️ Есть и вариант с паролем:


age -p -o secrets.txt.age secrets.txt


При расшифровке будет запрошен passphrase.

#linux #security

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
💿 WinPE не видит диски: загрузка драйверов

В WIM-образе WinPE содержится только минимальный набор универсальных драйверов. Их хватает для базового обнаружения оборудования, но в реальных инфраструктурах этого часто недостаточно.

Поэтому иногда возникает ситуация, когда: установщик Windows, загрузочная среда WinPE или среда восстановления WinRE не видят локальные диски или сетевые адаптеры.

▪️ Типичный пример - миграция виртуальной машины. После переноса ВМ с ESXi на Proxmox в гостевой Windows может не оказаться драйверов VirtIO. В этом случае при загрузке система падает с ошибкой:


0x0000007B: INACCESSIBLE_BOOT_DEVICE


Причина простая: Windows не понимает, как работать с новым SCSI-контроллером. Лучшее решение - установить VirtIO-драйверы в систему до начала миграции. Но если это уже произошло, проблему можно исправить через WinPE.

▪️ Загрузка драйвера прямо в WinPE. Смонтируйте ISO с драйверами VirtIO и загрузите нужный драйвер вручную:


drvload d:\vioscsi\2k22\amd64\vioscsi.inf


Команда загружает драйвер в память среды WinPE.

Проверить, что драйвер появился:


pnputil /enum-drivers


После этого WinPE должен увидеть диск с установленной Windows.

▪️ Добавляем драйвер в офлайн систему. Чтобы Windows смогла нормально загрузиться, добавим драйвер прямо в офлайн-образ системы:


DISM /Image:C:\ /Add-Driver /Driver:D:\vioscsi\2k22\amd64\vioscsi.inf


После этого драйвер VirtIO будет установлен в систему, и Windows сможет корректно работать с паравиртуализированным SCSI-контроллером.

⚠️ Такой подход полезен не только для VirtIO. Через drvload и DISM можно подгружать сетевые, RAID и NVMe драйверы, если WinPE их не распознает.

#windows #winpe

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍2
🤔 Idempotency: как не сломать прод повторным запуском

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

Именно здесь важна идемпотентность. Идемпотентный сценарий - это когда команду, скрипт или automation можно запускать повторно, а результат будет тем же, что и после первого успешного запуска. Проще говоря: повторный запуск не должен ломать систему.

▪️ Где чаще всего все ломается:

useradd без проверки - пользователь уже существует
echo ... >> file - строки дублируются при каждом запуске
mkdir dir без -p - ошибка на втором запуске
правила firewall добавляются снова и снова
конфиг не заменяется, а “дописывается сверху”
миграция БД запускается повторно без защиты

▪️ Плохой пример:


echo "backup enabled" >> /etc/myapp.conf
useradd deploy
systemctl restart myapp


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

▪️ Более здоровый подход:


grep -q "^backup enabled$" /etc/myapp.conf || echo "backup enabled" >> /etc/myapp.conf
id deploy >/dev/null 2>&1 || useradd deploy
systemctl try-restart myapp


Смысл простой: сначала проверка состояния, потом изменение только если нужно.

Вот главный принцип идемпотентности в админке: не "сделай действие", а "приведи систему к нужному состоянию".

То есть не: создай каталог, добавь строку или создай пользователя
а: убедись, что каталог существует, убедись, что строка есть в конфиге, убедись, что пользователь создан.

Именно поэтому Ansible так любят: он по умолчанию мыслит состоянием, а не одноразовыми действиями.

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

проверки перед изменением
безопасные команды вроде mkdir -p
ln -sfn вместо слепого ln -s
шаблоны конфигов вместо бесконечного echo >>
явная логика: если уже сделано - пропусти
аккуратная работа с exit code

Очень частая ошибка - считать, что скрипт нормальный, если он успешно отработал один раз.

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

Идемпотентность не означает, что скрипт вообще ничего не делает при повторном запуске. Она означает, что он не вносит лишних изменений и не уводит систему в другое состояние. Когда automation пишется без этого принципа, любой повторный запуск превращается в лотерею.

#linux #automation

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
👀 Security Onion/Wazuh: стоит ли тащить SIEM в небольшую сеть

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

Wazuh и Security Onion - это не одно и то же.

Wazuh - это open source платформа с упором на XDR/SIEM, агентский сбор событий, контроль целостности, уязвимости и корреляцию. У нее есть all-in-one deployment, который сам вендор считает подходящим небольших сред.

Security Onion - это уже более тяжелая история про network visibility, IDS, логи, кейс-менеджмент и полноценный security stack. Даже standalone-установка требует минимум 24 GB RAM, 4 vCPU и 200 GB диска, а для небольшого объема трафика сами разработчики советуют скорее 32 GB RAM и выше.

▪️ Что это значит по-простому:

• если у вас 10–50 серверов/рабочих станций и нужен порядок в логах, алертах и FIM - чаще разумнее смотреть в Wazuh. Для маленькой команды он обычно реалистичнее по железу и внедрению, плюс у него есть all-in-one и даже Docker single-node с порогом от 4 CPU, 8 GB RAM и 50 GB диска.

• если вы хотите именно сетевой мониторинг, IDS/NDR и разбор трафика, тогда Security Onion интереснее, но и цена входа по ресурсам и сопровождению заметно выше.

Главная ошибка маленьких сетей - тащить SIEM потому что так надо, а потом:

никто не разбирает алерты
retention урезан до боли
storage забивается за пару дней
ложные срабатывания быстро надоедают
платформа живет сама по себе, без реальной пользы

Вывод примерно такой:

в небольшую сеть SIEM стоит тащить только если есть конкретная цель: контроль критичных логов, аудит, FIM, базовая корреляция, расследование инцидентов.

Wazuh в такой роли обычно выглядит практичнее. Security Onion - уже когда вам действительно нужен сетевой security monitoring, а не просто хотим SIEM как у больших.

#security #siem

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥31👌1
👇 Типовые ошибки при монтировании дисков

/etc/fstab - один из тех файлов, которые выглядят безобидно ровно до первой ошибки. Одна кривая строка и после перезагрузки сервер может внезапно уйти в emergency mode вместо нормальной загрузки. Поэтому fstab - это не то место, где стоит править на глаз.

Что обычно описывают в fstab:

локальные диски;
LVM-разделы;
UUID устройств;
NFS/SMB-шары;
swap;
временные файловые системы.


Типовая строка выглядит так:


UUID=xxxx-xxxx /data ext4 defaults 0 2


▪️ Где чаще всего ошибаются:

1️⃣ Используют /dev/sdX вместо UUID. После перезагрузки или изменения порядка устройств диск может стать уже не sdb, а sdc. И mount сломается. Лучше так:


blkid


И в fstab использовать UUID=.

2️⃣ Путают точку монтирования. Каталог /data должен существовать заранее. Если его нет, система может не примонтировать раздел как ожидалось.

3️⃣ Ошибаются в типе файловой системы. Написали ext4 вместо xfs, xfs вместо ext4 - получили ошибку на загрузке.

4️⃣ Бездумно ставят defaults везде подряд. Для локального диска это нормально, но для NFS, CIFS, removable media или специальных mount’ов часто нужны отдельные опции.

5️⃣ Ломают загрузку сетевыми маунтами. Очень частая история: добавили NFS или SMB в fstab, сеть при старте еще не поднялась, и система зависает на boot.

Для таких случаев обычно используют:


_netdev,nofail,x-systemd.automount


6️⃣ Забывают про nofail для некритичных дисков. Если том не жизненно важен, лучше не валить из-за него загрузку всей системы.

7️⃣ Неправильно ставят последние два поля. Напоминание: предпоследнее - dump, а последнее - порядок fsck

Обычно для обычных разделов так: 0 2
Для root: 0 1
Для swap и многих специальных маунтов: 0 0

▪️ Что делать безопасно после правки: никогда не проверять только перезагрузкой.

Сначала:


mount -a


Если команда отработала молча - уже хороший знак. Если есть ошибка, увидите ее сразу, а не после reboot.

Еще полезно проверить:


findmnt


или


systemctl daemon-reload


если используете systemd-специфичные опции.

#linux #fstab

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91
Играл в настройки. Проиграл.

#юмор

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
😁14
☄️ Быстрый поиск по логам, конфигам и проектам

Когда нужно быстро что-то найти в логах, конфигах или коде, многие по привычке используют grep -R. Рабочий вариант, но на больших каталогах он быстро начинает раздражать: шумный вывод, медленный поиск, лишние файлы. Для таких задач есть ripgrep (rg) - быстрый и удобный инструмент для поиска по тексту. По сути это современный grep, который хорошо подходит и для админки, и для разработки.

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


apt install ripgrep


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


rg nginx


Команда найдет все вхождения nginx в текущем каталоге и покажет: путь к файлу, номер строки и совпадение в контексте.

▪️ Почему ripgrep так любят:

1️⃣ Работает быстро. Особенно заметно на больших деревьях каталогов.
2️⃣ По умолчанию умнее обычного grep. Игнорирует .gitignore, скрытые мусорные каталоги, временные файлы и бинарники.
3️⃣ Удобный вывод. Сразу видно файл, строку и совпадение без лишней возни.

На практике это очень удобно.

▪️ Примеры:

Ищем ошибку в логах:


rg "connection refused" /var/log


Ищем параметр в конфигах:


rg "proxy_pass" /etc/nginx


Ищем использование переменной в проекте:


rg "DB_HOST" /opt/myapp


▪️ Полезные флаги:

без учета регистра


rg -i error /var/log


только список файлов с совпадением


rg -l "server_name" /etc/nginx


искать только по определенным типам файлов


rg "listen 443" -t conf /etc


искать в скрытых файлах тоже


rg -uu "token"


показать несколько строк контекста


rg -C 2 "fatal" /var/log


▪️ Очень полезный сценарий - искать сразу по нескольким шаблонам:


rg "error|failed|denied" /var/log/auth.log


Или находить TODO/FIXME в проекте:


rg "TODO|FIXME" ~/projects


#linux #ripgrep

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🤩 Почему delete не всегда освобождает место на диске

Одна из неприятных ситуаций на сервере выглядит так: удалили большой файл, а место на диске не появилось. rm отработал, файла уже нет, но df -h показывает почти то же самое заполнение. Кажется, что что-то сломалось, но обычно проблема не в диске, а в том, как устроено удаление файлов.

Важно понять простую вещь: когда вы делаете rm, файл не исчезает с диска мгновенно. Удаляется ссылка на файл из файловой системы. Но если какой-то процесс все еще держит этот файл открытым, его данные продолжают занимать место.

То есть для ядра ситуация выглядит так:

имени файла уже нет;
в каталоге он не виден;
но процесс все еще пишет или читает его через открытый file descriptor.

Пока этот дескриптор не будет закрыт, место не освободится.

▪️ Типичный сценарий:

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

Именно поэтому иногда возникает странная картина:


du -sh /var/log


показывает одно, а


df -h


говорит, что диск почти заполнен.

▪️ Как найти такие файлы:


lsof | grep deleted


Или точнее:


lsof +L1


Эта команда показывает открытые файлы, у которых уже удалена ссылка из файловой системы.

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

▪️ Что делать дальше:

самый правильный вариант - перезапустить процесс, который держит файл
иногда достаточно корректно перечитать логи через systemctl reload
в крайнем случае: restart сервиса

Например, если это nginx, rsyslog, java-процесс или postgres, после перезапуска место обычно сразу возвращается.

▪️ Почему это важно знать:

Админ может удалить 20 ГБ логов и не понять, почему сервер все равно задыхается. А потом начать искать битую файловую систему, хотя проблема всего лишь в открытом удаленном файле.

du считает то, что видно в дереве каталогов.
df показывает то, что реально занято на файловой системе.

Если файл удален, но открыт процессом, du его уже не увидит, а df - да.

#linux #storage

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍91
👍 Split-horizon DNS: как не сломать внутренний и внешний доступ

Иногда один и тот же домен должен по-разному резолвиться изнутри и снаружи.

Например:

с интернета app.networkadmin.ru должен вести на публичный IP
из локальной сети - на внутренний адрес
внутри VPN - вообще на отдельный хост или балансировщик

Для этого и используют split-horizon DNS.

Его суть простая: разным клиентам DNS-сервер отдает разные ответы на один и тот же запрос.

▪️ На практике это выглядит так:

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

Пример: app.networkadmin.ru
Снаружи: 203.0.113.10
Изнутри: 10.10.20.15

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

не гонять внутренний трафик через внешний периметр;
не упираться в NAT loopback / hairpin NAT;
использовать один и тот же FQDN для всех пользователей;
разделять внутренние и внешние сервисы без лишнего зоопарка имен;

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

▪️ Что обычно ломают:

внутренний и внешний DNS живут разной жизнью. Снаружи запись уже поменяли, внутри забыли. В итоге часть пользователей ходит на старый IP.
сертификаты и TLS. Если внутри и снаружи используются разные имена для удобства, потом начинаются сюрпризы с HTTPS, redirect и SSO.
внутренний адрес недоступен части клиентов.Например, ноутбук без VPN получает внутренний DNS-ответ, но до приватного IP дотянуться не может.
отладка становится сложнее. У одного пользователя сервис работает, у другого - нет. И оба резолвят один и тот же домен, но в разные адреса.

▪️ Классический безопасный сценарий:

одно и то же DNS-имя;
внешний DNS отдает публичный IP;
внутренний DNS отдает приватный IP;
приложение и сертификаты рассчитаны на один FQDN.

▪️ Проверять это лучше явно:


dig app.networkadmin.ru
dig @internal-dns app.networkadmin.ru
dig @8.8.8.8 app.networkadmin.ru


Так сразу видно, какие ответы получают разные резолверы.

#dns #network

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3👎1
🗂 Как быстро собирать временные файловые слои

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

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

▪️ Типичная схема такая:

lowerdir - базовый слой только для чтения
upperdir - все новые изменения
workdir - служебный каталог overlayfs
merged - итоговая точка монтирования

▪️ Пример:


mkdir -p /tmp/overlay/{lower,upper,work,merged}
echo "base config" > /tmp/overlay/lower/app.conf

mount -t overlay overlay \
-o lowerdir=/tmp/overlay/lower,upperdir=/tmp/overlay/upper,workdir=/tmp/overlay/work \
/tmp/overlay/merged


Теперь в /tmp/overlay/merged будет виден базовый файл app.conf.

Если изменить его через merged:


echo "new config" > /tmp/overlay/merged/app.conf


то исходный файл в lower не поменяется. Изменение попадет в upper, а overlay покажет уже новую версию файла.

▪️ Почему это удобно:

не нужно копировать весь каталог ради теста;
можно быстро делать временные изменения;
исходные данные остаются нетронутыми;
удобно для sandbox-сценариев, chroot, build-окружений и контейнеров.

▪️ Размонтировать:


umount /tmp/overlay/merged


▪️ Важно учитывать:

upperdir и workdir должны быть на одной файловой системе;
lowerdir может быть read-only;
удаление файлов тоже идет через overlay-механику, а не по-настоящему из нижнего слоя;
это не замена снапшотам и не полноценный backup-механизм.

#linux #overlayfs

🧑‍💻 NetworkAdmin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🤔1
Что происходит на перегруженном TCP-сервере

Когда TCP-сервер начинает захлебываться под нагрузкой, проблема не всегда в CPU, памяти или плохом приложении. Иногда упирается сам механизм приема новых соединений. Чтобы понять, что происходит, полезно знать три вещи: SYN flood, backlog и somaxconn

▪️ Как выглядит обычное TCP-подключение:

клиент отправляет SYN
сервер отвечает SYN-ACK
клиент присылает ACK
соединение считается установленным

Но между "клиент постучался" и "приложение приняло соединение" есть очереди ядра.

▪️ Что может пойти не так:

SYN flood. Сервер получает огромное количество SYN, но рукопожатие не завершается. Это может быть атака, кривой балансировщик, сетевые потери или просто всплеск нагрузки. В итоге очередь полуоткрытых соединений заполняется, и новые клиенты начинают теряться.

backlog. Когда приложение вызывает listen(), оно указывает размер очереди ожидающих подключений.
Если приложение не успевает быстро принимать новые соединения через accept(), очередь переполняется.
Тогда часть клиентов начинает видеть: таймауты, connection refused, повторные SYN, странные задержки на подключении.

somaxconn. Это системный лимит ядра на максимальный backlog. Даже если приложение просит большую очередь, ядро все равно ограничит ее значением net.core.somaxconn.

Посмотреть можно так:


sysctl net.core.somaxconn


А заодно часто смотрят:


sysctl net.ipv4.tcp_max_syn_backlog


Первый параметр влияет на очередь установленных, но еще не принятых приложением соединений. Второй на очередь полуоткрытых SYN.

▪️ Что происходит на перегруженном сервере на практике:

приложение медленно вызывает accept()
очередь backlog заполняется
новые подключения начинают отваливаться
если сверху еще идет SYN flood, ситуация усугубляется
снаружи кажется, что сервер то работает, то нет

▪️ Как смотреть симптомы:


ss -lnt
netstat -s | grep -i listen
dmesg | grep -i syn


▪️ Что обычно помогает:

увеличить somaxconn;
проверить backlog самого приложения;
поднять tcp_max_syn_backlog;
включить или проверить SYN cookies;
разбираться, почему приложение медленно принимает соединения;
выносить защиту от flood на firewall/LB;

Например:


sysctl -w net.core.somaxconn=4096
sysctl -w net.ipv4.tcp_max_syn_backlog=4096


Но увеличение очередей не лечит корень проблемы. Если приложение не успевает обрабатывать подключения, вы просто делаете буфер больше. Это даст время, но не бесконечную защиту. Хорошая диагностика здесь начинается с простого вопроса: сервер не справляется с валидной нагрузкой или его забивают незавершенными SYN? Потому что снаружи это выглядит одинаково: TCP-порт открыт, а подключиться нормально уже нельзя.

#tcp #network

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