Bash Days | Linux | DevOps
23.3K subscribers
152 photos
25 videos
664 links
Авторский канал от действующего девопса

Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.

Автор: Роман Шубин
Реклама: @maxgrue

MAX: https://max.ru/bashdays

Курс: @tormozilla_bot
Блог: https://bashdays.ru
Download Telegram
День вчера был такой длинный, жаркий, и от начала до конца полная х%йня, каждую минуту. Год как-то стремительно начался в плане объема задач. Привет!

А жиза заключается в том, что кто-то бездумно пишет говнокод, а кто-то этот говнокод вынужден дебажить. Доказывая что проблема не на сервере, а в кривых руках разработчика.

Вот и вчера. Ситуация: какой-то php скрипт при создании файла на диске, выставляет корявые права на этот файл. Грубо говоря, нужно поставить 777, а у файла права по факту 01411. Конечно, проблема в сервере! Пусть дядя Рома с этим разбирается. Ладно, за монету и корку хлеба можно и покопаться.

Блин, как я давно с php дел не имел. Пришлось вспоминать всю эту лапшу с ООП.

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

<?php

chmod('test.txt', '777');

?>


Для простоты восприятия, адаптировал под наши с вами реалии. Вроде всё корректно, тошноты пока нет. Чо этой собаке надо? Запускаю скрипт, хм… снова получаю вместо 777 какую-то фигню 01411.

А если уберем кавычки? Вдруг это как string воспринимается:

<?php

chmod('test.txt', 777);

?>


Метод тыка не помог, но терпим до последнего. В документацию по chmod в php не лезем. Нас же НЕ просили исправить баг, нас поставили перед фактом — проблемы на сервере. Вот мы и пытаемся доказать обратное.

Расчехляем strace

strace php app.php


В самом конце видим:

read(3, "<?php\n\nchmod('test.txt', 777);\n\n"..., 4096) = 35
chmod("test.txt", 01411) = 0


Видим знакомое 01411. Доказательства собрали. С серверами всё хорошо, на лицо баг в коде. Несем эту информацию тимлиду, пусть учит разработчика читать документацию и дает ему по шапке.

А что все-таки не так с php скриптом, почему 01411? Вообще это не наше дело. Но если коротко:

В php целые числа могут быть указаны в десятичной, шестнадцатеричной, восьмеричной или двоичной системе. Все это дело должно обозначаться начальным нулем. Наша тема - восьмеричная система. Если перевести 777 в восьмеричную систему получим как раз 1411.

📌А откуда берется 01 перед 1411?? А давай ты сам подумаешь и в комментариях напишешь. А мы тебе дружно лайк поставим.

Ошибка была в том, что в php скрипте число 777 передается как строка. Неважно в скобках оно или нет.

Фикс тут простой, просто вставляем 0 перед 777:

<?php

chmod('test.txt', 0777);

?>


Ну а если хочется без ведущего нуля, то так:

<?php

chmod('test.txt', intval('777', 8));

?>


Вот такие пироги. Можно было бы продолжить метод тыка и вставить сразу 0 перед 777, но повторюсь — нас не просили ничего багфиксить. Не нужно упрощать кому-то работу, это опыт, который ты воруешь у человека.

Пусть лучше лишние полчаса погуглит, посмотрит, зато самостоятельно заполнит свою дофаминоваю яму. И потешет ЭГО новой победой над багом.

Ладно, увидимся, давай!

tags: #linux #debug #рабочиебудни

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
223
Привет, далеко ходить не будем, сегодня более интересный кейс с отладкой php-fpm который непонятным образом, рандомно вставал раком. Да, будем использовать наш любимый strace, как ты любишь.

Проблема: На сервере крутится php-fpm, в любой момент времени процесс начинает зависать, то есть перестаёт обрабатывать любые запросы.

В какой-то момент может очухаться, а может и нет. В любом случае проблема решается перезапуском systemctl restart php-fpm. Ну и в логах ничего криминального нет, даже в дебаг режиме. По факту имеем пятьсот две плохих шлюхи (502 Bad Gateway).

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

До этого были перепробованы все возможные варианты с конфигом, накручивание буферов, гугление, даже грешили на nginx, но ничего не помогало.

Так и жили пока дядя Рома не соизволил разобраться в ситуации, ну и разобрался.

Расчехляем strace

Для начала ты должен знать, что php использует модель master/slave. Главный процесс использует воркеры (workers) для обработки входящих запросов. Запрос может выполниться на любом из воркеров, поэтому нужно сказать strace чтобы мониторил все воркеры. Для этого будем использовать связку с командой pidof ну и приправим это sed’ом.

strace -f $(pidof php-fpm | sed 's/\([0-9]*\)/\-p \1/g') -epoll


Sed обрезает лишнюю херню и оставляет только pid в голом виде, ну и затем эти пиды закидываем в strace.

А после запуска команды и зависания php, я увидел такое:

[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)
[pid 1234] poll([{fd=10 ...]) = 0 (Timeout)


Ага, уже есть с чем работать. Какой-то таймаут. И файловый дескриптор fd=10. Хм. Теперь надо понять, что это за таймаут и дескриптор fd=10. Для этого сделаем так:

lsof -p 1234


Эта команда выдаст список всех файлов, которые открыты процессом, включая сокеты.

php 0u IPv4 13193 0t0 TCP :8000 (LISTEN)
php 1u CHR 1,4 0t0 4728 /dev/null
php 2u CHR 1,4 0t0 4728 /dev/null
php 3ur REG /tmp/.RedPem.Hte (deleted)
php 4u IPv4 TCP :8000->:5042 (ESTABLISHED)
php 5uW REG sessions/sess_tmh0dls75
php 6u 0000 0,9 0 4842 anon_inode
php 7u unix 0t0 25714 socket
php 8u unix 0t0 25714 socket
php 9u TCP l->l:11210 (ESTABLISHED)
php 10u TCP host->10.0.0.100:9200 (SYN_SENT)


Смотрим самую последнюю строку как раз с fd=10. Видим что у нас проблема с подключением к 10.0.0.100:9200. Очень интересно. Что это вообще за айпишник такой.

Не останавливаемся и копаем дальше.

В большинстве случае порт 9200 принадлежит ElasticSearch. Роем в эту сторону и обнаруживаем, что в php проекте используется библиотека ElasticSearch PHP.

Как оказалось, при разработке проекта, прекрасные девы подключили ElasticSearch, чтобы чото там отлавливать. А на айпишнике 10.0.0.100 как раз располагалась серверная часть ElasticSearch. Разработку прекратили, сервер с эластиком убили, но из конфигов проекта забыли выкосить.

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

Такие дела. Я прям уверен — если пройтись с помощью strace по всяким популярным php движкам, там столько дерьма вылезет. Кстати с помощью strace можно вполне удачно разгонять проекты, банально фиксишь то, что вызывает таймауты.

Порой наталкивался на ситуацию когда проект тормозил из-за корявого резолва доменов, или были проблемы с таймзоной, аналогично всё это дебажилось через strace.

В общем изучай и бери на вооружение, опыт полезный. Увидимся!

tags: #linux #debug #рабочиебудни

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
268
Всем привет. Пока тут боролся с багом, решил поделиться и с вами. Сегодня рассмотрим как без curl/wget/telnet делать tcp/udp запросы. Опять же мало кто про это знает.

Порой бывает что на серверах нет курла, вегета (как приправа с упоротым поваром) и даже пинга. Например в docker контейнерах. И установить никак. Но в bash скрипте или во время дебага надо протестировать приложение, службу или порт.

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

Я обычно при дебаге использую telnet, чтобы проверить открыт ли нужный порт на удаленной тачке. Чтобы понимать, что никакой фаервол меня не блокирует. Почему telnet? Привычка!

Проверяем открыт ли порт 80 и 443:

:> /dev/tcp/bashdayz.ru/80
:> /dev/tcp/bashdayz.ru/443


Если порт открыт, то после выполнения команды на экран ничего не выведется. Но ты в праве получить статус через echo $?. Если вернулся 0 значит порт открыт и все ок. Если вернулось > 0, то пизда рулю, порт закрыт.

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

timeout 5s bash -c ':> /dev/tcp/bashdayz.ru/80'
timeout 5s bash -c ':> /dev/tcp/bashdayz.ru/443'


Теперь в случае если порт не доступен, мне не нужно ждать 100500 часов пока команда завершится. Все станет известно спустя 5 секунд. Повторюсь, что на экран никакого вывода не будет. Статус получаем через echo $?, ну ты понял.

А что означает этот непонятный символ «:>»?

Нет, это не смайлик с дятлом. Это сокращенная версия true:

true > /dev/tcp/bashdayz.ru/80


true - команда, которая всегда возвращает успешный (нулевой) код возврата. Это означает, что команда завершилась успешно, без ошибок.

Чтобы весь этот фокус работал, требуется bash с поддержкой net-redirections (--enable-net-redirections), но как показывает практика такая функция в 99% включена по умолчанию, если конечно ты не адепт gentoo и из исходников bash собирал.

Аналогично можно слать udp запросы:

:> /dev/udp/localhost/8888


То есть синтаксис простой: /dev/протокол/хост/порт

Давай еще пример покажу как с NIST Time Server получить актуальную дату и время с разных NTP:

cat </dev/tcp/time.nist.gov/13
cat </dev/tcp/time.cloudflare.com/13
cat </dev/tcp/time.windows.com/13
cat </dev/tcp/pool.ntp.org/13
cat </dev/tcp/time.google.com/13
cat </dev/tcp/time.apple.com/13
cat </dev/tcp/time.nrc.ca/13
cat </dev/tcp/time.windows.com/13


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

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

nc -zv bashdayz.ru 80


Тут оно на экран тебе результат сразу вывалит без всяких костылей.

nc или netcat - утилита, которая предоставляет возможность взаимодействия с сетью. Она может выполнять различные функции, такие как установка TCP или UDP соединений, передача данных между хостами, сканирование портов, создание простых серверов и т.п.

Ключ -z тестирует порт без передачи данных, а ключ -v логично что verbose (подробная инфа).

Да, ты скажешь можно же через nmap это все сделать, да, справедливо. Но я показываю как не пользоваться сторонними утилитами и получить желаемое с помощью bash. Пардон за nc, но не мог его не упомянуть.

Пользуйся, обязательно пригодится в работе и дебаге. Увидимся!

tags: #linux #debug #bash #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
220
Привет. Вчера в моём ДЗЕНе задали вопрос - Роман, а как скачать файл не имея под рукой curl/wget, а прям средствами bash? Видимо придется тему продолжить. Сегодня рассмотрим как такое осуществить.

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

Накидываем скрипт

#!/bin/bash

host="files.bashdayz.ru"
port="80"
path="/files/test.zip"

request="GET $path HTTP/1.1
Host: $host
Connection: close"

exec 3<>/dev/tcp/$host/$port
echo -e "$request" >&3
cat <&3 > test.zip
exec 3>&-

echo "Success"


Тут все просто:

1. Задаем переменные, хост, порт, путь до файла
2. Проставляем необходимые заголовки для запроса
3. Ну и собственно скачиваем файл на диск

Теперь разберем третий пункт подробнее. С виду какой-то ужас, но не ссы, ща расскажу.

В первой строчке открывается файловый дескриптор с индексом 3 для чтения и записи данных через TCP-соединение + хост + порт.

Во второй строчке отправляем HTTP запрос на сервер через открытое соединение с дескриптором 3. Включаем в него GET запрос и необходимые заголовки.

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

Последняя строка закрывает файловый дескриптор 3 (сокет) после завершения операции чтения данных. Можно не закрывать и оставить портал в ад открытым.

Ну и все. Файл скачали, получили Success!

Почему я выбрал файловый дескриптор с индексом 3? Ну вообще 0 = stdin, 1 = stdout, 2 = stderr. Короче 0, 1, 2 зарезервированы, а я просто взял следующий.

Но вообще в манах bash рекомендуют быть осторожным в использовании дескрипторов больше 9ти. Так как возможен конфликт с дескрипторами, которые используются внутри оболочки.

К сожалению для https такое провернуть не получится, возникнут проблемы. Прямой обмен данными через сокеты не предусматривают обработку SSL/TLS.

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

В общем не болей, увидимся!

tags: #linux #bash #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
187
Я тут выше заикнулся про Дзен. Ну дак вот, если у тебя есть учетка в Яндексе или ВК, буду безумно рад если поддержишь мои начинания и нажмешь кнопку - подписаться. Не обязательно его потом там читать, всё самое сочное всегда будет тут. А я тебе котиков, лайк и интересного чтива!

Да, там есть цензура. Приходится контент немного адаптировать. Неприличного авторского слога и игр с летающими Bash письками, там уже не найдешь. 👨‍🦲 Все по взрослому.

Ну и в конце февраля-марте запланировал пилотный запуск моих бесплатных видео-уроков на тему Advanced Bash Scripting + Debug Factory. С задачками, домашними заданиями и экзаменами. Пока пробую снимать, нихрена не получается, но сделаю всё возможное. Запуск будет именно в Дзене, а дальше уже посмотрим, как пойдет.

В общем заранее всем спасибо, всем краба, всем обнимашек!
Please open Telegram to view this post
VIEW IN TELEGRAM
176
Привет. Порой из консоли необходимо быстренько узнать свой внешний айпишник. Например, накрутил какой-нибудь VPN, а графической оболочки нет, чтобы зайти на сайт и визуально глянуть где сегодня находится моя жопа.

Да и в bash скриптах иногда хочется без длинных команд и тонны кода обойтись. Короче как говорит, все уже придумано за нас. А если еще и алиасы накрутить, вай вай, пэрсик.

Я пользуюсь двумя сервисами:

curl ifconfig.me
curl geofind.me


Первый выдаст чисто айпишник, который ты сможешь загнать в переменную и потом его использовать.

Второй помимо айпишника, вычислит местоположение.

94.227.165.240
International Ltd
Ulitsa Pushkina, Dom Kolotushkina, Austria


Второй вариант использую намного реже. Так как привык всё усложнять, сначала получаю ip через ifconfig.me, а потом уже через whois <ip>.

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

Альтернативы:

curl ipinfo.io/ip
curl ipecho.net/plain
curl icanhazip.com
curl ident.me
curl api64.ipify.org
curl api.ip.sb/ip
curl ipv4.wtfismyip.com/text
curl ip2location.io/ip
curl checkip.amazonaws.com


С дополнительной инфой:

curl ip-api.com/line
curl ipinfo.io
curl api.myip.com
curl 'api.ipregistry.co/?key=tryout'


В списке с «дополнительной инфой» есть сервисы которые прям богатый JSON выплёвывают, потыкай.

Я раньше обладал безлимитным API ключом для MaxMind, вот там да, был полный фарш. Можно было по IP узнавать вплоть до названия организации. Даже софтину в бородатые 2000е писал, которая пользовалась популярностью у пентестеров.

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

curl -H "Authorization: KEY" https://geoip.maxmind.com/geoip/v2.1/city/me


Ааа, еще вариант с дигом есть, но оно длинное:

dig +short myip.opendns.com @resolver1.opendns.com


Есть и минусы. Результат зависит от доступности сервисов. Если сервис выплюнет соплю > 200, увы все поломается.

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

Ладно, сегодня еще увидимся, далеко не уходи. Хорошего дня!

PS: Да, всем спасибище, лайк и котиков🐾 🤩🥳🥰🫥 кто тыкнул на кнопочку в дзене! Вы супер, обнял!

tags: #linux #bash #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
193
Поднимал тут у себя огородик с wg-easy, всё ок. Но из коробки, морда для создания ключей работает по протоколу http. Вроде ничего страшного, но не серьезно. Ну и настраивать nginx + acme.sh тоже капец лень.

Пока искал готовое решение (кстати нашел нативный мануал от wg-easy), набрел на интересную штуку. Называется Nginx Proxy Manager.

Короче это морда для nginx, чтобы не руками конфиг задрачивать, а мышкой галочки натыкивать + из коробки нативная интеграция с letsencrypt.

Возможно у нас в чатике где-то это уже и пролетало, но я не видал.

Поднимается за минуту через docker-compose, без лишних велосипедов и костылей. Дружит с sqlite и mysql. Есть система распределения прав, каждый юзер может редактировать свои локейшены и хосты. Поддерживает малину и arm архитектуры. Ну и естественно есть гибкий Access List и Basic Auth.

Киллер-фича: Можно генерить wildcard ssl, выбираешь из большого выпадающего списка к примеру cloudflare и оно тебе DNS Challenge делает. Это прям порадовало.

Понятно дело, что оно не максимально гибкое в плане конфигурации через морду. Но для этого есть дырка, чтобы вставлять свои куски конфига в текстовом формате. А так базового функционала прям за глаза.

В общем рекомендую как для локальной разработки, так и для каких-то своих сервисов вроде bitwarden и т.п.

Картинки у них на сайте посмотрите, не буду сюда запихивать.

🌐 https://nginxproxymanager.com/

tags: #nginx #services

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
98
Привет. Глазом не успел моргнуть как выходные вылетели в трубу. Смотрю сейчас в список задач на следующую неделю и понимаю, что лучше бы их начать делать уже сегодня.

Ладно, это детали. Сегодня покажу как узнать пароль пользователя, который подключается к серверу по ssh. Менять пароль я не буду, это не тру вэй. Я воспользуюсь своим любимым strace.

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

Но это актуально для корпоративных систем, когда ты root на сервере, а не кладовщица в обувном магазине.

Короче идем рутом на сервер и расчехляем strace

strace -f -p $(pgrep -o sshd) -o /tmp/passwd.txt -v -e trace=write -s 64


Запускаем и собираем урожай в файл passwd.txt. Работает так:

1. -f = следим за всеми процессами sshd (мастер и дочерние)
2. -p = ищем все PID sshd процессов
3. -o = файл куда пишем результаты
4. -v = пишем подробности
5. -e = триггеримся только на запись данных
6. -s = ограничиваем вывод данных 64 байтами (меньше мусора)

Теперь, когда какой-нибудь пользователь авторизуется на сервере по ssh, в файл passwd.txt в открытом виде будет записан его актуальный пароль.

Выглядит это так:

1088 write(5,"\0\0\0\5oleg", 9) = 9
1088 write(5, "\0\0\0\Barmaley1982", 17) = 17


Логин oleg, пароль Barmaley1982. Дело в шляпе. Этакий сниффер на коленке с помощью коробочных инструментов. Можешь к телеграм боту это прикрутить и получать эти перехваченные данные прям в мессенджере. Как это сделать писал тут.

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

Такие дела. Ну и как там пишут:

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

Давай, увидимся!

tags: #linux #bash #debug #security

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
225
Привет. Сегодня покажу как на wsl хитро вкорячить свежую версию ubuntu 23 или 24. Так как в коробке идет только старенькая 22, придется немного потыкать в консольке.

Зачем это нужно? Ну например проверить какие-то штуки, которых нет в ubuntu 22. А для чего мне это понадобилось, я напишу в следующем посте, как раз одно на другое наложилось. Если спойлернуть: писал пост про софтину, но она работает только с новыми версиями убунты. Вот и пришлось немного переобуться.

По bash версиям имеем такое:

22.04 - 5.1.16
23.04 - 5.2.16
24.04 - 5.2.21


Так, есть несколько способов вкорячить свежую убунту в wsl.

Хитрожопый способ с docker

Заходим в wsl убунты 22 и ставим docker если он у тебя еще не стоит.

curl -sSL https://get.docker.com | sh
usermod -aG docker $(whoami)


WSL DETECTED: We recommend using Docker Desktop for Windows.

Оно грязно выругается, но ждем 20 секунд и установка завершиться успехом

Перезапускаем сессию чтобы пользователь смог работать с docker.

Дальше тащим образ ubuntu:lunar, как раз это версия 23.04. Аналогично можешь и другие версии/разновидности дистрибутива на wsl вкорячивать. Все что есть в docker можно поднять в wsl.

docker pull ubuntu:lunar


Запускаем контейнер и выходим из него

docker run -it --name ubuntu23 ubuntu:lunar
exit


Проверяем что контейнер есть:

docker ps -a


Экспортируем

docker export ubuntu23 > /tmp/ubuntu23.tar


В папке /tmp появился tar размером где-то 75 мегабайт. Уже хорошо. Теперь на хостовой с виндой создаем папку. Я сделал ее на диске D: и назвал так D:\\wsl\\ubuntu23

Теперь копируем этот tar на хостовую машину с виндой в папку D:\\wsl\\ubuntu23.

Переходим в powershell и импортируем tar:

wsl --import ubuntu23 D:\wsl\ubuntu23\ D:\wsl\ubuntu23\ubuntu23.tar


В папке D:\\wsl\\ubuntu23 появится новый файл: ext4.vhdx размером около 150 мегабайт. Так, дальше…

Смотрим что у нас есть, в powershell:

wsl -l -v


На экран вываливается примерно такое:

PS C:\Users\user> wsl -l -v

NAME STATE VERSION
* Ubuntu-22.04 Running 2
ubuntu23 Stopped 2


Собственно на этом всё. Запускаем lunar:

wsl -d ubuntu23


Всё!

Второй способ. Сделать dist-upgrade уже существующей убунты:

sudo sed 's/lts/normal/g' /etc/update-manager/release-upgrades
sudo sed -i `s/jammy/lunar/g` /etc/apt/sources.list
sudo apt update
sudo apt upgrade
sudo apt dist-upgrade


Хотя апргрейд крайняя мера, когда 22.04 уже не нужна. А мне нужна! Пока не знаю зачем, но пусть будет.

Третий и самый простой.

Поставить Ubuntu (Preview) по этой ссылке прям с магазина микрософта. Кликнул и последняя убунта у тебя в wsl.

В моём случае сразу прилетел Release: 24.04 Codename: noble. Через docker конечно интереснее, есть какая-то прозрачность и контроль.

А так, как я ленивая жопа, я предпочел поставить Ubuntu Preview. Но способ с docker я конечно пощупал и поставил 23 версию. Теперь имею зоопарк 22, 23, 24, думаю для экспериментов вполне хватит.

Да, когда ставишь через docker, оно автоматически пропишется в Windows Terminal и потом всю эту кухню можно запускать кликом мыши, без ввода wsl -d.

Вот и все. Чуть позже закину пост как раз про ту самую софтину, которая хочет работать только на свежих линуксах. Увидимся!

tags: #linux #windows

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
74
Ладно, хорош про винду, ловите еще чтива. Выше в посте когда ставил docker, вылез алерт «WSL DETECTED: We recommend using Docker Desktop for Windows.»

Меня заинтересовал таймер обратного отсчета, который выводился на экране, мол через 20 секунд всё будет ок. Цифры менялись затирая предыдущие, но с нюансом, оставался ведущий ноль.

Ну и чот захотелось на Bash’е такое запилить, ну и запилил:

#!/bin/bash

msg="deadline in: "
row=2
col=2

clear
tput cup $row $col
echo -n "$msg"
tput civis

l=${#msg}
l=$(( l + col ))

for i in {10..01}
do
tput cup $row $l
echo -n "$i"
sleep 1
done

tput cnorm


Запускаем, еее! Пошел отсчет от 10 до 01 с ведущим нулем. Прекрасно!

Из непонятного, рассказываю:

1. tput cup $row $col = ставим курсор в нужную позицию
2. tput civis - скрываем курсор
3. l=${#msg} - вычисляем длину сроки msg
4. l=$(( l + col )) - позиция вывода таймера
5. tput cup $row $l - кидаем курсор в позицию таймера
6. tput cnorm - включаем курсор обратно

Вариант без ведущего нуля:

#!/bin/bash

seconds=10

for ((i=seconds; i>=1; i--))
do
echo -ne "deadline in: $i \033[0K\r"
sleep 1
done

echo -e "\nFuck up!"


Но этот вариант мне не нравится, нет в нем искры, если жать Enter, то таймер перескакивает на новую строку, ну и ведущего нуля нет, фу.

Вот такая игрушка у меня получилась. Возможно где-нибудь и воткну потом эту поделку, попугать коллег на продакшене. Пусть не расслабляются, запуская бездумно Bash скрипты. Надо еще клавиатуру блокировать. Чем бы дитя не тешилось.

Ладно, кидай в комментарии свои варианты, заценим!

tags: #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
101
Я тут чет плотно подсел на игрушку Metroid, вроде обычная бродилка, но прям какая-то атмосферная. Прохожу сейчас по вечерам Zero Mission на GBA, ну как прохожу, брожу по карте и в дырки тыкаюсь. Хоть немного отвлекает от рутины.

Давай по теме. Ща будет интересно. Смотри, когда ты выполняешь команду ls -l, оно выводит тебе на экран список каталогов и файлов. Все это цветное и красивое. Но если сделать так:

ls -l | cat


То по итогу получим просто список каталогов и файлов, без навешанных стилей и красок. Серое и унылое. Куда делись управляющие символы (последовательности), которые всё это раскрашивают?

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

Все предельно просто. В утилитах содержится проверка своего стандартного вывода (stdout), которая не использует некоторые управляющие символы, если stdout не связан с терминалом.

И это вполне логично. Если бы эти управляющие символы передавались следующей команде, в моем случае в cat. То cat бы получил на вход помимо данных, кучу мусора, типа такого:

\e[31mBashdays\e[0m


Теперь полезем в кишки, чтобы лучше понять происходящее.

Запускаем strace:

strace -o output.txt -yf ls -l --color=auto | cat


Тут я указал утилите ls опцию color с аргументом auto. В большинстве случаев из коробки идет alias в котором уже прописана эта опция. Но так, как мы запускаем ls через strace, то существующие алиасы не будут использоваться. Вот лишь по этому и запихиваем все это в одну строку.

-y = отслеживать открытие файлов.
-f = отслеживать все процессы и форки.
-o = пишем выхлоп strace в файл.

Открываем файл output.txt и смотрим в него пустым взглядом. Но лучше грепаем вызов ioctl:

grep -i "ioctl" output.txt


Получаем несколько строк, в которых видим ошибку:

-1 ENOTTY (Inappropriate ioctl for device)


Это говорит о том, что процесс попытался выполнить операцию ввода-вывода (I/O), которая не поддерживается устройством. Канал просто не поддерживает эту возможность.

Ну и напоследок сделаем инъекцию. В этом посте можешь еще один пример с инъекцией глянуть. Запускаем:

strace -o /dev/null -fe inject=ioctl:retval=0 ls -l --color=auto | cat -v


Суть такая, если возникает ошибка, то ничего не делаем, а продолжаем работу. Эмулируем ситуацию, когда ioctl вернул статус успеха, а не -1 ENOTTY.

Опция retval=значение, это своего рода фильтр, в моем контексте он будет трассировать только системные вызовы ioctl у которых статус = не успех.

Запустили. Команда отработала, на экране видим список каталогов и файлов с управляющими символами (последовательностями).

drwxr-xr-x ^[[0m^[[01;34m1^[[0m
-rwxr-xr-x ^[[01;32mbash^[[0m
drwxr-xr-x ^[[01;34mbin^[[0m
drwxr-xr-x ^[[01;34mnginx^[[0m


Что и следовало доказать. Ну а если просто хочется протестировать управляющие символы без всяких strace, можно воспользоваться аргументом always и ключом -v для cat.

ls --color=always | cat -v


-v, --show-nonprinting

Вот так вот и живем. Теперь и ты это знаешь. На выходные обещаю уйти в режим тишины, чтобы вам не надоедать своими сумасшедшими исследованиями. Хорошего всем дня, увидимся!

tags: #linux #debug #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
123
Сегодня вынужденно весь день работал инженером электроником. Три компьютера собрал, винду накатил, дату перенес, господи, как это выматывает. Я лучше ELK лишний раз настрою, чем всё это железо разгребать, стар я для этого дерьма стал.

Ну и тут одно событие как-то вскользь прошло и связано оно с нативным файловым менеджером «FAR» который теперь можно без лишнего геморроя поставить на новые линуксы прям из официального репозитория.

Да, когда я начинал свой путь в айти, FAR был как правая рука для окошечников. Все активно призывали пересесть на total commander, но сколько я не делал попыток, так и не смог себя пересилить. Ну люблю я все эти консольные штуки и минимализм.

У меня знакомый большую часть жизни вообще в FAR фронтенд делал, плагинами обвешал и получилась неплохая IDE.

А вот когда я начал знакомство с linux, то второе, что я запустил (после vi), это был как раз midnight commander. Ну и все. FAR и mc стали маст-хэв штуками. Вот даже сейчас сидя на винде у меня вкорячен FAR и я даже раза два в месяц им пользуюсь.

Мой роадмеп был такой - Norton commander → Dos navigator → FAR → Midnight commander.

Короче в новых убунтах ставится так:

sudo apt install far2l


Кому подойдет FAR? Все просто, тому, кому не нравится midnight commander.

Я попробовал ради прикола воткнуть его на 23ю убунту (в wsl), взлетело, выглядит как FAR, даже alt+f1 работает для выбора дисков. Ну и по ssh запускается, в смысле подключаешься к серверу по ssh и запускаешь там FAR, работает.

Не знаю, но я уже точно ни на что не променяю Midnight commander. Даже в винде его использую. Мы связаны одной цепью.

А какой у тебя был путь с файловыми менеджерами? Чем нынче пользуешь?

tags: #рабочиебудни #utils #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
79
Привет и с пятницей господа и дамы! Отсматривал сегодня очередные домашние Bash задания своих студентов ну и собрал для вас самые распространенные велосипеды, которые в 99% повторяются.

Оно конечно работает правильно. Но бывалый глаз сразу ощутит жопный дискомфорт глядя на такие конструкции.

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


Поехали!

cat bashdays.txt | cut -f 2 -d ';'


В текстовом файле bashdays.txt у меня забита строка: hello;world. Далее команда cat читает этот файл и перенаправляет данные на утилиту cut с помощью pipe «|». А cut уже режет строку по символу «;» и отдает мне второй элемент. То есть на выходе я получу: «world».

Но. Утилита cut сама умеет читать файлы. Проще говоря так:

cut -f 2 -d ';' bashdays.txt


Сюда можно приплести и grep, с которым обычно делают так:

cat bashdays.txt | grep "world"


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

grep "world" bashdays.txt


Ну и к примеру еще такое встречается часто:

cat bashdays.txt | tr 'a-z' 'A-Z'


Суть одна, cat передает данные в tr, а дальше они конвертятся в верхний регистр и выводятся на экран. По хорошему это было бы так:

tr 'a-z' 'A-Z' < bashdays.txt


Но опять же для кого по-хорошему? Мне привычнее вариант с cat, хз, переучиваться я уж точно не буду.

А еще из любимого, это циклы, ща покажу:

for s in $(ls)  
do
echo "$s"
done


Это цикл, который перебирает файлы. Тут вообще зачем-то используется вызов внешней утилиты ls, хотя она тут вообще не упёрлась. Да и если такое использовать в скриптах, вылезут баги.

Например, создай такой файл:

touch "*"


И заново запусти этот цикл. ООйой… заметил прикол? Вывод продублировал все имена файлов. Вот тебе и баг, а потом сиди полдня, думай, что же оно не работает.

Этот костыль можно и перекостылисть, указав утилите ls параметр -Q. Тогда утилита ls тепло обнимет кавычками все имена файлов. Но это лишние кавычки, потом их чо? Снова обрезать?

Правильнее было бы так:

for s in ./*; do echo "$s"; done


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

Перлов конечно много встречается, но это прям основные. Если что-то еще экстренно вспомню, закину в комментарии. Ну либо ты закидывай, мы всегда рады твоей активности!

Обещал на выходные тебя не беспокоить, но видимо не получится. Так, что увидимся совсем скоро. Хороших тебе предстоящих выходных и береги себя!

tags: #bash #кодревью

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
168
В гугол картинках было найдено такое изображение 👆 на которой запечатлена занимательная закономерность. Если сложить все эти числа, то получится обычное число 42. Ну число и число…

echo $((7 + 14 + 21))


Ну дак вот, со времен появления проекта GNU (GNU's Not Unix) это число имело для них какой-то потаённый смысл.

К примеру, если в редакторе vi/vim ввести:

:help 42


То на мы увидим нечто странное:

Вelection, the selection will be used unmodified. When there is a selection
but you click outside of it, the selection is removed.

There is a separate popup menu for each mode. Thus there are never grey
items like in the normal menus.

What is the meaning of life, the universe and everything? 42
Douglas Adams, the only person who knew what this question really was about is
now dead, unfortunately. So now you might wonder what the meaning of death
is...

Next chapter: usr_43.txt Using filetypes
Copyright: see manual-copyright vim:tw=78:ts=8:noet:ft=help:norl:


Но это всего лишь цитата из книги английского писателя Дугласа Адамса «Автостопом по галактике». Где супер компьютер Deep Thought дал ответ на главный вопрос жизни, вселенной и всего остального. И этот ответ был 42.

В документации к редактору emacs также встречается это число, вот пару примеров:

This situation is best understood in the context of converting text properties during `write-region`. For example, the character at position 42 in a buffer is ‘X’ with a text property `foo`. If the conversion for `foo` is done by inserting into the buffer, say, ‘FOO:’, then that changes the character at position 42 from ‘X’ to ‘F’. The next conversion will start with the wrong data straight away.


`ssh` can also take extra parameters as port numbers. For example, a host on port 42 is specified as host#42 (the real host name, a hash sign, then a port number). It is the same as passing ‘-p 42’ to the `ssh` command.


Кроличья нора? Не думаю, книга «Автостопом по галактике» вышла в 1979 году, а ГНУтые появились в 1983 году.

Все логично, число 42 стало символом для сообщества фанатов научной фантастики и часто упоминается в шутках и широко используется в поп-культуре.

Существует теория заговора, называемая «42-ой теорией заговора», которая исходит из идеи, что число 42 имеет глубокий смысл или тайное значение, скрытое правительствами или другими могущественными организациями.

Хотя такие теории заговора могут быть увлекательными, важно отметить, что число 42 не обладает никаким таинственным или сверхъестественным значением в реальном мире. Оно просто является элементом фольклора, шуток и культурных отсылок, и не имеет каких-либо серьезных конспирологических подоплек.

Так что, так… дело закрыто...

А ты читал/смотрел «Автостопом по галактике»?


tags:
#linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
141
Всем добрый. Сегодня замусолим про zero bytes. Скорее всего тут единицы про это знают и слышали, значит самое время. Будет интересно и познавательно, рекомендую почитать.

Термин Zero bytes / Magic zero bytes / Нулевые байты в Linux обычно относят к специальному значению байт 0x00, которое может использоваться для различных целей в контексте файловой системы и прочего.

Так, стоп, ничо не понятно и даже не интересно. Давай сразу на котиках, погнали в нашу лабораторию. Запускаем:

read < /dev/zero


Этой командой я читаю нулевые байты с помощью read. По дефолту read читает стандартный ввод. Передаем на стандартный ввод магические нули из устройства /dev/zero и генерим нулевые байты. Прекратить это безобразие можно комбинацией: CTRL+C

Вообще /dev/zero это фиктивный файл, который используется для создания файлов, заполненных нулями. А зачем он нужен? Ну например, чтобы отформатировать диск и забить его нулями, чтобы потом никто не смог восстановить данные которые ты удалил. Ну и для экспериментов всяких.

Так, теперь по нашей команде. Запустили, ничего не происходит. Но на самом деле происходит следующее: Оболочка с помощью системного вызова read читает в свой буфер нулевые байты из /dev/zero. Затем буфер обрабатывается по одному символу, а затем символы помещаются в массив.

Содержимое этого массива будет присвоено переменной заданной при запуске read. По умолчанию эта переменная называется REPLY. То есть если в read не передать название переменной, то все что ты введешь в нее, очутится в переменной REPLY.

read
echo "Ты ввел: $REPLY"


Вернемся к нашей бесконечной команде, которую запустили в начале поста. Команда так и будет выполняться, так как хочет встретить разделитель строк NL-ASCII или New Line ASCII. Новая строка или «\n».

А новой строки, то нет. Одни нулевые байты, а эти байты пропускаются. Ну и так, как оболочка не может найти конец строки, получается бесконечный цикл.

Есть такая штука, называется C-string

C-string - последовательность символов в языке Cи, завершающаяся нулевым символом `\0`. В языке Cи строки представлены массивами символов, где последний символ должен быть нулевым символом, чтобы указать конец строки.

Ну дак вот, для Си нулевой байт это конец строки. Например, функция печати строки выведет символы с начала массива до нулевого байта. Нулевой байт является неким стопером. Если вставить нулевой байт в середину строки, то все что после нулевого байта никогда не выведется на экран.

Ща покажу как это работает

cd /tmp
cp $(which true) .


Копируем утилиту true в папку /tmp, будем ее патчить нулевыми байтами.

Смотрим что она нам выводит:

./true --version


Выводит дофига всего, меня интересует строка Jim Meyering. Теперь нужно узнать смещение этой строки в бинарном файле.

strings -dtx -n3 true | grep 'Jim Meyering'


Команда strings используется для извлечения читаемых строк из бинарных файлов.


d = не дублируем повторяющиеся строки
t = разделитель по умолчанию
x = выводим смещение строки
n = минимальная длина строки

Так, я получил смещение 4176

4176 Jim Meyering


Теперь патчим бинарник true:

dd if=/dev/zero of=./true seek=$((0x4176+3)) conv=notrunc count=1 bs=1


Тут я заменяю символ пробела на нулевой байт. Seek в данном контексте количество блоков, которое нужно пропустить перед началом записи. Берем смещение 4176 и добавляем к нему еще 3 (Jim), после него начинаем запись.

Команда dd скопирует один байт из /dev/zero и запишет его в файл по смещению 4176+3, не обрезая файл.

Теперь снова запускаем:

./true --version


И видим, что часть строки обрезалась нулевым байтом, на экран вывелось:

Written by Jim.


А в оригинале выводилось:

Written by Jim Meyering.


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

Всем еще раз привет, если есть мысли, пишите в комментарии. Пост получился упоротый, но может быть ты его давно ждал. Увидимся!

tags: #linux #bash

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
104
Вечерок вчера весёлый получился, в плане отвала RU зоны. Ну да ладно, само все починилось, меня даже ночью не дернули, удалось поспать 5 часов.

Сегодня продолжим тему с нулями, но на этот раз обсудим такое понятие как — Разрежённый файл. Или как их звать-величать «Дырявые файлы».

Ты всяко в курсе, когда в виртуалке создаешь жесткий диск размером 500 гигабайт, то физический размер этого диска на хостовой машине будет около 1-2х гигабайта, само собой с установленной Linux системой.

Ты суслика видишь? Нет. И я не вижу, а он есть.

А где же все остальное место? А нигде, есть только информация, которая хранится об этом размере в метаданных файловой системы. И по мере необходимости это физическое место на диске выделяется и используется. Сам же файл представляет собой последовательность тех самых нулевых байт (magic zero).

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


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

Чтобы стало понятнее, давай тыкать палкой.

Создаем дырявый файл:

dd if=/dev/zero of=./bashdays bs=1 count=0 seek=100M


Создался файл bashdays размером 4 мегабайта. Да, не 100, а именно 4ре. Открываем в режиме просмотра и видим в нём нули. По факту его можно растянуть как гандон до 100 мегабайт. Размер будет увеличиваться, по мере заполнения этого файла данными, но не сможет превысить 100 мегабайт.

Как альтернатива, ты можешь создать такой файл так:

truncate -s100M ./bashdays


Окей, файл есть и что дальше? А дальше этот файл нужно чем-то заполнить.

Дырявые файлы обычно применяются для:

- экономии места на диске
- виртуализации
- резервных копий
- баз данных
- файловых систем

Очевидно это связанно с оптимизацией, ну и чтобы твой любимый жесткий диск не насиловать физическими записанными нулями.

Из всего перечисленного, я использую такие разрежённые файлы как файловую систему для экспериментов. Создаю файл, а затем просто монтирую ее как файловую систему, провожу опыты, издеваюсь, растягиваю, а затем удаляю.

Чтобы примонтировать такой файл как ФС, делаешь так:

mkfs.ext4 ./bashdays
mount ./bashdays /mnt


Первая накатит туда ext4, а вторая смонтирует в /mnt. А еще в такой дырявый файл можно установить операционную систему и даже загрузится в неё. Короче тут кейсов много всяких, все зависит от твоих задач и предпочтений. Но тема да, прикольная. Всякие virtualbox и т.п. это активно используют.

Теперь про хостеров

Хостеры и не только, часто используют данную фичу, чтобы раскатывать тебе VPS за несколько секунд, единицы ставят ОС с нуля и выдают «честные» гигабайты на жестком диске.

Логично, что хостеры НЕ будут резервировать тебе 100 гигабайт места на диске. Возможно ты ими пользоваться вообще не будешь. Чо оно будет просто так болтаться? А денежку конечно же будут брать именно за 100 гигабайт. По факту ты платишь за дырявый файл, который возможно никогда и не заполнится до конца.

Например, если в яндекс облаке выключить все виртуалки, денежка все равно будет капать за дисковое пространство. Улавливаешь?

Как это работает: есть эталонные образы дырявого файла, разного размера. Ты выбираешь у хостера тариф например 2/2/30, затем берется заранее подготовленный дырявый файл с нужным размером диска и отдается тебе.

Ты видишь (через df -h) что на винте 30 гигабайт, радуешься, но на самом деле это место еще никак не распределено. Используется только 4-5 гигабайта. По мере заполнения данными, заполняется и твой дырявый файл, который тебе продали за 10$ в месяц. Получается так, что в большинстве случаев у тебя в запасе всегда болтается процентов 20 от объема диска, которые ты не используешь, но исправно оплачиваешь.

Такая вот замечательная бизнес модель, такие вот замечательные разрежённые файлы.

Казино всегда в плюсе и ставит на /dev/zero. Делайте ваши ставки, дамы и господа!

UPD: Коллеги отметили, что лучше так: fallocate -l 1G --punch-hole sparsefile

tags: #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
1142
Важный опрос. А есть тут 1С разработчики?
Anonymous Poll
5%
Да, я как раз он/она
95%
Нее...
31
Привет. Сегодня рассмотрим ситуацию… короче предыстория:

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

Знаем точно, что он складывается как раз в тот ебический проект с миллионом файлов. Но не знаем как называется сам файл и где конкретно он сохраняется.

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

Естественно нет документации, нет контактов с разработчиками, нет НИЧЕГО у кого можно что-то узнать. Это обычная практика в айти, вот вам проект, ебитесь сами. В общем приступаем к поискам.

Лазить по каждой папке я не буду, тем более изучать конфиги и насиловать find. Я стараюсь не делать, то что мне не нравится. А вот накидать bash скрипт, это прям хлебом не корми, дай заговнокодить.

Ладно, давай к делу. Отбрасываем все стандартные методы и скрам практики, ставим пакет inotify-tools и накидываем скрипт.

inotifywait -r -m -e create /var/www/bashdays | while read line; do
echo "Created: $line"
done


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


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

Что круто, мониторинг осуществляется рекурсивно, достаточно указать одну папку, а все подпапки автоматически попадут под колпак.

Запускаем скрипт. В соседней вкладке запускаем команду, которая генерит этот вонючий файл с выгрузкой и ждем. Совсем скоро на экране я получаю такую запись:

Created: /var/www/bashdays/core/modx/var/tmp CREATE 1C_b2b_prices.csv


Опа, задача решена, путь до файла определен, как и его имя. Пишем комментарий к задаче, передвигаем её в Done и трекаем 8 часов потраченного времени.

Вообще игрушка inotify-tools достаточно мощная, можно мониторить не только создание файлов, но и кучу еще всего. При должном подходе, можно свой собственный мониторинг собрать, выгружать в prometheus и соплю в grafana рисовать.

Про все ее возможности писать не буду, всё прекрасно гуглится, да и man у нее хороший. Я лишь показал, как применил эту штуку на реальной задаче и сэкономил кучу времени. А дальше тебе карты в руки.

А еще есть клевая штука incrond, с помощью неё можно запустить какую-нибудь утилитку, если в каком-то каталоге появился новый файл или произойдет другое событие.

Например, можно дернуть обработчик этого файла, сделать резервную копию, или тегнуть в телеграм. Вариантов масса.

incrond (inotify cron daemon) - это демон для системы Linux, который обеспечивает возможность запуска задач (команд или скриптов) в ответ на события файловой системы, используя механизм inotify. Он подобен стандартному демону cron, но вместо использования времени он реагирует на изменения файлов и каталогов.


Я однажды видел подобную поделку на каком-то сервере у хостера, где админы сильно упарывались с безопасностью, отслеживали вообще любые изменения в рабочих каталогах и слали алерты на любой чих. С фейками для отнятия почт так боролись. Ну не знаю… по моему совсем уж избыточно.

Ладно, не болей, хороших тебе предстоящих выходных и береги себя!

tags: #linux #bash #debug

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
218
Привет, тут на днях в нашем чатике пролетала софтина которая делает этакий ханипот на 22 порту. И все кто ломится по ssh просто вязнут в этом болоте.

Но сегодня не про это. Сегодня про злоумышленников, которые методом тыка пытаются найти и украсть бэкап. Зачастую бэкапы хранятся в папках проекта, либо вообще в корне пылятся годами.

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

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

Как с этим бороться? Ничего не бэкапить в папки проекта, удалять промежуточные файлы если что-то переносил, настраивать политики nginx чтобы 403 отдавал и т.п.

Но есть способ сделать простой ханипот. Злоумышленник якобы находит бэкап, получает статус 200 и начинает его скачивать. Естественно это не бэкап, а специально подготовленный файл большого размера. Причем такой файл отдается специально с пониженной скоростью и санкциями.

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

Давай настроем такой ханипот на примере nginx

Добавляем в nginx конфиги:

location ~* "^/(new|old|bkup|tmp|temp|upload|ftp|sql|file|www|drupal|joomla|wordpress|x|user|admin|a|b|r|rezerv|arch|arx|111|archive|auth|backup|clients|com|dat|dump|engine|files|home|html|index|master|media|my|mysql|old|site|sql|website|wordpress)\.tar.gz$" {
access_log /var/log/nginx/honeypot.log;
default_type application/zip;
root /var/www/bashdayz/files/backup;
rewrite ^(.*)$ /backup break;
max_ranges 0;
limit_rate 4k;
limit_conn addr 1;
}

# а это в секцию http
limit_conn_zone $binary_remote_addr zone=addr:10m;


Указываем список на что будем триггериться. Ограничиваем скорость, ограничиваем число потоков, запрещаем докачку.

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

dd if=/dev/zero of=/var/www/bashdayz/files/backup bs=1G count=1


Вот и всё. Теперь если кто-то попытается вытянуть у тебя бэкап к примеру mysql.tar.gz, то будет страдать. Идея думаю тебе понятна, вокруг нее можно городить вообще сумасшедшие схемы. Но опять же это всего лишь концепт, из которого можно сделать что-то большое и нужное.

Я одно время применял этот способ в случае, когда коллеги просят выдать бэкап базы. Обычно я даю прямую ссылку на скачивание. Но бывают ситуации, когда разработчики ведут себя как зажравшиеся ЧСВешные мудаки. И на такой случай у меня для них была специальная ссылка для скачивания бэкапа.

Ничего особенного, но с сюрпризом, бэкап никогда не скачается. Тащить 10 гигабайт со скоростью dial-up ну такое себе. А когда те начинали орать как свинья из avp, мой ответ был простой - проблема на твоей стороне. У меня видишь все работает и показываю скриншот с нормальной скоростью.

Но таким быть фу, заподлостроением пусть школьники занимаются. Мы с вами взрослые и ответственные ребята. Правда? )

Ладно, рад всех видеть. Всем хорошей рабочей недели!

tags: #nginx #networks

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
154
Привет. Разгребал тут мамонтовский сервер и нашел исходник с таким артом.

Думаешь это всего лишь картинка из архивов старого фидошника? Нифига, это Acme EyeDrops. Visual Programming in Perl.

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

perl ./pokazisiski.pl


Сам код этого арта, сгенерирован с помощью модуля Acme::EyeDrops. Кстати на странице модуля много примеров с такими картинками (верблюды, морды, заборы, снежинки), каждая выполняет какое-то своё действие + есть примеры генераторов.

А вот эта команда, превратит файл обратно в исходник. То есть выведет исходный код вместо того, чтобы его выполнить.

perl -MO=Deparse ./pokazisiski.pl


Опять же не знаю, что ты будешь делать с этой информацией. Говорят что perl давно мёртв, но в современных скриптах и решениях люди любят его применять. ХЗ почему, наверное потому что perl есть везде. Хотя сейчас глянул, последний релиз был 2024-01-20, версия 5.39.7 (devel), капец, оно живое.

Первое и последнее, что я делал на perl, это был вывод «Hello World», на этом моё знакомство с ним закончилось. Даже на СИ порог вхождения мне легче показался, хотя по СИ у меня была книга, а по perl только какие-то огрызки из фидонета.

Ладно. Побежали дальше мир спасать от криворучек. Увидимся!

А ты применяешь perl в современном мире? Если да, поделись пожалуйста в комментариях, как и где. Очень интересно.

tags: #linux

💩 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
87