en
Feedback
LinuxSkill - Сводки с прода и Шпаргалки

LinuxSkill - Сводки с прода и Шпаргалки

Open in Telegram

Следим за новостями Linux, DevOps и ИБ, чтобы быть готовым к любым факапам. Бонусом — плотные шпаргалки и чеклисты для ежедневной работы в терминале. 📩 По всем вопросам: @chorapov Зеркало в MAX: https://max.ru/LinuxSkill РКН https://vk.cc/cMUwm4

Show more

📈 Analytical overview of Telegram channel LinuxSkill - Сводки с прода и Шпаргалки

Channel LinuxSkill - Сводки с прода и Шпаргалки (@linuxskill) in the Russian language segment is an active participant. Currently, the community unites 10 747 subscribers, ranking 11 103 in the Technologies & Applications category and 59 284 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 10 747 subscribers.

According to the latest data from 30 August, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -48 over the last 30 days and by 0 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 11.54%. Within the first 24 hours after publication, content typically collects 4.80% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 1 240 views. Within the first day, a publication typically gains 516 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 4.
  • Thematic interests: Content is focused on key topics such as docker, linux, bash, devops, скрипт.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
Следим за новостями Linux, DevOps и ИБ, чтобы быть готовым к любым факапам. Бонусом — плотные шпаргалки и чеклисты для ежедневной работы в терминале. 📩 По всем вопросам: @chorapov Зеркало в MAX: https://max.ru/LinuxSkill РКН https://vk.cc/cMUwm4

Thanks to the high frequency of updates (latest data received on 31 August, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

10 747
Subscribers
No data24 hours
-107 days
-4830 days

Data loading in progress...

Attracting Subscribers
August '26
August '26
+11
in 0 channels
July '26
+20
in 0 channels
Get PRO
June '26
+20
in 0 channels
Get PRO
May '26
+57
in 0 channels
Get PRO
April '26
+47
in 0 channels
Get PRO
March '26
+26
in 0 channels
Get PRO
February '26
+257
in 0 channels
Get PRO
January '26
+49
in 2 channels
Get PRO
December '25
+70
in 6 channels
Get PRO
November '25
+76
in 0 channels
Get PRO
October '25
+230
in 0 channels
Get PRO
September '25
+367
in 0 channels
Get PRO
August '25
+505
in 0 channels
Get PRO
July '25
+238
in 1 channels
Get PRO
June '25
+89
in 0 channels
Get PRO
May '25
+539
in 1 channels
Get PRO
April '25
+193
in 0 channels
Get PRO
March '25
+192
in 0 channels
Get PRO
February '25
+159
in 0 channels
Get PRO
January '25
+187
in 1 channels
Get PRO
December '24
+503
in 4 channels
Get PRO
November '24
+1 144
in 0 channels
Get PRO
October '24
+1 744
in 0 channels
Get PRO
September '24
+782
in 0 channels
Get PRO
August '24
+874
in 0 channels
Get PRO
July '24
+912
in 0 channels
Get PRO
June '24
+1 949
in 0 channels
Get PRO
May '24
+416
in 0 channels
Get PRO
April '24
+581
in 0 channels
Get PRO
March '24
+359
in 0 channels
Get PRO
February '24
+1 227
in 0 channels
Date
Subscriber Growth
Mentions
Channels
31 August0
30 August0
29 August0
28 August0
27 August0
26 August0
25 August0
24 August+2
23 August0
22 August0
21 August+1
20 August+1
19 August+1
18 August0
17 August+3
16 August+1
15 August0
14 August+1
13 August0
12 August0
11 August0
10 August0
09 August0
08 August0
07 August0
06 August0
05 August0
04 August0
03 August+1
02 August0
01 August0
Channel Posts
Сервис упал ночью, до утра гигабайт логов. Порядок, в котором в них лезть Начать с ошибок текущей загрузки

journalctl -p err -b
-b отсекает всё, что было до последней перезагрузки, -p err оставляет уровень Error и выше. Цифровой вариант -p 3 делает то же самое, но словом читается лучше. Сузить окно до времени инцидента

journalctl --since "2026-08-13 23:00:00" \
  --until "2026-08-14 01:00:00"
Нюанс: форматы вроде yesterday 23:00:00, которые кочуют по подборкам, systemd не разбирает — получишь Failed to parse timestamp. Проверил на systemd 255: отдельно yesterday работает, -2h работает, 23:00 работает, а вот их комбинация — нет. Надёжнее всегда писать полную дату. Посмотреть, не прибило ли сервис ядро

dmesg -T --level=err,warn
dmesg -T | grep -i oom-killer
-T переводит секунды аптайма в нормальную дату. Фильтр по уровню полезнее грепа: покажет и OOM, и ошибки диска, и отвалившийся сетевой интерфейс. Проверить блокировки SELinux

ausearch -m avc -ts recent
Нюанс: на Debian и Ubuntu команда чаще всего вернёт пустоту — там AppArmor, а не SELinux, и /sys/fs/selinux просто нет. Шаг актуален для RHEL-семейства; на Debian смотри journalctl -t audit и dmesg | grep -i apparmor. Найти, кто сканирует сайт

awk -F'"' '{split($3,a," ");
  if (a[1]==404) print $1}' access.log |
  awk '{print $1}' | sort | uniq -c | sort -rn
Нюанс: ходовой вариант awk '$9 == 404' разваливается, если в URL попал пробел — поле уезжает, и строка молча не считается. У меня из трёх запросов с 404 такой вариант нашёл два. Разбор по кавычкам берёт код ответа там, где он реально лежит. Для пары серверов этого хватает. Когда машин десятки, CLI перестаёт работать и нужен Loki или ELK — но и там первый вопрос будет тот же: какое окно и какой приоритет. А с чего начинаете вы, когда прод упал и надо быстро локализовать причину? #Linux #Logs #journalctl #Troubleshooting #DevOps

2
Диски гостей раздулись, а внутри места полно. Вернуть его хосту — и не просадить запись Проверить, поддерживает ли диск discard lsblk --discard Нюанс: в подборках советуют hdparm -I /dev/sda | grep -i trim. На virtio-диске это не сработает вовсе — у меня вернуло Operation not permitted, потому что hdparm говорит по протоколу ATA, которого у виртуального диска нет. lsblk --discard показывает нужное для любого типа: NAME DISC-GRAN DISC-MAX vda 4K 1G vdb 0B 0B Ненулевые DISC-GRAN и DISC-MAX означают, что discard проходит. Нули — гипервизор его не отдаёт, дальше можно не настраивать. Отдать блоки хосту прямо сейчас fstrim -av --dry-run fstrim -av Сначала --dry-run: он делает всё то же самое, но без самого discard. У меня показал 0 B (dry run) trimmed on /dev/vda, а боевой запуск вернул 243.1 GiB trimmed. Настроить регулярный TRIM systemctl enable --now fstrim.timer systemctl list-timers fstrim.timer Нюанс: свой скрипт в /etc/cron.weekly писать не нужно — в пакете util-linux уже лежит готовый fstrim.timer с OnCalendar=weekly и разбросом запуска до 100 минут, чтобы виртуалки не пошли в discard одновременно. Если всё-таки делаешь через cron, помни про две вещи. Скрипт без строки #!/bin/sh не выполнится: run-parts: failed to exec: Exec format error. И файл с точкой в имени, вроде fstrim.sh, run-parts молча пропустит. Не включать онлайн-TRIM в fstab UUID=xxxx / ext4 defaults,discard 0 1 Опция discard при монтировании шлёт запрос на очистку при удалении каждого файла. Пакетный TRIM раз в неделю делает то же самое, но одним заходом и в спокойное время. Всё это работает, только если discard включён в настройках диска на самом гипервизоре. Иначе гость честно шлёт команды, а хост их игнорирует и продолжает копить мусор. А вы fstrim по таймеру гоняете или руками, когда место кончилось? #Linux #Virtualization #Proxmox #fstrim #DevOps
656
3
🎥 Вебинар: Первый веб-сервер на Linux: Nginx, Apache и проверка доступности На открытом уроке разберем, как устроен веб-серв
🎥 Вебинар: Первый веб-сервер на Linux: Nginx, Apache и проверка доступности На открытом уроке разберем, как устроен веб-сервер на Linux и какие компоненты нужны для публикации веб-приложения. Рассмотрим базовую настройку Nginx и Apache, проверку доступности сервиса и принцип работы обратного прокси. О чем поговорим: — Из каких сервисов состоит базовая конфигурация веб-сервера — Чем отличаются задачи Nginx и Apache — Как установить и выполнить первичную настройку веб-сервера — Как проверить, что сервис запущен и доступен по сети — Как работает обратный прокси и для чего он используется 🧠 Вебинар приурочен к старту курса «Администратор Linux. Базовый уровень». Вы освоите Bash, TCP/IP, Nginx, Apache, MySQL, Docker, Git, Prometheus, Grafana и ELK. На живых занятиях с практикующими экспертами научитесь настраивать веб-серверы, работать с сетью, контейнерами, мониторингом и фильтрацией трафика. 👉 Для участия зарегистрируйтесь https://otus.pw/nUFb/ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
988
4
Как достать пароль из kdbx, когда графика легла и буфер обмена недоступен Всё проверено на keepassxc-cli 2.7.6 из репозитория Ubuntu 24.04. Посмотреть, что вообще есть в базе keepassxc-cli ls -R database.kdbx Нюанс: без -R увидишь только верхний уровень. Вложенные записи в группах не покажет — легко решить, что база пустая. Вытащить конкретный пароль в терминал keepassxc-cli show -a Password database.kdbx "Production/DB" Нюанс: обычный show без ключей выводит Password: PROTECTED вместо значения. Флаг -s раскрывает все поля, -a Password отдаёт только пароль одной строкой — удобно подставлять в скрипт. Открыть базу с файлом ключей keepassxc-cli ls -k keyfile.key database.kdbx Тот же -k работает во всех подкомандах. Если пароля на базе нет вообще, добавь --no-password, иначе утилита будет ждать ввода. Найти запись, когда не помнишь путь keepassxc-cli search database.kdbx "DB" Вернёт полный путь вида /Production/DB, который дальше подставляется в show. Забрать всю базу разом keepassxc-cli export -f csv database.kdbx Отдаёт в stdout все записи вместе с паролями открытым текстом. Полезно при переезде, но перенаправлять это в файл на общей машине — плохая идея. Про clip, который советуют для копирования пароля в буфер. Именно в сценарии «GUI лёг» он и не работает: без графической сессии команда отвечает All clipping programs failed. Tried xclip. Смысл в нём есть только в живой графике, где он же и чистит буфер через 10 секунд. И про совет закрыть GUI перед работой в консоли. Проверил: при открытой базе KeePassXC создаёт рядом файл .kdbx.lock. Утилита о нём знает, так что «гарантированного повреждения» не будет — но менять базу из двух мест одновременно всё равно не стоит, последняя запись затрёт чужие правки. А вы держите пароли в локальных kdbx или переехали на self-hosted Vaultwarden? #Linux #KeePass #Security #CLI #DevOps
784
5
Если гоняешь ansible по сотне серверов, SSH каждый раз делает хендшейк заново Переиспользовать одно TCP-соединение # ~/.ssh/config Host * ControlMaster auto ControlPath ~/.ssh/sockets/%C ControlPersist 10m Замерил на локальном sshd: первое подключение 0.22 секунды, второе и третье — по 0.01. Разница в двадцать раз, и это на loopback, где сети как таковой нет. На реальном канале с задержкой выигрыш будет больше. Каталог ~/.ssh/sockets надо создать заранее, сам он не появится. Не упереться в лимит длины пути Нюанс: %C тут не для красоты. Классический %r@%h:%p на длинных именах хостов выходит за предел, и ssh отказывается работать: ControlPath too long ('/root/.ssh/sockets/xxx... -root@127.0.0.1:2222' >= 108 bytes) Проверил на пути в 109 байт — ровно на границе. %C даёт хеш фиксированной длины и снимает вопрос совсем. Проверить, жив ли мастер ssh -O check user@host Отвечает Master running (pid=924). Пригодится, когда непонятно, идёт ли новая сессия через кеш или поднимает соединение с нуля. Сбросить залипшую сессию ssh -O exit user@host Печатает Exit request sent. и удаляет файл сокета. Нужно, когда на сервере поменялись ключи или конфиг, а мастер держит старую сессию. Нюанс: если мастер-процесс умер не сам, а был убит, файл сокета остаётся сиротой. Прибил мастера через kill -9 — -O check стал отвечать Connection refused, но новое подключение прошло нормально: ssh увидел мёртвый сокет и поднял соединение заново. Честный минус: ноутбук ушёл в сон с активным сокетом — при пробуждении получишь висящую сессию и таймаут вместо мгновенного входа. Лечится тем же -O exit, но сначала надо догадаться, что дело в нём. А вы ControlPersist держите глобально на Host * или включаете точечно? #Linux #SSH #Ansible #DevOps #Terminal
1 083
6
Пробросить TCP через WebSocket мимо DPI и не собрать по дороге утечку сокетов websocat — консольный клиент вебсокетов на Rust, авторства Виталия Шукелы. Соединение начинается с обычного HTTP-рукопожатия Upgrade, поэтому фильтр видит легитимный веб-трафик. Проверял на версии 1.14.0, скачанной статическим бинарником с релизов. Пробросить локальный TCP-порт в вебсокет websocat --binary -E \ tcp-l:127.0.0.1:8080 ws://example.com/socket Нюанс: без -E websocat печатает предупреждение про утечку сокетов при обслуживании нескольких клиентов. У меня оно вылезало на каждом запуске туннеля, с флагом лог чистый. Держать сессию живой на нестабильной сети websocat -t --ping-interval 10 \ - autoreconnect:ws://example.com/socket Нюанс: autoreconnect: требует двух аргументов. Вариант с одним, который ходит по подборкам, падает: Specify ws:// or wss:// URI to connect to a websocket. Первым аргументом идёт источник данных — - для stdin или tcp-l: для туннеля. Проверил разрыв: поднял клиент раньше сервера, в логе Reconnecting failed, процесс жив. Сервер появился — соединение поднялось само. Отправить одно сообщение и выйти echo "get_metrics" | websocat -1 ws://example.com/socket Отправляет ровно один фрейм из stdin и закрывает сессию. Удобно дёргать из скрипта. Локальный эхо-сервер вернул get_metrics и завершился с кодом 0. Пробить туннель на тестовый сервер с самоподписанным TLS websocat -k wss://staging.example.com/socket Флаг -k отключает проверку сертификата. Для стенда годится, дальше стенда — нет: MITM на таком туннеле не отличить от обычной работы. Из полезного при отладке: websocat -t ws-l:127.0.0.1:1234 mirror: поднимает локальный эхо-сервер, на котором можно проверить свою команду, не выходя наружу. Честный минус — синтаксис. Аргументы это цепочки специферов вида overlay:addrtype:address, и с непривычки половина попыток заканчивается Invalid command-line parameters. Плюс инкапсуляция в кадры съедает скорость, а на больших объёмах приходится крутить -B вручную. А чем вы пробиваете туннель, когда наружу открыт только 443? #Linux #websocat #Networking #Tunneling #DevOps
1 315
7
🎥 Вебинар: «Nftables без потери SSH: безопасно настраиваем firewall на удаленном сервере» На открытом уроке разберем, как на
🎥 Вебинар: «Nftables без потери SSH: безопасно настраиваем firewall на удаленном сервере» На открытом уроке разберем, как настроить сетевую фильтрацию на удаленном Linux-сервере и не потерять доступ по SSH. Рассмотрим основные принципы работы nftables, его отличия от привычного iptables, совместимость инструментов и подход к постепенному переходу на новую систему фильтрации трафика. О чем поговорим: — Почему nftables приходит на смену iptables — Как устроена фильтрация сетевого трафика в nf_tables — Как составлять и применять базовые правила firewall — Как менять настройки на удаленном сервере, не потеряв доступ по SSH — Что учитывать при совместимости и переходе с iptables на nftables 🧠 Вебинар приурочен к старту курса «Администратор Linux. Продвинутый уровень». Программа постоянно обновляется с учётом современных требований рынка. Занятия проводят практикующие эксперты, которые ежедневно работают с производственной инфраструктурой. Вы изучите востребованные инструменты: Zabbix, Prometheus, Docker, Nginx, PostgreSQL, ELK, Ansible, SELinux, Bash и многие другие. 👉 Для участия зарегистрируйтесь https://otus.pw/eQjk/ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
1 186
8
Закрыть системные файлы от правки и не получить молча сломанный useradd Запретить правку файла даже руту chattr +i /etc/passwd Нюанс: useradd после этого выдаёт cannot open /etc/passwd и завершается с кодом 0. Пользователь не создаётся, скрипт не падает, мониторинг молчит. Снял атрибут — создался. Разрешить логу только дозапись chattr +a /var/log/secure Нюанс: ротация делается переименованием, а его атрибут не пускает. Запустил logrotate на таком файле: error: failed to rename: Operation not permitted rc=0 Снова ноль на выходе. Файл не ротировался, cron считает, что всё прошло, логи растут до конца места. Найти файлы с SUID и SGID find / -xdev -perm /6000 -type f -ls 2>/dev/null Нюанс: без -xdev поиск по корню вернул ноль файлов и код 1 — захлебнулся на /proc. С ним нашлось 16 штук. Пустой вывод легко принять за чистую систему. Старый синтаксис +6000 GNU find уже не понимает, отвечает invalid mode. Выдать права одному пользователю setfacl -m u:lisa:rw file setfacl -b file Единственное место без подвоха. После первой команды в ls -l появляется плюс: -rw-rw-r--+, после сброса исчезает — по нему и замечают ACL. Поставить наблюдение за файлом auditctl -w /etc/passwd -p wa -k pwd_change Нюанс: правило живёт до перезапуска auditd. Постоянные пишутся в /etc/audit/rules.d/audit.rules. Закрыть входящий трафик, оставшись в сессии iptables -A INPUT -m conntrack \ --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -P INPUT DROP Порядок именно такой: политика последней. iptables -P INPUT DROP первой командой на удалённом сервере обрывает соединение сразу. И два уточнения: -m state до сих пор принимается, но актуален -m conntrack --ctstate, а iptables -V на 24.04 отвечает v1.8.10 (nf_tables) — правила уезжают в nftables. У двух худших находок общее одно: команда не сработала, а код возврата ноль. Мониторингом такое не ловится. А вы chattr +i на боевых конфигах ставите или считаете это ловушкой для самого себя? #Linux #Security #Hardening #iptables #DevOps
1 143
9
Посмотреть, какие интерфейсы подняты, и не принять погасший порт за живой Краткий статус интерфейсов ip -4 -br address show up Нюанс: up фильтрует по состоянию линка, а не по наличию адреса. Погасил eth0 — с ключом он пропал из вывода совсем, без ключа виден как DOWN со всеми адресами на месте. Пустая строка тут не значит «адреса нет». Второй адрес без алиасов вида eth0:1 ip address add 10.0.0.50/24 dev eth0 ip address del 10.0.0.50/24 dev eth0 Второй адрес встаёт рядом с первым, при удалении линк не дёргается. Узнать, куда реально пойдёт пакет ip route get 8.8.8.8 # 8.8.8.8 via 192.0.2.1 dev eth0 src 192.0.2.2 Не читает таблицу, а спрашивает у ядра готовое решение вместе с исходящим адресом. Для локального ответит local 192.0.2.2 dev lo. Увидеть все таблицы маршрутизации ip route show table all Обычный show дал одну строку, table all — шесть, включая local с broadcast и host-маршрутами. С VPN и контейнерами разница уходит в десятки строк. Посмотреть, кто есть в сети рядом ip -4 neigh show ip -6 neigh show Нюанс: ip neigh — не ARP-таблица, как пишут в шпаргалках, а таблица соседей: ARP плюс IPv6 NDP. Без ключа -4 или -6 получишь обе вперемешку. arp -n показывал только первую, отсюда и путаница. Сбросить кэш соседей ip -s -s neigh flush dev eth0 Нюанс: без -s -s команда молчит и отдаёт код 0 — не отличишь «очистил десять записей» от «там было пусто». С ключом печатает удалённые записи и итог *** Round 1, deleting 1 entries ***. Дать интерфейсу второе имя без даунтайма ip link property add dev eth0 altname eno2 altname eno2 появляется в ip link show eth0, и по новому имени интерфейс находится: ip address show dev eno2 отдаёт eth0. Есть с ядра 5.8 и iproute2 5.8, на RHEL 7 синтаксис не разберётся. Всё, что пишет, требует CAP_NET_ADMIN — в контейнере без --cap-add=NET_ADMIN упадёт. А вы ip route get в отладке применяете или сразу лезете в show? #Linux #iproute2 #Networking #DevOps #Debug
1 171
10
Ходовой набор для отладки bash-скрипта известен всем: set -euo pipefail сверху, set -x вокруг мутного места и ловушка DEBUG с read, чтобы останавливаться перед каждой командой. Прогнал этот набор на Ubuntu 24.04, bash 5.2. Три вещи из него ведут себя не так, как ожидаешь. Сначала то, что работает без оговорок: # падаем на ошибке, пустой переменной и в пайпах set -euo pipefail pipefail не декорация: false | true без него даёт код 0, с ним 1. А set -u ловит то, до чего не доберётся проверка синтаксиса: echo "путь: /${UNSET_VAR}/data" # bash: UNSET_VAR: unbound variable Но `set -e` замолкает в условиях. Вызвал функцию через if — код возврата внутри перестал что-либо значить: check() { false; echo "функция продолжила"; } if check; then :; fi # echo выполнился, rc=0 Трассировка. Обычно пишут просто set -x, но дефолтный PS4 печатает голый плюс — в скрипте на 300 строк не поймёшь, где ты: PS4='+ ${BASH_SOURCE}:${LINENO}: ' set -x do_something_risky set +x Теперь в каждой строке трассировки видно файл и номер: + g.sh:4: mkdir -p /tmp/zz Пошаговый режим. Типовой рецепт — функция с read и ловушка DEBUG: dbg() { read -p "$BASH_SOURCE:$LINENO? " _; } trap 'dbg' DEBUG В нём три поломки, и каждая тихая. Первая: $LINENO и $BASH_SOURCE внутри функции указывают на саму функцию. На всех командах печаталось line=3 — строка, где стоит read. Реальные 6 и 7 не появились ни разу. Координаты надо передавать аргументами: dbg() { read -r -p "[$1:$2] $3? " _; } trap 'dbg "$BASH_SOURCE" "$LINENO" "$BASH_COMMAND"' DEBUG Вторая: ловушка не заходит внутрь функций. Без set -T виден только вызов work, а команды в её теле пропадают — как раз там, где обычно и прячется баг. set -T Третья самая злая. read в ловушке читает тот же stdin, что и скрипт. Подал в цикл три строки — дошла одна: printf 'alpha\nbeta\ngamma\n' | bash f.sh получил: beta Две строки съела отладка — отладчик изменил поведение отлаживаемого. Плюс при неинтерактивном stdin приглашение read -p не печатается вовсе, и скрипт молча проносится мимо пауз. Лечится перенаправлением: dbg() { read -r -p "$1? " _ < /dev/tty; } С ним прошли все три строки, паузы работали даже при stdin из /dev/null. И про bash -n, который советуют как «проверку перед запуском». Он про синтаксис и только: незакрытый if поймал с кодом 2, а несуществующую команду и rm -rf /$UNSET_VAR/data пропустил с кодом 0. Прогонял на двух машинах, bash 5.2.21 и 5.2.37 — поведение одинаковое. А вы set -T вообще используете или обходитесь set -x? #Linux #Bash #Debug #DevOps #Автоматизация
1 355
11
🎥 Вебинар: Почему сервер тормозит: первая диагностика Linux для начинающего администратора На открытом уроке разберем, как о
🎥 Вебинар: Почему сервер тормозит: первая диагностика Linux для начинающего администратора На открытом уроке разберем, как определить, из-за чего Linux-сервер начал работать медленнее: процессор, оперативная память, дисковая подсистема или отдельный процесс. Познакомимся с базовыми инструментами мониторинга и посмотрим примеры диагностики проблем производительности. О чем поговорим: — Какие ресурсы сервера чаще всего становятся причиной снижения производительности — Как оценивать состояние системы с помощью top, htop, iotop, sysstat и vmstat — На какие показатели обращать внимание при первичной диагностике — Как последовательно искать источник нагрузки — Примеры разбора типовых проблем на Linux-сервере 🧠 Вебинар приурочен к старту курса «Администратор Linux. Базовый уровень». Вы освоите Bash, TCP/IP, Nginx, Apache, MySQL, Docker, Git, Prometheus, Grafana и ELK. На живых занятиях с практикующими экспертами научитесь настраивать веб-серверы, работать с сетью, контейнерами, мониторингом и фильтрацией трафика. 👉 Для участия зарегистрируйтесь https://otus.pw/D2in/ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
1 331
12
Попалась заметка про reptyr — утилиту, которая забирает уже запущенный процесс в новую сессию терминала. Команды из ходовых инструкций прогнал сам, на двух машинах с Ubuntu 24.04. Ситуация: запустил в ssh дамп базы, а он затянулся. Надо было сразу в tmux, но уже поздно. Сначала отвязываем процесс от текущей оболочки: # Ctrl-Z, потом bg jobs -l disown %1 Вот тут первая шероховатость. В инструкциях пишут disown top, по имени команды. Оно работает, но ровно пока такой job один. Проверил: один sleep снимается нормально, два — ambiguous job spec и выход с кодом 1. Пиши %1 или PID, не имя. Дальше открываем новую сессию в tmux и забираем процесс: # PID берём из вывода jobs -l reptyr 7972 Работает. Прогнал на top из одной tmux-сессии в другую: нулевой дескриптор сменился с /dev/pts/0 на /dev/pts/2, вывод продолжился в новом окне. При этом reptyr напечатал [-] Timed out waiting for child stop. — и всё равно перенёс. Причём это вылезло на обеих машинах и на разных версиях, так что предупреждение можно игнорировать. А вот чего в инструкциях обычно нет. По умолчанию в Debian и Ubuntu kernel.yama.ptrace_scope равен 1: подцепиться можно только к своему потомку. Процесс из старой ssh-сессии новой оболочке не потомок. Запустил от обычного пользователя — получил отказ: Unable to attach to pid 2162: Operation not permitted Дальше reptyr сам подсказывает посмотреть ptrace_scope — за это спасибо автору. Лечится так: cat /proc/sys/kernel/yama/ptrace_scope # 0 — классические правила ptrace sysctl -w kernel.yama.ptrace_scope=0 С нулём тот же скрипт перенёс процесс на /dev/pts/5. Но это ослабление защиты: любой процесс под тем же uid сможет подцепиться к любому другому. Держать так постоянно на боевой машине я бы не стал. Под root, кстати, всё работает и при единице — CAP_SYS_PTRACE обходит yama. Есть флаг -T: крадёт весь терминальный сеанс и по описанию должен выручать, когда у процесса есть дети. Взял конвейер sleep 400 | cat, натравил reptyr -T — и ничего. Ни ошибки, ни переноса: лог пустой, tty прежний. В чём подвох, не разобрался. И про версии. На одной машине приехал reptyr 0.9.0-1, на другой при той же Ubuntu 24.04 — 0.8.0. Флаги в обеих одинаковые, но длинных опций нет ни там, ни там: reptyr --help отвечает invalid option. А вы reptyr вообще применяли в бою или проще перезапустить и не рисковать? #Linux #Bash #tmux #reptyr #DevOps
1 288
13
Чек-лист как проверить софт из чужой подборки На Хабре попалась подборка «Стек российского сисадмина в 2026». Идея хорошая, а вот что с ней делать дальше — вопрос. Такие списки выходят каждый год, и половина позиций в них кочует по инерции. Автор списал у прошлогоднего автора, а проект уже год как не двигается или тихо переехал на несвободную лицензию. Вот шесть проверок, которые снимают вопрос за десять минут. До того, как ты выкатишь это в прод. 1. Паспорт репозитория R=zabbix/zabbix curl -s "https://api.github.com/repos/$R" \ | jq '{pushed_at, archived, license: .license.spdx_id}' Три поля решают почти всё. archived: true — проект заморожен официально, дальше можно не смотреть. 2. Сколько на самом деле прошло с последнего пуша P=$(curl -s "https://api.github.com/repos/$R" \ | jq -r .pushed_at) echo $(( ($(date +%s) - $(date -d "$P" +%s)) / 86400 )) Глазами дату читать бесполезно — «2024-03-11» не выглядит страшно, пока не увидишь рядом число 881. 3. Bus factor S=$(date -u -d '90 days ago' +%Y-%m-%d) curl -s "https://api.github.com/repos/$R/commits\ ?since=$S&per_page=100" \ | jq -r '[.[] | (.author.login // "?")] | group_by(.) | map("\(length) \(.[0])") | .[]' \ | sort -rn | head -5 Если весь список — один ник, проект держится на одном человеке. Это не приговор, но знать надо заранее, а не когда он выгорит. Тут спрятаны грабли, на которые я сам наступил. Без скобок вокруг .author.login // "?" конвейер молча теряет коммиты, у которых автор не привязан к аккаунту GitHub. На макете из пяти коммитов jq вернул четыре. Оператор `//` в jq применяется ко всему потоку, а не к каждому элементу — скобки обязательны. 4. Лицензия В первом же запросе смотри на spdx_id. Значение NOASSERTION означает, что GitHub не смог сопоставить файл лицензии ни с одной стандартной. Чаще всего это BSL, SSPL или самописный текст с ограничениями на коммерческое использование. Открывай LICENSE руками. 5. Есть ли пакет в репах твоего дистрибутива for p in netdata zabbix-server-pgsql; do v=$(apt-cache madison "$p" 2>/dev/null | head -1) printf '%-22s %s\n' "$p" "${v:-НЕТ В РЕПАХ}" done Проверял на Ubuntu 24.04: netdata нашёлся в noble/universe, zabbix-server-pgsql — нет, ставить придётся из репозитория вендора. Отдельная засада: apt-cache madison и apt-cache policy возвращают код 0, даже когда пакета не существует, просто печатают пустоту. Конструкция apt-cache policy X || echo "нет" не сработает никогда — проверяй пустоту переменной, как выше. 6. Помни про лимит Анонимно GitHub API даёт 60 запросов в час на IP, и на общем адресе они кончаются мгновенно — я на этом словил 403 посреди проверки. С персональным токеном лимит 5000: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/rate_limit | jq .rate Честный минус метода: API показывает активность, а не качество. Проект может коммитить каждый день и при этом быть непригодным, а может годами лежать без изменений, потому что он просто дописан. Так что это фильтр первого уровня, а не вердикт. #Linux #DevOps #GitHub #jq #Чеклист
1 354
14
🔬 Дали root и разрешили ломать. Сервис, который я хотел создать Постоянные читатели знают, что у меня есть бот @gradeliftbot, в котором больше 200 задач по Linux. Работает он просто: кусок лога и вопрос по нему. Песочницы нет вообще. Всё скатывается в механику заданий вопрос-ответ. Кейсы генерит нейросеть, и местами это заметно, хотя там содержится достаточно много материала, чего стоит только полный гайд от Docker на 1195 страниц и 8500 страниц с командами Linux и их подробным описанием. Изначально идея была создать песочницу с заданиями, где нужно было выполнять задания, но я так и не смог придумать, как адаптировать её под мобильный формат Telegram-бота. Поэтому получилась очень упрощённая версия от изначальной идеи. На днях наткнулся на izzylab.ru — тренажёр по Linux и DevOps, где терминал живёт прямо в браузере. Открыл первую задачу «создай пользователя john» и вместо useradd набрал разведку. Интереснее было понять, куда меня пустили и насколько там можно наглеть. uname -r; nproc; free -m | head -2 id; sudo -n true; echo $? 4.19.0-gvisor, 2 ядра, 256 МБ, uid=0. Под тобой не хост и не виртуалка, а gVisor — юзерспейсное ядро от Google, которое перехватывает системные вызовы и разбирает их само. Отсюда и щедрость: тебе спокойно дают root и разрешают крушить систему, потому что до настоящего ядра ты всё равно не дотянешься. У каждой задачи свой контейнер, сброс откатывает всё начисто. Больше всего я боялся увидеть чекер, который сверяет введённую строку с эталоном. Проверил в лоб. Задание «закодируй /root/data.bin в base64» решил не той утилитой: openssl base64 -A -in /root/data.bin \ -out /root/data.b64 Засчитано, хотя штатный base64 ломает вывод каждые 76 символов, а openssl -A пишет одной строкой. Проверка смотрит на результат, а не на способ. Обмануть тоже не вышло: подложил валидный base64 от постороннего текста — поймал и написал, какой критерий не сошёлся, решение при этом не выдал. На момент, когда я смотрел сервис, уже было 437 заданий, что значительно больше чем в @gradeliftbot. 87 лёгких, 276 средних, 74 сложных. Разбивка не самая ожидаемая — Git 39, регулярки 30, скрипты 29, SQLite 25, Kubernetes 20, диагностика 20. Redis и Postgres поднимаются руками и отвечают, apt install работает, сеть наружу есть. А дальше пошли находки, ради которых стоило лезть. ss -s возвращает get_sockstat: No such file or directory, при этом ip -br a работает нормально. Причина в netlink: gVisor держит NETLINK_ROUTE, но не NETLINK_SOCK_DIAG, на котором стоит ss. Я сам писал «netstat мёртв, бери ss» — вот вам среда, где канон переворачивается. Со strace то же самое, только тоньше. Запуск программы под трейсом работает, а attach к чужому PID — нет: ptrace(PTRACE_SEIZE, 261): Operation not permitted PTRACE_TRACEME есть, PTRACE_SEIZE нет. Ещё ping даёт 100% потерь, а curl https://ya.ru возвращает 302 — ICMP не проброшен, TCP ходит. Я такие штуки люблю: за час разведки узнал про gVisor больше, чем за все статьи о нём. Теперь честно. Если вы хотите просто научиться внимательно читать логи, что важно на собесах или когда за кем-то исправляешь ошибки, тогда подходит @gradeliftbot. А если цель — именно практика в живом терминале, то формат izzylab.ru на мой взгляд, подходит лучше. Что скажете насчёт идеи живой песочницы в браузере телефона? Тут в MAX ботов разрешили создавать самозанятым, можно будет попробовать перенести бота из телеги в MAX. #Linux #DevOps #gVisor #strace #Практика
1 522
15
🎥 Вебинар: Kubernetes + CI/CD + GitOps — делаем стабильный деплой без выхода из кластера 📌 На уроке вы узнаете: - Как настр
🎥 Вебинар: Kubernetes + CI/CD + GitOps — делаем стабильный деплой без выхода из кластера 📌 На уроке вы узнаете: - Как настроить конвейер CI/CD для автоматизации развертывания приложений в Kubernetes. - Что такое GitOps, и как с его помощью управлять инфраструктурой и релизами через декларативные манифесты. - Использование Kubernetes для построения стабильных и безопасных процессов развёртывания приложений. - Лучшие практики внедрения, внедрения и управления изменениями прямо из кластера. 🎯 После вебинара вы: - Вы поймёте, как интегрировать Kubernetes, CI/CD и GitOps для создания стабильных и автоматизированных процессов развертывания. - Освоите изменение и оптимизацию конвейеров CI/CD для работы в Kubernetes-кластерах. - Изучите подходы к мониторингу, организации тестирования и управлению релизами через GitOps, повышению доступности и безопасности процессов. ⚠️ Открытый урок проходит в преддверии старта курса «Инфраструктурная платформа на основе Kubernetes». 👉 Для участия зарегистрируйтесь: https://vk.cc/d0aUej Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
1 546
16
🩹 Прогнал 10 популярных регулярок. Четыре врут Салют, дежурный по проду. Попалась подборка «10 регулярок для админа» — та самая, что кочует по всем каналам. Вместо того чтобы репостнуть, прогнал её в песочнице: Ubuntu 24.04, GNU grep 3.11, GNU sed 4.9. Четыре пункта из десяти работают не так, как обещает комментарий рядом. Поиск IP ловит версию ядра grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' file.log На моём тестовом логе выдал 5.15.0.91 (версия ядра), 999.999.999.999 и 1.2.3.4 — откушенный кусок от 1.2.3.4.5. Октеты не проверяются, границы тоже. -w не спасает: точка не словесный символ. grep -oP '(?<![\d.])((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\ \.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?![\d.])' file.log Мусор ушёл. Цена — -P, а это PCRE, на BSD-grep не заработает. Пустые строки удаляются не все sed -i '/^$/d' file.txt ^$ — это строка нулевой длины. Строка из трёх пробелов останется, строка с табом останется. Проверил через cat -A. Правильно так: # сначала посмотреть, что уйдёт sed -n '/^[[:space:]]*$/p' file.txt # и только потом править, с бэкапом sed -i.bak -E '/^[[:space:]]*$/d' file.txt -i без .bak переписывает файл на месте. Один раз ошибёшься с шаблоном — восстанавливать неоткуда. URL глотает всё до пробела grep -Eo 'https?://[^ ]+' file.txt На строке см. (http://foo.org/x) и "https://bar.io/y" вернул адреса вместе со скобкой и кавычкой. А в строке с табуляцией утащил ещё и следующее слово — таб это не пробел. grep -Eo 'https?://[^[:space:]<>"()]+[^[:space:]<>"(),.;:]' \ file.txt .{100,} — это сто и больше Комментарий обещает «длиннее 100 символов», регулярка ловит и ровно стошную. Плюс зависит от локали: строка из 60 кириллических букв под LC_ALL=C считается длинной (120 байт), под UTF-8 — нет. Проверил обе, результат разный. Если нужны символы и строго больше — берите awk 'length($0) > 100'. По мелочи: ^# не видит комментарии с отступом, -v 'ERROR' выкидывает строки со словом NOERROR, а \s в седьмом пункте — GNU-расширение, на macOS и busybox отвалится, там нужен [[:space:]]. Регулярки для email и извлечения доменов, кстати, оказались нормальными. Придираться не к чему. Забирайте исправленный набор в закладки — пригодится, когда в три часа ночи будете грепать чужой лог. #Linux #Bash #grep #sed #regex #DevOps
1 622
17
🔍Тестовое собеседование с Head of DevOps уже завтра 4 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собесед
🔍Тестовое собеседование с Head of DevOps уже завтра 4 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle DevOps-разработчика. Как это будет: 📂 Александр Хренников, Head of DevOps в KTS с опытом 14+ лет, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Александр будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Александру Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для DevOps-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_devops_bot Реклама. О рекламодателе.
1 773
18
🧨 Ты ищешь в strace open() — а его там нет Полез за выжимкой по strace в свою базу конспектов, получил бодрый совет: фильтруй по -e trace=open,openat, увидишь, где программа ищет конфиг. Решил проверить перед постом. Ubuntu 24.04, strace 6.8. Не увидел ничего. Подопытный — скрипт, который проверяет конфиг через test -f: # фильтр из конспекта strace -f -e trace=open,openat ./finder.sh \ | grep myapp # пусто # весь файловый класс strace -f -e trace=%file ./finder.sh | grep myapp # newfstatat(AT_FDCWD, "/etc/myapp/config.ini", # 0x7ffc0f32bee0, 0) = -1 ENOENT Программе незачем открывать файл, чтобы понять, что его нет. Она зовёт newfstatat, и фильтр по open его срезает. Фильтр отрезает ровно то, ради чего ты запускал strace. Заодно: open( в выводе cat — 0 вхождений, openat( — 3. glibc на x86_64 давно ходит через openat. Искать в трейсе open() бессмысленно. Рабочий вариант # -Z печатает только вызовы, вернувшие ошибку strace -f -Z -e trace=%file \ -o /tmp/t.log ./myapp grep -E 'ENOENT|EACCES' /tmp/t.log -o тут не для красоты. Без него 2>&1 | grep смешает трейс с выводом самого приложения, у меня в грепнутый поток прилетело cat: /nonexistent: No such file от подопытного. Если процесс уже крутится PID=$(systemctl show -p MainPID --value nginx) sudo strace -f -Z -e trace=%file -p $PID Честно: эту связку я проверял только по документации, systemd-хоста под рукой не было. Синтаксис --value живёт с systemd 230. Что читать в ошибках ▪️ ENOENT — такого пути нет ▪️ EACCES — нет прав на файл или каталог ▪️ ENOTDIR — в середине пути не каталог ▪️ ELOOP — symlink закольцевался Половина «config not found» в проде — это EACCES, а не отсутствие файла. Грабли: -Z появился в strace 5.2 от 12 июля 2019. На старом RHEL 7 со strace 4.12 его нет, там остаётся grep по ENOENT. В контейнере нужен --cap-add=SYS_PTRACE. И трейс тормозит процесс в разы — на живом сервисе цепляйся коротко. А вы чем ловите такие вещи — strace, ltrace или сразу lsof -p? #Linux #strace #DevOps #Debug #SRE
1 517
19
🧨 Ты ищешь в strace open() — а его там нет Полез за выжимкой по strace в свою базу конспектов, получил бодрый совет: фильтруй по -e trace=open,openat, увидишь, где программа ищет конфиг. Решил проверить перед постом. Ubuntu 24.04, strace 6.8. Не увидел ничего. Подопытный — скрипт, который проверяет конфиг через test -f: # фильтр из конспекта strace -f -e trace=open,openat ./finder.sh \ | grep myapp # пусто # весь файловый класс strace -f -e trace=%file ./finder.sh | grep myapp # newfstatat(AT_FDCWD, "/etc/myapp/config.ini", # 0x7ffc0f32bee0, 0) = -1 ENOENT Программе незачем открывать файл, чтобы понять, что его нет. Она зовёт newfstatat, и фильтр по open его срезает. Фильтр отрезает ровно то, ради чего ты запускал strace. Заодно: open( в выводе cat — 0 вхождений, openat( — 3. glibc на x86_64 давно ходит через openat. Искать в трейсе open() бессмысленно. Рабочий вариант # -Z печатает только вызовы, вернувшие ошибку strace -f -Z -e trace=%file \ -o /tmp/t.log ./myapp grep -E 'ENOENT|EACCES' /tmp/t.log -o тут не для красоты. Без него 2>&1 | grep смешает трейс с выводом самого приложения, у меня в грепнутый поток прилетело cat: /nonexistent: No such file от подопытного. Если процесс уже крутится PID=$(systemctl show -p MainPID --value nginx) sudo strace -f -Z -e trace=%file -p $PID Честно: эту связку я проверял только по документации, systemd-хоста под рукой не было. Синтаксис --value живёт с systemd 230. Что читать в ошибках ▪️ ENOENT — такого пути нет ▪️ EACCES — нет прав на файл или каталог ▪️ ENOTDIR — в середине пути не каталог ▪️ ELOOP — symlink закольцевался Половина «config not found» в проде — это EACCES, а не отсутствие файла. Грабли: -Z появился в strace 5.2 от 12 июля 2019. На старом RHEL 7 со strace 4.12 его нет, там остаётся grep по ENOENT. В контейнере нужен --cap-add=SYS_PTRACE. И трейс тормозит процесс в разы — на живом сервисе цепляйся коротко. А вы чем ловите такие вещи — strace, ltrace или сразу lsof -p? #Linux #strace #DevOps #Debug #SRE
1
20
💀 Процесс намертво завис в проде? Ставим диагноз без kill -9 Если сервис перестал отвечать, рука сама тянется к kill -9. Но перезапуск вслепую не решает проблему — он уничтожает контекст, и сбой повторится. Показываю, как заглянуть внутрь зависшего приложения на лету и поставить точный диагноз, не останавливая процесс. Базовая диагностика зависания # 1. Находим PID проблемного процесса по имени. pidof my_process # 2. Подключаемся к процессу на лету и слушаем ввод-вывод. # -t добавит таймстампы: видно, КОГДА процесс замер. sudo strace -tt -p <PID> -e trace=read,write Расширенный мониторинг дескрипторов # 3. Отслеживаем ВСЕ файловые операции. # ВАЖНО: не 'open', а группа %file — современный glibc зовёт openat(), а не open(), # поэтому одиночный 'open' почти ничего не покажет. %file ловит open, openat, stat, access. sudo strace -p <PID> -e trace=read,write,%file # Если ждёшь именно сетевую блокировку (отвалившаяся БД, зависший сокет): sudo strace -p <PID> -e trace=%net Анализ блокировки (Read Blocking) # 4. Если вывод strace замирает на строке вида: # read(5, # — процесс жив, но ждёт данных в дескриптор №5. # Отключаемся (Ctrl+C НЕ убьёт процесс) и смотрим, что это за дескриптор: sudo lsof -p <PID> -a -d 5 # Быстрая альтернатива без lsof — прямо из /proc: sudo ls -l /proc/<PID>/fd/5 Такой подход превращает абстрактное «оно зависло» в понятную картину: процесс может просто ждать read() из сокета из-за отвалившейся БД или недоступного пайпа, а не находиться в deadlock. Диагноз без правки кода и простоя на рестарт. ❗️❗️❗️ Нравится формат? Ставь 👍 👉 Рубрика: #шпаргалка@LinuxSkill #Linux #Strace #Troubleshooting #DevOps #SysAdmin
1 808