LinuxSkill - Сводки с прода и Шпаргалки
Следим за новостями 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.
Data loading in progress...
| Date | Subscriber Growth | Mentions | Channels | |
| 31 August | 0 | |||
| 30 August | 0 | |||
| 29 August | 0 | |||
| 28 August | 0 | |||
| 27 August | 0 | |||
| 26 August | 0 | |||
| 25 August | 0 | |||
| 24 August | +2 | |||
| 23 August | 0 | |||
| 22 August | 0 | |||
| 21 August | +1 | |||
| 20 August | +1 | |||
| 19 August | +1 | |||
| 18 August | 0 | |||
| 17 August | +3 | |||
| 16 August | +1 | |||
| 15 August | 0 | |||
| 14 August | +1 | |||
| 13 August | 0 | |||
| 12 August | 0 | |||
| 11 August | 0 | |||
| 10 August | 0 | |||
| 09 August | 0 | |||
| 08 August | 0 | |||
| 07 August | 0 | |||
| 06 August | 0 | |||
| 05 August | 0 | |||
| 04 August | 0 | |||
| 03 August | +1 | |||
| 02 August | 0 | |||
| 01 August | 0 |
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, проверку доступности сервиса и принцип работы обратного прокси.
О чем поговорим:
— Из каких сервисов состоит базовая конфигурация веб-сервера
— Чем отличаются задачи 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 на удаленном сервере»
На открытом уроке разберем, как настроить сетевую фильтрацию на удаленном 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-сервер начал работать медленнее: процессор, оперативная память, дисковая подсистема или отдельный процесс. Познакомимся с базовыми инструментами мониторинга и посмотрим примеры диагностики проблем производительности.
О чем поговорим:
— Какие ресурсы сервера чаще всего становятся причиной снижения производительности
— Как оценивать состояние системы с помощью 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 — делаем стабильный деплой без выхода из кластера
📌 На уроке вы узнаете:
- Как настроить конвейер 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 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на 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 |
