Bash Days | Linux | DevOps
23.2K subscribers
127 photos
22 videos
600 links
Авторский канал от действующего девопса

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

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

Курс: @tormozilla_bot

РКН: https://two.su/bashdays
Download Telegram
Сентябрь горит, как и моя жопа. Поставил я давеча на пятую малинку self-hosted гитлаб, чтоб к ребятам с LF быть поближе.

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


Всё бы хорошо, но в моменте пуша свеженького image docker в registry, я невзначай обнаружил, что в гитлабе его просто-напросто НЕТ!

Куда же он сука такая делся? В облачном есть, в self-hosted — хуй!

Ну думаю щас галочку где-нибудь в настройках поставлю и все у меня получится. Перерыл всё что только возможно. Но гитлаб тот еще выблядок парижской потаскухи. Нет галочки… Хуй сосали на вокзале!

Да даже взять ситуацию перевода private репы в public.


Кароче. Чтобы включить Container Registry, нужно зайти в конфиг /etc/gitlab/gitlab.rb и…

Раскомментировать эту строчку:

gitlab_rails['registry_enabled'] = true


И после этого запустить:

gitlab-ctl reconfigure
gitlab-ctl restart


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

И о чудо! Заветный пункт меню Container Registry внезапно появляется. Тут и сказочки конец. НО НЕТ. При попытке зайти в этот новый пункт, получаем ошибку:

Docker connection error. We are having trouble connecting to the Container Registry. Please try refreshing the page. If this error persists, please review the troubleshooting documentation .


Ебутся блохи в суматохе!!! Идем читать документацию!

Реестр контейнеров автоматически включается и становится доступным в вашем домене GitLab, если вы используете встроенную интеграцию Let's Encrypt.


Fuck This Shit! Включаем поддержку Let's Encrypt в конфиге gitlab.rb:

letsencrypt['enable'] = true
letsencrypt['auto_renew'] = true


Запускаем gitlab-ctl reconfigure && gitlab-ctl restart

Иииии… тадам, модуль registry запустился!

sudo gitlab-ctl status

ok: run: registry: (pid 20114) 0s


Квест успешно пройден, но мне пиздец как не понравилось!

Поэтому сношу я этот sefl-hosted гитлаб к хуям и возвращаюсь в облачный. А на малинку пожалуй воткну gitea, надеюсь там такой хуйни не будет. Или будет?

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

tags: #devops

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
527314
Здрасти. К делу!

Гиту откровенно насрать на права доступа файлов. И после клонирования репы, эти права будут установлены по umask пользователя.

Ситуация не критичная, но иногда случаются моменты когда нужно все эти права сохранить и после клона восстановить.

На помощь приходит костыль, всё в лучших традициях!

#!/bin/bash

find . -type f -exec stat --format='%a %n' {} \; > permissions.txt
git add permissions.txt
git commit -m "на залупе лешего вертели"
git push


Пробегаемся по всем файлам и каталогам, записываем текущие права в файл permissions.txt, коммитим, пушим.

Ну и скрипт для восстановления прав:

#!/bin/bash

if [ -f permissions.txt ]; then
while read perm file; do
if [ -f "$file" ]; then
chmod "$perm" "$file"
fi
done < permissions.txt
fi


Вот и вся наука. По желанию вешаешь это на Git Hook (post-checkout, post-merge) и автоматизируешь.

Как автоматизировать писал в этом посте, на примере можешь адаптировать.


А еще есть git-restore-mtime, для восстановления метаданных времени модификации файлов.

Такие дела, изучай…

tags: #linux #bash

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
186314
Богатствуйте!

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

Меня часто спрашивают… Нет, всем похуй. Короче:

systemctl restart php-fpm

Unit php-fpm.service could not be found.


Хм, я точно знаю что php на сервере есть! Так какого чернослива?

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

В примере выше, php сервис называется: php8.2-fpm-fuck-you!

Ха! В жизни не догадаешься.

Первым делом пиздуем в:


history | grep php


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

Если не повезло делаем так:

systemctl | grep php

php8.2-fpm-fuck-you.service
phpsessionclean.timer


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

Можно конечно воспользоваться внешними утилитами, но не рекомендую. Потому что systemctl есть всегда, а внешних утилит - нет.

➡️ Сразу привыкай работать с инструментами из коробки и будет тебе счастье.

Все!

Ну и анекдот как обещал: еслиб у бабушки был бы хуй, она была бы дедушкой.

tags: #linux #debug

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
259824
Тыж в курсе, что терминал и консоль это не одно и тоже?

Нет? Спешу удивить, нихуя это не одно и тоже.

Хотя для меня и скорее всего для тебя терминал и консоль — один хуй.

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

Хоть усрись, неважно как это называется, важно какой смысл ты в это закладываешь.

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

Вернемся к терминалам и консолям.

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

У нас на заводе бухгалтерию так называли — «кабинет с бабинами». Бабины были моё почтение.


В настоящее время мы пользуемся эмуляторами терминалов, это всякие Konsole, Gnome Terminal, Tilix, Guake и т.п. которые прекрасно себя чувствуют в GUI.

То есть эмулируем ту самую хуйню с кнопками и телевизором.

Теперь про консоль

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

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

Писал я тут недавно про Magic SysRq, вот это про консоль.

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

Терминал:

/dev/pts/<x>: Псевдотерминальные устройства, используемые для терминальных сессий, таких как SSH или терминалы в графических средах. Они представляют собой виртуальные терминальные устройства, которые обычно создаются и управляются операционной системой.


Консоль:

/dev/tty/<x>: Устройства, представляющие собой физические или виртуальные терминалы на уровне ядра. Например, это могут быть устройства для текстовых консольных сессий или виртуальные консоли, предоставляемые ядром Linux.

Важно отметить, что /dev/tty без <x> также может обозначать текущее терминальное устройство, к которому привязан процесс, например, при работе в командной строке.


Заходим в консоль и отправляем на терминал:

$ echo "Bashdays here!" > /dev/pts/0


А еще про всякие vt100, xterm, ansi я писал тут, почитай, интересно.


Такие дела. Не заморачивайся. Изучай!

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
267127
Аутентификация, авторизация. Навеяло.

Есть два вида запоминания паролей - хранение и связанная генерация. Это когда ты вводишь логин, а программа на основании его и модификатора (соли) вычисляет пароль.

Хранить лучше в программах типа keepass и аналогах. Сейчас затронем тему генерации.

Есть такая известная программа как pwgen. Просто чудесная. Столько всего умеет. В том числе и связывать логин и пароль. Проблема только в том, что при генерации командная строка может попасть в history.

И пароль может быть немного скомпрометирован. Я написал для нее небольшую обертку, которая, как мне кажется, решает эту проблему.

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

Модификатор - это что-то типа парольной фразы при использовании ключа.

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

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

Модификатор может набираться с клавиатуры видимом и скрытом режимах. Все зависит от агрессивности коллектива.

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

Да, совсем забыл, параметр PWGEN_OPT - дополнительные опции генерации пароля НЕЛЬЗЯ менять после начала эксплуатации программы.

Программа pwgen должна быть установлена.

Для debian sudo apt install pwgen

declare -r PWGEN_OPT='-1 --symbols --ambiguous --capitalize'
declare -r PASSLEN=15
declare -r PASSNUM=5
declare -r KEYFILE=${0%/*}/'1.jpg'
declare -l HIDDENMOD=0
declare -r PWGEN=$(which pwgen)
declare LOGIN
declare MOD MOD1

if [[ ! "$PWGEN" ]];then
echo pwgen not installed
exit 1
fi
if [[ ! -s "$KEYFILE" ]];then
echo keyfile "$KEYFILE" not found
exit 2
fi
read -p "Input login:" LOGIN
if [[ "1y" =~ "$HIDDENMOD" ]];then
read -s -p "Input modificator:" MOD;echo
read -s -p "Confirm modificator:" MOD1;echo
if [[ "$MOD" != "$MOD1" ]];then
echo "Modificator not confirmed"
exit 3
fi
else
read -p "Input modificator:" MOD;echo
fi
echo pwgen options: $PWGEN_OPT
echo "Login: $LOGIN"
$PWGEN $PWGEN_OPT -H"${KEYFILE}#${LOGIN}${MOD}" $PASSLEN $PASSNUM


сохраняем в файл passgen.sh


chmod +x passgen.sh
./passgen.sh


По умолчанию ввод модификатора отображаемый. Для параноиков - установить HIDDENMOD=1 результат работы примерно такой:

Input login:tagd@bashdays.ru
Input modificator:BashDaysTheBest

pwgen options: -1 --symbols --ambiguous --capitalize
Login: tagd@bashdays.ru
aig3ohkie.Wah4X
AiguW~u7vohphae
eiJa7ahxei.die!
FaeNa=phah9voh3
Kih]ahca3Hie7ke


Если повторить ввод тютелька в тютельку пароли будут те же самые, что и требовалось.

➡️ Тыкни сюда, чтобы посмотреть описание работы программы.

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

Почитать:

help declare read
man pwgen
https://cheatsheets.zip


tags: #bash #linux © by Tagd Tagd

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
4113
Когда ты устанавливаешь софтину через apt или подобную херню, зачастую к софтине прилипают паразиты.

То есть Recommended packages. Ща покажу!

Смотри:

apt install mc

The following NEW packages will be installed:
bzip2 libssh2-1 mailcap mc mc-data unzip

6 newly installed.


Ага, будет установлено 6 пакетов, включая паразитов — mailcap unzip.

Midnight Commander отлично работает без этих mailcap unzip.

А прикинь, ставишь ты какую-нибудь phantomjs, а он дополнительно тянет KDE, на сервер где вообще нет иксов.


Это так для примера, чтобы ты понял про что я.

Как избавиться от паразитов? Вот так:

apt install mc --no-install-recommends

Recommended packages:
mailcap unzip
The following NEW packages will be installed:
libssh2-1 mc mc-data
3 newly installed.


Всё! На три пакета установится меньше (bzip2 это Suggested packages)

Как глобально избавиться от Recommended packages?

Создаем файл: /etc/apt/apt.conf.d/99norecommends

И вставляем в него:

APT::Install-Recommends "false";


Теперь ключик no-install-recommends можно везде не пихать, паразиты отключены.

Ну а чтобы для конкретного пакета установить паразитов:

apt-get install mc --install-recommends


Конец! Пользуйся на здоровье!

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
1320146
Как ускорить установку пакетов

Берем для примера пресловутый midnight commander и устанавливаем повторно + снимем бенчмарку.

time apt install -y --reinstall mc
real: 2.977s


Почти 3 секунды. Приемлемо. Но если нужно поставить 100 пакетов, то в среднем это займет 300 секунд или 5 минут. Уже дохуя!

Давай оптимизируем этот процесс и превратим 300 секунд в 150, а то и меньше.

Устанавливаем утилиту eatmydata:

apt install eatmydata


Устанавливаем midnight commander и замеряем время:

time eatmydata apt install -y --reinstall mc
real: 1.204s


Хуясе, почти одна секунда, установка mc прошла в два раза быстрее.

Но почему? И что сделала eatmydata?

eatmydata предназначенная для ускорения операций записи на диск в Linux-системах, особенно при установке пакетов с помощью APT. Она временно отключает механизмы, которые обеспечивают сохранность данных при сбоях системы, такие как fsync, fdatasync, flock и msync, что позволяет уменьшить время записи данных на диск.


Короче говоря утилита игнорирует запросы на немедленное сохранение данных на диске (синхронизация).

Где это можно использовать?

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

Такие дела, изучай!

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
168423
Чтобы каждый раз не задрачивать жесткий диск операциями — чтение/запись, ядро Linux обычно сохраняет некоторую часть данных в памяти.

Представим ситуацию — у тебя на кухне гудит сервак, ты запускаешь на нем apt update и внезапно отключают свет. Через минуту свет включают, ты запускаешь вновь apt update, а оно тебе орет:

The package cache file is corrupted


Что это за покемон? Почему оно сломалось?

Потому что во время операции apt update, часть данных была сохранена в памяти и данные просто не успели записаться на диск. Соответственно целостность файла с кешем была похерена.

Давай посмотрим:

free -h


Смотрим столбец buff/cache, в нем видим что-то вроде: 383Mi.

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

В Linux есть команда sync, которая позволяет насильно записать все данные из памяти на диск.

Но если после sync повторно запустить free -h, изменений ты не увидишь, потому что sync ничего не зачищает, а только записывает.

Зачистить можно так:

sync; echo 1 > /proc/sys/vm/drop_caches
sync; echo 2 > /proc/sys/vm/drop_caches
sync; echo 3 > /proc/sys/vm/drop_caches


Хуячим командами в ядро и зачищаем buff/cache, теперь можно снова запустить free -h и лицезреть меньший размер.

Очищает кэш страниц (page cache), который используется для кэширования содержимого файлов и каталогов.

Очищает только кэш объектов inode и dentry (данные о файловой системе, такие как пути и метаданные файлов).

Очищает как кэш страниц, так и кэш объектов inode и dentry.

Где применять?

1. Перед отключением устройства (umount)
2. Перед очисткой кэшей памяти (drop_caches)
3. После крупных файловых операций
4. В bash скриптах для безопасного завершения

А для анализа всех этих кешей, памяти, буферов и т.п. есть несколько утилит: vmtouch, bpfcc-tools, dstat. Можешь потыкать на досуге.

Пользуйтесь!

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
168324
🔥 Говяжий дошик ВСЁ!

Есть штука прикольнее, называет — tig.

Это утилита-обёртка для git с консольной мордой лица (ncurses). Охуенно заходит для быстро позырить историю коммитов и прочие непотребства.

- Просмотр истории и логов
- Отображение состояния репозитория
- Работа с изменениями на уровне отдельных блоков
- Поиск по содержимому файлов


Можно конечно и через нативные git командами всё это глянуть, но любителям новогодних ёлок — tig однозначно зайдёт.

Звездочек у проекта достаточно дохуя (12к), поэтому рекомендую забрать в свой рабочий инструментарий. Авось зайдёт на постоянку. Потыкай.

Установка: apt install tig

Репа на гитхабе: https://github.com/jonas/tig

tags: #utils #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
8478
Реверсим Dockerfile

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

Как произвести реверсинг?

Для примера соберем образ из такого Dockerfile

FROM python:3.8-slim
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]


Запускаем сборку имейджа:

docker build -t pythoner:latest .


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

docker history pythoner:latest


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

docker history --no-trunc pythoner:latest


Вылетит простыня, но при сноровке и насмотренности, всё вполне предсказуемо.

В идеале совмещаем с dive, смотрим окно Layers и стрелками перемещаемся по слоям, а там уже видно все команды, которые выполнялись из Dockerfile.

По итогу из говна и палок собираем копию нужного нам Dockerfile.

А файлы, которые были добавлены через COPY, вытягиваем себе на локальную машину так:

docker cp <image id>:/etc/nginx/nginx.conf /tmp


Про дебаг докер имейджей и контейнеров я писал в этом посте, почитай, достаточно информативно.


Как вариант можешь воспользоваться анализаторами, например trivy.

Trivy это комплексный и универсальный сканер безопасности для docker images. Заодно еще безопасность своих решений можно позырить и приуныть.

А еще есть клевая поделка для этого на python, но про нее закину уже завтра.

Вот такие пироги, если знаешь еще способы — пиши в комменты, будет полезно!

tags: #debug #devops #docker

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
156517
Вчера мы рассмотрели способы как отреверсить Dockerfile с помощью рук и глаз.

Сегодня рассмотрим никому не известную утилиту — «Дедок».

Утилита написана на питоне и позволяет свести к минимуму handjob по реверсу.

Грубо говоря «Дедок» проанализирует твой docker image и выплюнет на экран готовый Dockerfile.

Ну как готовый, очень приближенный к реальности.

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

Запускаем так:

docker run -v /var/run/docker.sock:/var/run/docker.sock mrhavens/dedockify <ID Image>


Либо сразу в алиас:

alias dedoc="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm mrhavens/dedockify"


Предварительно подставь нужный ID Image.


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

➡️ Репа проекта и документашка.

Развлекайся. Увидимся совсем скоро!

tags: #debug #devops #docker

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
123613
Порой бывает необходимо прям из bash-скрипта добавить/удалить какое-нибудь задание в cron.

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

{ crontab -l; echo '#@reboot echo BashDays >/tmp/BashDays.txt' ; }| crontab -


ИЛИ:

{ crontab -l; echo '#*/10 * * * 5 echo BashDays >>/tmp/BashDays.txt' ; }| crontab -


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

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


#!/bin/bash

function ADD_CRON_TASK(){
local CRON_TASK=${1:-'#'}
local COMMENT=${2:-$(date +%s)}
COMMENT=${COMMENT// /_}
{ crontab -l 2>/dev/null; echo "$CRON_TASK #$COMMENT"; }| crontab -
}

function REMOVE_CRON_TASK(){
if [[ $# -eq 0 ]];then
echo No comment to remove cron task >&2
return
fi
COMMENT=${1// /_}
crontab -l 2>/dev/null|sed '/#'$COMMENT'$/d'|crontab -
}

CRON_TASK='#@reboot reboot'
COMMENT="My litle joke"
ADD_CRON_TASK "$CRON_TASK" "$COMMENT"

crontab -l|tail -3

echo '###################################################'
REMOVE_CRON_TASK "$COMMENT"

crontab -l |tail -3


Если запустить программу, увидите что-то типа:

# 
# m h dom mon dow command
# @reboot reboot #My_litle_joke
#############################
# For more information see the
#
# m h dom mon dow command


Видно, что программа добавила задание, вывела последние три строки crontab'a, потом разделитель.

Затем задание было удалено. Это видно по последним трем строкам.

В комментариях задания пробелы заменяются на "_" для упрощения работы c sed.

Ну, и на всякий пожарный напомню, что для корректной работы с cron нужно задать переменную PATH либо в crontab, либо в скрипте.

tags: #bash #linux © by Tagd Tagd

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
287
Привет. Почему-то я думал что сегодня пятница, мда…

Ладно, поехали. Ты всяко встречался с такой ебаной ошибкой при подключении к серверу по ssh:

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

Please contact your system administrator. Add correct host key in /home/your_user/.ssh/known_hosts to get rid of this message. Offending RSA key in /home/your_user/.ssh/known_hosts:xx


У меня коллеги обычно сразу прибегают и начинают подозревать неладное — ааа спасите, сервер взломали, не могу подключиться! Паникёры блядь…


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

Чо за ошибка и что нужно делать?

Файл ~/.ssh/known_hosts используется для хранения списка хостов, с которыми ты ранее взаимодействовал по ssh.

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

В дальнейшем, при каждом подключении к этому серверу, ssh-клиент сверяет ключ сервера с тем, что хранится в файле known_hosts.

Это помогает удостовериться, что ты подключаешься к правильному серверу, а не к какому-то левому.

Короче вся эта чача сделана для безопасности, чтобы избежать анальной атаки — «мужик посередине».


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

Открываем свой локальный /etc/ssh/ssh_config или ~/.ssh/config и херачим в него такое:

Host * 
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null


Всё! Теперь даже если случится «мужик посередине», ты успешно подключишься к серверу без всяких ошибок.

Если нужно отключить защиту для конкретного хоста, знак звездочки заменяем на нужный тебе ip или домен.

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

ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@hostname


Либо сделать алиас:

alias ssh = "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"


А если всё делать по уму и остерегаться «мужика посередине»:

1. Наводим справки, что случилось с сервером у админов
2. Если все ок, делаем так: ssh-keygen -R <hostname_or_ip>

После этой команды, файл known_hosts подчиститься и ошибка отправится в пешее эротическое.

Чо тебе еще рассказать? Особо больше нечего по этой теме.

А если тебе есть что добавить — велком в комментарии.

Давай краба! Завтра надеюсь точно пятница…

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
137121
У меня возникла проблема. Мне нужно переконфигурировать сеть на железном сервере, который находится в другом городе. И командировка туда займет пару дней.

Проблема усугубляется тем, что на сервере нет ipmi или аналогов, кроме того, в окружении нет админа. Поэтому конфигурировать сеть нужно по ssh.

Надеюсь никому здесь не нужно объяснять, чем это грозит. В общем, прикинул я хрен к заднице, что можно сделать и написал скрипт.

Скрипт поможет в случае чего восстановить конфигурацию, в случае моего косяка.

Алгоритм работы следующий:

0. Есть работающий сервер.

1. При запуске создается резервная копия защищаемого каталога конфигурации /etc

2. В crontab добавляется задание, которое через определенное время ПОСЛЕ ПЕРЕЗАГРУЗКИ восстановит каталог из копии.

3. Если вышеуказанное задание определит, что в систему по ssh вошел указанный пользователь, восстановление отменяется и задание из crontab убирается.

4.Если пользователь не смог войти в систему - сначала создается вторая резервная копия защищаемого каталога (на тот случай, если сконфигурировали все правильно, но забыли/не смогли войти из-за проблем на вашей стороне, ну и для анализа), после этого производится восстановление резервной копии из пункта 1, убирается задание из crontab и производится перезагрузка сервера. Сервер приведен к пункту 0.


Пользоваться этой цацой просто:

1. ПЕРЕД НАЧАЛОМ КОНФИГУРИРОВАНИЯ запускаем скрипт, Он запрашивает имя пользователя и время ожидания до восстановления ПОСЛЕ ПЕРЕЗАГРУЗКИ.

2. Конфигурируем сервак.

3. Отправляем сервак в перезагрузку. (Да, не лучший вариант, но по сравнению с командировкой фигня).

4. Пытаемся войти по ssh.


По ssh мы войдем в любом случае. Или быстро (если сервак сконфигурировали правильно) или по окончании времени ожидания и перезагрузки.

Обращаю внимание - если пользователь смог войти в систему - Сервер считается работоспособным, задание из cron убирается.

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

Скрипт тестировался на debian путем удаления каталога /etc/network

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

Скрипт не сможет восстановить конфигурацию, если машина не грузится совсем (ну, например грохнули fstab)

На Alpine точно не работает по двум причинам:

1. crontab не понимает опцию @reboot (проблема решаемая через /etc/inid.d)

2. по умолчанию не работают команды last, who, w. Поэтому несколько проблематично определить наличие пользователя в системе.

➡️ Скрипт в комментариях к этому посту, сюда не влез сука!

tags: #bash #linux © by Tagd Tagd

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
8417
Здрасти. Давай сегодня соберем свой «мета-пакет».

Что такое «мета-пакет»? Нууу…

Например, я хочу разом поставить htop, git, rclone, mc и прочее. И чтобы не вводить команду на установку:

apt install htop git rclone mc


Я могу поставить один «мета-пакет», который будет содержать в себе все эти утилиты. Что-то из оперы Zver DVD, где нужный софт ставился сразу пачкой.

Поехали тыкать палкой!

Ставим зависимости и готовим окружение:

sudo apt-get install -y build-essential devscripts dh-make


Создаем структуру для «мета-пакета»:

cd /tmp
mkdir bashdays-soft
cd bashdays-soft


Создайте контрольные файлы пакета:

dh_make --native --single --yes -p bashdays-soft_1.0


Ключи:

native — создаёт пакет без указания версии дистрибутива
single — создаёт минимальную структуру
-p my-metapackage_1.0 — имя пакета и версия (1.0)

В ответ получаем выхлоп:

Maintainer Name : root
Email-Address : root@unknown
Date : Sun, 29 Sep 2024 03:58:22 +0000
Package Name : bashdays-soft
Version : 1.0
License : gpl3
Package Type : single


Открываем файл на редактирование:

vim debian/control


И хуячим описание для «мета-пакета»:

Source: bashdays-soft
Section: misc
Priority: optional
Maintainer: Roman Shubin <hello@devopsina.ru>
Standards-Version: 4.5.0
Build-Depends: debhelper-compat (= 11)

Package: bashdays-soft
Architecture: all
Depends: mc, htop, curl, git
Description: My own Installer


В секции Depends перечислены все пакеты, которые должны быть установлены вместе с мета-пакетом. У меня это mc, htop, curl, git.

Параметр Architecture: all указывает, что пакет не зависит от архитектуры.

Собираем «мета-пакет»:


debuild -us -uc


Ключи -us и -uc отключают подпись пакета.

Смотрим что получилось:

ls -la ..


И видим:

bashdays-soft_1.0.tar.xz
bashdays-soft_1.0_all.deb


Наш «мета-пакет готов». Давай теперь его установим и посмотрим что получилось:

sudo apt install -yf ../bashdays-soft_1.0_all.deb


Проверяем и видим что произошла установка всех пакетов которые я описал в секции Depends в файле debian/control. ЗБС!

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

dpkg -l mc htop curl git


В ответ получишь красивую табличку и информацию о пакетах.

Теперь можешь приготовить свой собственный «мета-пакет» со всем необходимым и быстренько раскатывать его на новые сервера.

Темка достаточно интересная, поэтому рекомендую потыкать.

Пользуйтесь!

tags: #linux

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
138821
Решился я тут по быстрому взгромоздить proxmox на пятую малину, благо есть решение — Pimox7.

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

Кто не в курсе:

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


Всё чего я добился с Pimox7:

The following packages have unmet dependencies:
ceph-fuse : Depends: libfmt7 (>= 7.1.3+ds1) but it is not installable
libpve-rs-perl : Depends: perlapi-5.32.1 but it is not installable
libpve-u2f-server-perl : Depends: perlapi-5.32.1 but it is not installable
librados2-perl : Depends: perlapi-5.32.1 but it is not installable
lxc-pve : Depends: libgnutlsxx28 but it is not installable
pve-cluster : Depends: perlapi-5.32.1 but it is not installable
pve-qemu-kvm : Depends: liburing1 (>= 0.7) but it is not installable


Какой-то сука перл... Ну раз такое дело, надо решать! Фиксить скрипт Pimox7 я ебал, поэтому устроил анал-карнавал и зашел с черного хода.

В телеге с разметкой беда, поэтому запилил свою «официальную документацию» в другом месте. Мож кому пригодится 👇

➡️ Proxmox на Raspberry Pi 5

Хорошего тебе дня-вечера, увидимся!

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

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
174413
Принцесса для снятия стресса

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

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


<прилагательное><фамилия> и всегда написаны в нижнем регистре.

Например:

quirky_pare
agitated_turing
furious_heisenberg
romantic_curie


Окей. После некоторого ресёрча оказалось, что 90% докера написано на Golang. Вот это поворот!

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

➡️ Посмотреть можешь тут.

Мотаем этот код в самый низ и видим забавную хуйню:

if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
goto begin
}


Этакая пасхалочка. Но зачем все эти имена?

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

Ну и на закуску адаптируем полученные знания на bash, генератор может выглядеть так:

#!/bin/bash

adjectives=(
"adoring" "agitated" "amazing" "angry" "awesome" "blissful" "bold"
"boring" "brave" "clever" "cool" "compassionate" "competent" "crazy"
"dazzling" "determined" "ecstatic" "elegant" "eloquent" "epic"
"exciting" "fervent" "focused" "furious" "gallant" "gifted" "goofy"
"gracious" "happy" "hardcore" "hopeful" "hungry" "infallible" "inspiring"
"jolly" "jovial" "keen" "kind" "laughing" "loving" "magical"
"mystifying" "naughty" "nervous" "nostalgic" "optimistic" "peaceful"
"practical" "priceless" "quirky" "recursing" "relaxed" "reverent"
"sad" "serene" "sharp" "silly" "sleepy" "stoic" "strange" "stupefied"
"suspicious" "tender" "thirsty" "trusting" "unruffled" "vibrant"
"vigilant" "wizardly" "wonderful" "youthful" "zealous" "zen"
)

scientists=(
"albattani" "allen" "archimedes" "ardinghelli" "babbage" "bashdays" "banach"
"banzai" "bardeen" "bartik" "bassi" "bell" "benz" "bhabha" "bhaskara"
"blackwell" "bohr" "booth" "borg" "bose" "boyd" "brahmagupta" "brattain"
"brown" "carson" "chandrasekhar" "colden" "cori" "cray" "curie"
"darwin" "davinci" "dijkstra" "dubinsky" "easley" "einstein"
"elion" "engelbart" "euclid" "euler" "fermat" "fermi" "feynman"
"franklin" "galileo" "galois" "goldberg" "goodall" "hawking"
"heisenberg" "hermann" "herschel" "hertz" "hodgkin" "hoover" "hopper"
"hypatia" "joliot" "kalam" "keller" "kowalevski" "lalande" "leavitt"
"lichterman" "liskov" "lovelace" "mayer" "mccarthy" "mcclintock"
"mclean" "mcnulty" "meitner" "mendel" "mendeleev" "minsky" "mirzakhani"
"moore" "napier" "newton" "nobel" "noether" "panini" "pare"
"pasteur" "payne" "perlman" "pike" "poincare" "ptolemy" "raman"
"ramanujan" "ride" "ritchie" "roentgen" "rosalind" "saha"
"sammet" "shockley" "sinoussi" "stallman" "stonebraker" "swanson"
"tesla" "thompson" "torvalds" "turing" "varahamihira" "visvesvaraya"
"wilbur" "wiles" "williams" "wilson" "wing" "wozniak" "wright"
"yonath"
)

generate_container_name() {
local adjective="${adjectives[RANDOM % ${#adjectives[@]}]}"
local scientist="${scientists[RANDOM % ${#scientists[@]}]}"
echo "${adjective}_${scientist}"
}

count=${1:-10}
for ((i=1; i<=count; i++)); do
generate_container_name
done


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

Теперь ты в праве заполнить массивы своими данными и генерировать уникальные имена, например: pizdatiy_huy или ohuennaya_pizda.

А потом использовать сразу в командах:

docker run --name $(bash script.sh) -d nginx


Есть еще такая штука:

alias dn='curl -s https://frightanic.com/goodies_content/docker-names.php'


Это выплюнет тебе подобное имя прям в консоли без скриптов и приседаний.

А еще есть библиотека на питоне — codenamize, которая проворачивает тоже самое.

Короче есть из чего выбрать. В общем пользуйся, прикручивай, изучай!

tags: #linux #bash #docker

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
265719
Тема вроде не айтишная, а вроде и айтишная, сделал я короче МРТ, по итогу приобрел грыжу и протрузию поясничного отдела.

Вас много и полюбому кто-то с этим уже столкнулся и живет в клубе по интересам. Вопрос — как эту хуйню захотфиксить? Мидокалм, пластыри и т.п. гавно это понятно.

В ремиссии чо делаете? ЛФК из чего состоит? Я ебать попробовал по официальному мануалу от невролога как котик спину выгибать и вгибать на корачках, через полчаса с температурой слег ))

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

Короче у меня одни вопросы, посоветоваться кроме как с вами мне не с кем. Гуглёж выдает тонны воды, а нужна проверенная база )

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

Короче коллеги-калеки поделитесь инвайтом в ваш клуб и методичкой чо делать, спасибо ) Всем отвечу уже завтра, пойду плакать.

UPD: Всем кто дал дельные советы — Спасибо! А кто хочет еще что-то добавить то велком сюда.

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

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
34387
С пятницей ребят!

Недавно пришло письмо от мейл.ру мол у вас SPF запись пиздец хуёвая.

SPF-запись домена https://bashdays.ru задана таким образом, что для ее проверки необходимо 36 DNS-запросов из 10 допустимых.


Я человек простой — вижу хуйню, прохожу мимо. Но тут пройти не смог, какой-то животный интерес возник. Что это еще за 10 допустимых запросов?

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

➡️ Рекомендую добавить сервис в закладки, для дебага самое оно!

От результата я знатно прихуел, вот моя SPF:

v=spf1 mx a include:spf.gca.to include:_spf.google.com include:spf.smtp.bz include:mindbox.ru ~all


И результат: 36/10

И чо мне с этим делать? Для начала убрал mx и a, по итогу получил результат: 18/10. Уже лучше, поехали дальше оптимизировать!

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

Перегуглил… нииихуууя!

И как это дерьмище сокращать? Если каждый инклуд содержит в себе еще сабинклуды. Сука!

Короче пост не про решение проблемы, а про сервис SPF Surveyor.

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

Такие дела…

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

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
173616
Начало месяца - время делать бэкапы. О бэкапах уже столько сказано, что еще одна статья ничего нового не добавит, но тем не менее позволю себе поделиться своим опытом.

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

Пока мой архив был меньше 10 Тб, я не понимал, нахрена нужны инкрементные копии? А у кого-то петабайты...

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

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

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

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

Причем дисков должно быть минимум два с чередованием (месячным, недельным, ежедневным не важно, но чередование должно быть). Кроме того, есть холивар, по поводу того, кто должен быть инициатором соединения при архивировании - СХД или рабочий сервер.

Просто подумайте, кто больше подвержен атаке клиент или сервер. Конечно сервер. Поэтому для обеспечения минимальной безопасности архивов инициировать соединение должна СХД.

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

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

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

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

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

Ну, и остался вопрос именования архивов. Кто-то использует даты в имени и удаляет по устареванию. Я использую цифры и провожу ротацию по одному файлу за раз. Потому что в случае атаки на сервер времени дата-именованные архивы можно потерять за раз.

Для нумерованных архивов для атаки - дату нужно менять несколько раз.

Причем число раз будет зависеть от схемы.

В общем резюмирую:

1. Хороших и плохих схем архивирования не существует - есть такие, которые подходят вам и не подходят.
2. СХД - самая защищенная машина инфраструктуры. Без возможности управления по сети.
3. Есть внешние копии с чередованием, на случай выхода из строя СХД.
4. Архивные копии между СХД и сервером передаются через промежуточную машину.
5. Несколько дневных копий можно ДОПОЛНИТЕЛЬНО хранить на самом рабочем сервере.
6. Используем нумерованные архивы с ротацией.

Холивар в коммментах приветствуется.

tags: #рабочиебудни © by Tagd Tagd

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
74315