Bash Days | Linux | DevOps
Авторский блог от действующего девопса Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу. Автор: Роман Шубин Реклама: @maxgrue MAX: https://max.ru/bashdays Курс: @tormozilla_bot Блог: https://bashdays.ru
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام Bash Days | Linux | DevOps
تُعد قناة Bash Days | Linux | DevOps (@bashdays) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 23 738 مشتركاً، محتلاً المرتبة 5 559 في فئة التكنولوجيات والتطبيقات والمرتبة 27 925 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 23 738 مشتركاً.
بحسب آخر البيانات بتاريخ 01 أغسطس, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار 2، وفي آخر 24 ساعة بمقدار -5، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 21.76%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 12.80% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 5 165 مشاهدة. وخلال اليوم الأول يجمع عادةً 3 037 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 23.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل bashdays, linux, bash, docker, скрипт.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“Авторский блог от действующего девопса
Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.
Автор: Роман Шубин
Реклама: @maxgrue
MAX: https://max.ru/bashdays
Курс: @tormozilla_bot
Блог: https://bashdays.r...”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 02 أغسطس, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
limit_req_zone, он то нам и пригодится. Этот параметр ограничивает количество одновременных запросов с одного айпишника.
Поехали настраивать.
Создаем файл /etc/nginx/conf.d/assholes.conf
geo $limited {
default 1;
192.168.1.1 0; # Этот IP не лимитируется
10.0.0.0/24 0; # 10.0.0.0/24 тоже без ограничений
}
map $limited $limit {
1 $binary_remote_addr;
0 "";
}
limit_req_zone $limit zone=bashdays:20m rate=200r/s;
limit_req_zone - ключ для отслеживания запросов.
$binary_remote_addr - системная переменная nginx, внутри хранит ip адрес клиента.
zone=bashdays:20m - произвольное имя зоны, 20m это объём памяти в мегабайтах для хранения данных. В этой зоне хранятся данные о количестве запросов от каждого уникального клиента.
rate=200r/s - ограничение равное 200 запросов в секунды с одного ip клиента.
Для рейта есть такая табличка:
Сценарий rate burst ------------------------------------------- API с высокой нагрузкой 100r/s 200 Средний веб-сайт 50r/s 100 Анти-DDoS защита 10r/s 20 CDN или кеширующий прокси 500r/s 1000тестируем так:
ab -n 1000 -c 50 http://bashdays.ru/
wrk -t4 -c100 -d10s http://bashdays.ru/
И смотрим нет ли ошибок 503 Слишком дохуя запросов и корректно ли отрабатывает лимит.
🅰️🅰️
Сука! А как рассчитать эту 20m памяти? Щаа…
Максимальное количество клиентов = размер зоны в байтах / размерзаписинаклиентаПардон, хуйню сморозил, давай на котиках:
Пример расчёта для 20m (20 мегабайт = 20 × 1024 × 1024 = 20 971 520 байт): 20 971 520 / 128 = 163 840То есть, зона
20m может хранить лимиты примерно для 163 тысяч уникальных клиентов одновременно.
А откуда взялось 128?
Как я написал выше nginx хранит каждого уникального клиента (ключ $binary_remote_addr или другое значение) в зоне, используя примерно 128 байт на запись.
Есть такая табличка:
< 20 000 = 4m ~80 000 = 10m ~160 000 = 20m 500 000+ = 64mДа, еще можно настроить
burst для резких пиков. burst позволяет временно превышать rate, прежде чем включится жёсткий лимит.
Например:
limit_req zone=bashdays burst=400 nodelay;
Клиенту разрешается до 400 мгновенных запросов, а затем он попадает в ограничение 200r/s.
nodelay означает, что первые 400 запросов проходят сразу, а потом начинается строгий лимит.
Теперь по мапингам и гео хуйне.
В первом блоке про гео:
1. Все пользователи получат $limited = 1 (по умолчанию).
2. Те, кто с 192.168.1.1 или из 10.0.0.0/24, получат $limited = 0 и не будут ограничены.
Во втором блоке про мапинг:
1. Если $limited = 1, то $limit = $binary_remote_addr (IP-адрес клиента).
2. Если $limited = 0, то $limit = "", и клиент не попадает в limit_req_zone.
Короче делаем что-то вроде белого списка и кто в него не входит — идёт нахуй! Надеюсь понятно объяснил.
Теперь чтобы вся эта поебота заработала, нужно прописать в нужный локейшен:
location / {
limit_req zone=bashdays burst=10 nodelay;
try_files $uri $uri/ /index.php?$args;
}
Про burst и nodelay выше уже рассказывал.Ну а чтобы отдавать нужный статус при достижении лимита, делаем:
location / {
limit_req_status 429;
limit_req zone=bashdays burst=10 nodelay;
try_files $uri $uri/ /index.php?$args;
}
Возвращаем 429 Слишком дохуя запросов, вместо стандартного 503.
Бездумно это настраивать не советую, могут пострадать обычные пользователи, а вот если всё вдумчиво сделать — спасешь свой стартап от злых писек.
➡️ Ну и сыпь в комменты свои варианты!
tags: #nginx #devops #security
—
🔔 @bashdays➡️ @gitgateЧто прикольно — можно выполнять команды из файлов. Нахуячил инструкций в файл, скормил этой тулзе, запустил. Вуаля!Ни циклов тебе, ни ансиблов, для быстрых манипуляций — сгодится. Написан на змеях. В коробке много еще всяких фишек, посмотри на досуге ради интереса, авось в хозяйстве сгодится. ➡️ Проект на гитхабе Заявлена поддержка винды, маков, хуяков. tags: #linux #utils — 🔔 @bashdays➡️ @gitgate
tar -czvf bashdays.tar.gz /etc
На выходе получаем годный bashdays.tar.gz. Теперь нужно проверить, что этот архив действительно годный и случайно не побился.
Для этого запускаем:
tar -tzf bashdays.tar.gz
Ключ «t» как раз и запускает необходимый тест. Если все хорошо, то команда вернет статус: echo $? ага выдаёт 0. Отлично!
Теперь ломаем архив:
truncate -s -10 bashdays.tar.gz
И после проверки получаем:
tar -tzf bashdays.tar.gz
gzip: stdin: unexpected end of file
tar: Child returned status 1
tar: Error is not recoverable: exiting now
А echo $? ага выдаёт 2. Ага. Зная это ты можешь тестировать архивы без распаковки и затем заливать их например в s3.
Еще можно протестировать так:
gzip -t bashdays.tar.gz
Ну или банально распаковать в дев/нуль:
tar -xzf bashdays.tar.gz -O > /dev/null
Bash скрипт для проверки может выглядеть так:
#!/bin/bash
# Проверяем, передан ли аргумент
if [ $# -ne 1 ]; then
echo "Использование: $0 <файл архива>"
exit 1
fi
ARCHIVE="$1"
# Проверяем, существует ли файл
if [ ! -f "$ARCHIVE" ]; then
echo "Ошибка: файл '$ARCHIVE' не найден!"
exit 2
fi
# Определяем тип архива
if [[ "$ARCHIVE" == *.tar.gz || "$ARCHIVE" == *.tgz ]]; then
echo "Архив '$ARCHIVE' определён как tar.gz"
FORMAT="tar.gz"
elif [[ "$ARCHIVE" == *.tar ]]; then
echo "Архив '$ARCHIVE' определён как tar"
FORMAT="tar"
else
echo "Ошибка: неподдерживаемый формат архива!"
exit 3
fi
# Проверяем целостность архива
echo "Проверка содержимого архива..."
if ! tar -tzf "$ARCHIVE" &>/dev/null; then
echo "Ошибка: tar.gz архив повреждён!"
exit 4
fi
if [[ "$FORMAT" == "tar.gz" ]]; then
echo "Дополнительная проверка gzip..."
if ! gzip -t "$ARCHIVE" &>/dev/null; then
echo "Ошибка: gzip-архив повреждён!"
exit 5
fi
fi
echo "Архив '$ARCHIVE' проверен: ошибок не обнаружено."
exit 0
Чмодим и запускаем:
chmod +x check_tar.sh
./check_tar.sh bashdays.tar.gz
Такие дела.
Чуть позже покажу какие есть способы проверять целостность архивов которые ты заливаешь в s3. Очень полезно это проверять в рамках бекапов, когда локально оно у тебя все хорошо, а в s3 все нахуй битое-побитое лежит.
tags: #linux #bash
—
🔔 @bashdays➡️ @gitgateРеклама. ООО «Отус онлайн-образование», ОГРН 1177746618576Макс, 35 лет, ищет работу, в меру упитанный мужчина, обладатель сокровенных знаний, закрыл ящик Пандоры, забрал душу у Шанг Тсунга, прыгал из самолета без парашюта, горел, делал сам себе искусственное дыхание. Опыт ёпта! - Девопс ин де хаус - Программист на yaml - Широчайшие познания в aws - Пайпы, ансиблы, докеры и вся байда - Сети, роутинг, фаерволы - Опыт работы в иностранных компаниях - Часовой пояс? Наверное похуй! - Linux, мониторинг, golang, java, bash…Можно бесконечно это описывать, короче уверенный стек и скиллы выживания в айти за спиной. Макс прошел LF и по его скиллам скажу так — моё почтение, снимаю шляпу! Работа на максимальный результат. Было бы у меня 150к я бы без раздумий забрал его кубы
#/bin/bash
declare -x PATH="/usr/local/bin:/usr/bin:/bin"
declare -i JOB_NUM=$(nproc)
declare DELAY=0.5
exec >&2
for i in {1..50};do # это цикл по всем заданиям
# это команда, выполняемая в фоне
( sleep $(($SRANDOM % 3 +1)); echo ${SECONDS}_sec ) &
while [[ $(jobs -r -p |wc -l) -ge $JOB_NUM ]];do
sleep $DELAY
echo $i
done
done
echo end loop
wait
echo TOTAL $SECONDS sec
Ну, и небольшая пояснялка:
nproc - число "ядер"
DELAY - задержка между проверками окончания выполнения фоновых заданий. Если задание выполняется долго (проверка архива) - можно смело ставить 10-30 секунд.
exec >&2 перенаправили весь вывод на stderr. В реалном скрипте можно убрать. (Как и все echo).
for - основной цикл по списку всех заданий.
sleep $(($SRANDOM % 3 +1)) - собственно фоновое задание. В данном случае пауза 1-3 сек.
echo ${SECONDS}_sec - ввел для примера, чтобы показать, что команд в фоновом задании может быть несколько.
while - как только запустили нужное число фоновых заданий, начинаем ждать окончания одного или нескольких.
echo end loop - как только основной цикл закончился - скрипт можно завершать (но некоторые задания еще могут долго работать).
wait - ожидать окончания всех фоновых заданий.
echo TOTAL $SECONDS sec - время полного выполнения скрипта.
На данный момент все задания завершены. Можно отправлять лог.
man nproc wc help exec jobs waittags: #linux #bash — 🔔 @bashdays➡️ @gitgate
ssh -p2222 user@server
Охуеть как удобно! Ты скажешь - дак можно же в ~/.ssh/config все это прописать и всё вернуть на свои места.
Host bashdays.ru
HostName bashdays.ru
User user
IdentityFile ~/.ssh/shuba
Port 2222
Справедливо. Но зачем жертвовать своим удобством?
У тебя на серверах уже отключен вход по паролю, только ключи, рут тоже запрещен.
Пусть эти писька-боты долбятся и дальше в жопы. Накрайняк воткни fail2ban и устрой им веселую жизу.
Да и боты сейчас умные, если они видят закрытый 22 порт, они сделают nmap -Pn, по итогу получат твой 2222 и продолжат долбиться.
Как не прячься, все равно тебя найдут и насрут в логи.
Получается все манипуляции с портом это бесполезные телодвижения в ущерб удобства.
Соблюдай базовые правила безопасности и всё с твоими серверами будет хорошо.
- отключи вход по паролю - перейди на ssh ключи - запрети вход для рутаЗа всю свою практику я встретил только одну компанию, где меняли 22 порт на какой-то другой, но никакой смысловой нагрузки в этом не было. Так и так эту компанию подломили и спиздили базу данных. Да, еще был компания, где 22 порт открывался через port knocking. То есть нужно было предварительно стукнуться на 3 определенных порта и если последовательность была соблюдена, то открывался 22 порт. Ну тоже такое себе решение в ущерб удобства. Любят люди из пушки по воробьям стрелять. Это как в жизни — мойте руки перед едой. Если соблюдаешь этот базовый принцип, то повышаешь шансы, что твой организм не хакнет кишечная палочка. Такие дела, изучай! tags: #devops #ssh #linuxfactory #security — 🔔 @bashdays➡️ @gitgate
Порой возникает ситуация, когда какой-нибудь раннер отказывается клонировать репу и начинает орать на доступы.Ты проверяешь, видишь в табличке «Заголовок» — gitlab-runner-1 и вроде всё хорошо, ключ прописан и в раннере его приватная часть есть. Чо за хуйня? Тут нам и пригодится команда:
ssh-keygen -l -E md5 -f ~/.ssh/id_rsa
Выполняем ее для ключа с которым подключаемся (работает и для приватной и публичной части одинаково).
И по итогу видим фингерпринт, отпечаток:
2048 MD5:03:62:23:ca:ce:1b:8c:ad:60:1f:66:16:05:43:d8:a7 shuba@server (RSA)
Сравниваем этот отпечаток с тем что прописан в гитлабе/гитхабе и видим что он НЕ совпадает.
А это значит что твой раннер использует не тот приватный ключ для подключения.Фиксим и радуемся. Как фиксить? Прописать актуальную публичную часть ключа в гитлаб/гитхаб. Дело закрыто. tags: #git #devops #ssh #linuxfactory — 🔔 @bashdays➡️ @gitgate
crane cp gcr.io/shlyapa-project/executor:v1.7.0-debug myharbor.ru/shlyapa-executor:v1.7.0-debug
Эта команда скопирует образ executor:v1.7.0-debug из реестра gcr.io в ваш собственный реджистри myharbor.ru.
Просмотр содержимого образа:
Иногда хочется заглянуть внутрь образа и посмотреть, что там внутри.
С crane это проще простого:
crane export executor - | tar -tvf - | less
Здесь мы экспортируем файловую систему образа executor и просматриваем список файлов с помощью команды tar.
Извлечение конкретного файла из образа:
Нужно достать нужный файл из образа? Легко!
crane export executor - | tar -Oxf - etc/passwd
Эта команда извлечет файл passwd из директории etc образа executor и выведет его содержимое.
Сравнение конфигураций двух версий образа:
Хотите узнать, чем отличаются конфигурации двух версий одного образа? Пожалуйста:
diff <(crane config front:1.32 | jq) <(crane config front:1.33 | jq)
Здесь мы сравниваем конфигурации версий 1.32 и 1.33 образа front с помощью утилиты diff.
Получение размера образа:
Интересно, сколько весит ваш образ? Вот как это узнать:
crane manifest gcr.io/buildpacks/builder:v1 | jq '.config.size + ([.layers[].size] | add)'
Эта команда выводит суммарный размер конфигурации и всех слоев образа.
Изменение меток и аннотаций образа:
Вы можете добавлять или изменять метки и аннотации в существующем образе без необходимости его повторной сборки:
crane mutate myharbor.ru/shlyapa-project/bear_ass_image:tag --annotation "org.opencontainers.image.description=New description" --label "version=2.0"
Эта команда добавит или обновит аннотацию и метку в указанном образе.
Также можно доложить tarbar (архивы .tar .tar.gz .tgz), добавить тэг (удобнее чем в дефолтном докер клиенте), задать другой entrypoint и т.д.
И это ещё не всё)
Но это чем я пользую практически регулярно. + это 1 бинарь (на любимой многими GOшечке) что позволяет спокойно его использовать и в системах автосборки и упростить взаимодействие с контейнерам.
tags: #utilites #devops
—
🔔 @bashdays➡️ @gitgate/etc/sshd/) руками и просто откатываешь, то что ты там закомментировал.
Ладно, предположим у тебя есть доступ к руту и ты зашел на сервер.
Запускай команду:
tail -f /var/log/auth.log
Теперь открывай другой терминал и пробуй подключиться по ключам. После того как ты это сделал, возвращайся в терминал где запускал tail и внимательно смотри что тебе пишут.
В 100% там будет ошибка, которая элементарно гуглится. Обычно это просто проблемы с правами на файл ~/.ssh/authorized_keys или папку ~/.ssh/.
Но бывают и другие приколы, например ты используешь не тот ключ или вообще без ключа подключаешься.
Распространенные ошибки:
Invalid user
bad ownership or modes for /home/<username>/.ssh
Authentication failed
Connection closed by remote host
Permission denied
Too many authentication failures
Connection refused
PAM authentication errors
User not allowed
Host key verification failed
SSH protocol mismatch
Banner errors
Brute-force attempts
Timeout
Subsystem errors
Resource temporarily unavailable
Не ссым читать логи и находить нужное. А как только нашел что-то вменяемое — гуглим или скармливаем GPT (как ты любишь).
Кстати китайцы тут DeepSeek запустили, мол убийца GPT. Бесплатная и работает в РФ без приколов. Домашку ребенку решать милое дело.tags: #git #devops #ssh #linuxfactory — 🔔 @bashdays➡️ @gitgate
Первая часть Вторая частьКак научиться договариваться. Часть 3. ㅤ На встречах нужно постоянно быть в фокусе чувств. То есть надо обращать внимание на сколько тебе хуева и на сколько хуево твоему собеседнику. Это очень важная переменная в переговорах. Если ты или собеседник начнете примерять на себя пиджак жертвы, вся твоя охуеть важная встреча заведет прямиком коту в жопу. И ничо хорошего с этого естественно не получится. Ты пострадавший, он пострадавший, включается защитная реакция и вы оба идëте нахуй. А тот кто пострадавший, всегда будет бычить в ответ на все более-менее разумные закидоны. Ты такое сразу почувствуешь, вроде все правильно говоришь, а в ответ получаешь негативное сморкание. Поэтому и надо быть начеку, заранее просекая настроение и чувства твоего собеседника. Как ты читаешь чувства Прикинь простую ситуацию: Шараёбишься ты с женой по магазинам, проходишь мимо прилавка с пивом и такой — бля, надо пивка взять. Потом смотришь на жену и думаешь — тааааккк, полчаса назад я не купил ей сапоги, она в хуевом настроении, взять сейчас пивка без последствий будет пиздец проблематично. Чо делать? Надо купить ей сапоги, а потом взять пивка. Что важно в этом примере 1. Ты прочитал эмоции жены (жена пиздец злая без сапог) 2. Проанализировал ситуацию (если взять пиво, будет больно) 3. Нашел компромисс (купил сапоги) 4. Снял с жены пиджак жертвы (жена пиздец добрая с сапогами) 5. Добился своего без последствий (взял пива, все счастливы) Взрослые ведут себя так-же как и дети. Не купили игрушку, начинают выебываться. Вот и с тобой также, не повысили зарплату, начал хуева работать. Работодатель жертва и ты сука жертва, у всех проблемы. А что нужно было сделать? Правильно! Прочитать, проанализировать чувства и затем ёбнуть именно так, чтобы и ЗП тебе подняли и директор твой понял зачем он поднимает тебе ЗП. Не должно быть никакого негатива, гнева, злости. Каждая сторона должна остаться с мыслью, что все сделано правильно. Не должно быть сомнений! Как-то так, продолжение следует. tags: #рабочиебудни #memories — 🔔 @bashdays➡️ @gitgate
