Линукс и DevOps Дни
2.04K subscribers
108 photos
8 videos
194 links
Самобытно про разработку, devops, linux, скрипты, тестирование, сисадминство, техдирство, пиэмство и за айтишную жизу.
Download Telegram
Здарова! Годнота подъехала!

Если любишь копаться в «кишочках» эта штука тебе обязательно пригодится, называется Binsider.

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

У хорошего девопса и бычий хуй веревка!


Короче это хуйня на расте позволяет анализировать «Эльфов» (ELF бинарники).

- Статический анализ: изучение структуры бинарного файла, включая секции, сегменты, символы и релокации.

- Динамический анализ: выполнение бинарного файла с отслеживанием системных вызовов и сигналов (strace/ltrace).

- Извлечение строк: поиск полезных строк (например, паролей или URL) внутри бинарного файла.

- Шестнадцатеричный дамп: просмотр содержимого файла в виде шестнадцатеричного кода с удобной визуализацией.

Инструкция по установке тут, есть докеры-хуёкеры и т.п.

Я собрал из исходников, делов 30 секунд:

cd /tmp

VERSION="0.1.0"

wget "https://github.com/orhun/binsider/releases/download/v${VERSION}/bins
...
Здрасти. К делу!

Гиту откровенно насрать на права доступа файлов. И после клонирования репы, эти права будут установлены по 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

🔔 ➡️
Богатствуйте!

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

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

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

🔔 ➡️
«Группа Астра» проводит первую бесплатную практическую конференцию для разработчиков Astra DevConf 2024.

Разработчики ИТ-компаний раскроют секреты эффективной и безопасной разработки, а также поделятся практическими кейсами.

На конференции мы:
— расскажем как выстроить процесс разработки на базе Git-системы (конкретные примеры на различных языках и фреймворках);
— покажем, как легко и просто опубликовать ваше приложение в RuStore;
— поделимся лучшими практиками в построении DevOps-процессов для проектов, написанных на Spring Framework и Java/Kotlin;
— расскажем, как осуществить сборку из Dockerfile или Buildpack и развертывание образа на виртуальной машине (пока вы пьете кофе);
— и многое другое.

Для участников конференции будет доступен:
— личный кабинет разработчика, в котором можно бесплатно скачивать решения «Группа Астра» для целей изучения и разработки (в том числе ОС Astra Linux 1.8);
— портал с документацией, где опубликованы различные инструменты для разработки, примеры кода и готовые стенды д...
Аутентификация, авторизация. Навеяло.

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

Хранить лучше в программах типа 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.ru
Input modificator:BashDaysTheBest

pwgen options: -1 --symbols --ambiguous --capitalize
Login: tagd.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

🔔 ➡️
Порой бывает необходимо прям из bash-скрипта добавить/удалить какое-нибудь задание в cron.

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

{ crontab -l; echo '# 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'
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 #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

🔔 ➡️
Привет. Почему-то я думал что сегодня пятница, мда…

Ладно, поехали. Ты всяко встречался с такой ебаной ошибкой при подключении к серверу по 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


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

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


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

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

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

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

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

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

tags: #linux

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

Проблема усугубляется тем, что на сервере нет 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 не понимает опцию (проблема решаемая через /etc/inid.d)

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

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

tags: #bash #linux © by Tagd Tagd

🔔 ➡️
Здрасти. Давай сегодня соберем свой «мета-пакет».

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

Например, я хочу разом поставить 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
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.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

🔔 ➡️
Принцесса для снятия стресса

Привет. Когда ты создаешь новый 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

🔔 ➡️
С пятницей ребят!

Недавно пришло письмо от мейл.ру мол у вас 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: #рабочиебудни

🔔 ➡️
Начало месяца - время делать бэкапы. О бэкапах уже столько сказано, что еще одна статья ничего нового не добавит, но тем не менее позволю себе поделиться своим опытом.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

🔔 ➡️
Не ssh, но близко — sftp.

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

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

Из минусов - может создавать нагрузку на проц. В openssh включен из коробки. Поэтому если есть доступ по ssh - как правило, есть доступ и по sftp.

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

Вот, для этого есть решение — mysecureshell.

Для debian можно поставить:

sudo apt install mysecureshell


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

Возможностью ограничить пользователя только своим каталогом. И еще работа с виртуальными серверами. Рекомендую.

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

cat /etc/shells


А изменить, например так:

sudo usermod -s /usr/bin/mysecureshell username


Конфигурируется данное чудо путем редактирования файла /etc/ssh/sftp_config

Кстати, отлично сочетается с sshfs (монтирование через ssh (по факту через sftp)).

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

Репа Mysecureshell
Документация

tags: #linux #utilites © by Tagd Tagd

🔔 ➡️
Bash генератор OTP для 2FA

Я давненько пользуюсь Authy. Это генератор OTP кодов для 2FA. Большим плюсом было — что этот генератор работал на десктопе.

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

TOTP (Time-based One-Time Password) — это алгоритм, используемый для генерации одноразовых паролей (OTP), которые действуют в течение ограниченного времени.


Короче в мою зону комфорта беспощадно насрали.

Каждое случившиеся гавно это повод изобрести велосипед что-то своё.

Пошло оно всё нахуй! Будем генерить коды Bash скриптом!

Для начала нам понадобится утилита zbar, она позволит из терминала распознать qr код, этот код выдают сервисы где включается 2FA.

Не парься, иксы не нужны, всё работает нативно в терминале.

sudo apt install zbar-tools


Далее пиздуем например в gitlab и включаем 2FA, в ответ оно тебе выплюнет QR код. Делаем скриншот QR и сохраняем.

Запускаем сканер:

zbarimg gitlab_qr.png


В ответ получаем нечто подобное:

QR-Code:otpauth://totp/gitlab.com:gitlab.com_hello%40devopsina.ru?secret=1234567890ABCDEFG&issuer=gitlab.com

scanned 1 barcode symbols from 1 images in 0.02 seconds


Замечательно. Из этой кишки нам нужен только secret=1234567890ABCDEFG.

Устанавливаем вторую утилиту:

sudo apt install oathtool


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

#!/bin/bash

SECRET="1234567890ABCDEFG"
echo "Gitlab 2FA code: $(oathtool --totp -b "$SECRET")"


Запускаем и получаем желаемый OTP код, вводим его в Gitlab и охуеваем. Мы успешно прошли 2FA. Всё работает!

Базу расковыряли. Теперь нужно какое-то человеческое решение. Накидываем еще один bash скрипт:

#!/bin/bash

secrets=(
"GitLab:1234567890ABCDEFG"
"Google:1234567890ABCDEFG"
"Bashdays:1234567890ABCDEFG"
)

for i in "${!secrets[@]}"; do
IFS=":" read -r service secret <<< "${secrets[i]}"
echo "$((i + 1)). $service"
done

read -p "Введите номер сервиса: " choice

if [[ "$choice" -gt 0 && "$choice" -le "${#secrets[@]}" ]]; then
IFS=":" read -r selected_service selected_secret <<< "${secrets[choice - 1]}"
TOTPCODE=$(oathtool --totp -b "$selected_secret")
echo "TOTP код для $selected_service: $TOTPCODE"
else
echo "Неверный выбор."
fi

read -p ""


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

Что-то вроде:

secrets_file="secrets.txt"

while IFS= read -r line; do
secrets+=("$line")
done < "$secrets_file"


Сохраняем получившийся скрипт в qr.sh, делаем алиас если нужно и запускаем. В ответ получаем нумерованный список сервисов:

1. Gitlab
2. Google
3. Bashdays

Введите номер сервиса:


Вводим нужный номер сервиса и получаем актуальный OTP код.

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

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

В общем тут уже полет фантазии, можно и кнопочки прикрутить и другие украшения. Было бы время и желание.

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

Вот такой хуйнёй переодически приходится заниматься.

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

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

🔔 ➡️
Покопавшись с вопросом по SPF из этого поста, решил воспользоваться советом Ivanchos, а именно — для начала выписать все ip которые инклудятся по домену.

Выписал, получилось достаточно много, строчка SPF стала длинной как хуй туземца, размером > 1024 символов.

v=spf1 ip4:178.154.239.164/32 ip4:77.222.53.78/32 ......


Согласно RFC 7208, длина SPF-записи (Sender Policy Framework) не должна превышать 255 символов в одной строке. Однако, если SPF-запись превышает 255 символов, ее можно разбивать на несколько строк, но общая длина записи не должна превышать 512 символов при передаче в DNS.


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

А у меня блядь превышает… 1039!

Попёрся я обратно в SPF Surveyor смотреть. И в самом низу увидел секцию PIDR CIDR IP, где перечислялись диапазоны.

Ёпта, а чо так можно было? Собираю все эти диапазоны в одну строку, благо их там адекватное количество.

v=spf1 
ip4:32.190.247.0/24
ip4:65.233.160.0/19
ip4:64.102.0.0/20
ip4:75.14.192.0/18
ip4:78.125.0.0/16
ip4:103.177.8.0/21
ip4:174.194.0.0/16
ip4:206.85.128.0/17
ip4:213.58.192.0/19
ip4:171.217.0.0/19
ip4:171.217.32.0/20
ip4:171.217.128.0/19
ip4:44.92.0.0/15
ip4:48.107.0.0/16
ip4:81.220.186.0/24
ip4:168.154.239.164/32
~all


Скармливаю сначала в валидатор, а потом уже добавляю в TXT.

Хуяк! И оно работает! Теперь по DNS lookups needed to validate the record получаем - 0/10.

То есть теперь мы вообще не делаем никакие DNS запросы, а чисто сидим на CIDR.

За сутки на почту dmarc@ почти перестали приходить письма с варнингами, да и саппорт пока молчит, почта ходит.

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

Если всё накроется пиздой, я обязательно тебе про это сообщу ))

Всего тебе наилучшего!

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

🔔 ➡️
Так, про aeza, коллизия вышла

aeza.ru - находится в юрисдикции РФ и рассчитан на юридических лиц.
aeza.net - находится в юрисдикции Великобритании.

аккаунты как оказалось не сквозные , все решилось, всем кто принял участие в решении вопроса — спасибо!

Теперь у меня есть прямые контакты, буду теперь заебывать их в личку )
Интересный вопрос сегодня залетел:

Если функции, вынесены в файл, подключенный через source, bash каждый раз его будет открывать/перечитывать при обращении к функции? Или как-то считает в память и все?


Давай посмотрим что происходит в кишках в это время. Давненько мы с тобой в strace не смотрели.

Предположим есть bash скрипт с функциями:

functions.sh

#!/bin/bash

bashdays_function() {
echo "Hello from BashDays"
}


И основной скрипт, который сорсит файл с функциями:

test_script.sh

#!/bin/bash

source ./functions.sh

bashdays_function
bashdays_function


Не забываем сделать: chmod +x test_script.sh

Запускаем test_script.sh под контролем strace:

strace -e trace=openat ./test_script.sh


И видим:


openat(AT_FDCWD, "./test_script.sh", O_RDONLY) = 3
openat(AT_FDCWD, "./functions.sh", O_RDONLY) = 3

Hello from BashDays
Hello from BashDays


То есть в контексте скрипта test_script.sh, файл с функциями был прочитан один раз.

При втором вызове функции всё считалось из памяти.

Если бы файл functions.sh читался каждый раз, то мы увидели бы несколько строчек openat(AT_FDCWD).

Грубо говоря при каждом запуске test_script.sh, подключенный файл через source будет прочитан один раз.

Вроде очевидно, но порой заставляет задуматься.

Изучай!

tags: #bash #debug #linux

🔔 ➡️
Все умрут, а я root!

Еще раз всем здрасти, раз в неделю в рандомный момент буду разыгрывать пиццу 🍕 (1000р). Кто первый в комменты напишет ответ на задачку, тот и забирает приз.

Чуть позже сделаю еще 2 призовых места с шавухой.

Коммент с ответом должен быть к посту, а не в чатике. А далее к тебе приходит Макс, спрашивает номер РФ карты и закидывает пиццу.

У кого не включены уведомления на канал, ну ты сам виноват!

Поехали: 13−6+7 ?

Можешь написать бота, парсить и решать задачки автоматом, но лучше не трать своё время, задачки будут не шаблонные и порой пиздец упоротые.
Сегодня мы рассмотрим одну очень интересную тему. Бывает, что у вас маленькая локалка (/24), или сеть класса D.

И нужно, чтобы у некоторых групп пользователей были разные внешние IP.

Ну, например wi-fi желательно выпускать через отдельный ip, чтобы меньше было проблем типа "из вашей сети исходят подозрительные запросы".

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

А через прокси не каждый софт работает. Ну, в общем, задача понятна.

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


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

pfsense позволяет работать с usb модемами, и подключениями типа pptp, pppoe и другими. Сейчас практически любой домашний роутер может работать как pptp сервер.

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

Добавляем Новые интерфейсы (типа PPP, или что там у вас есть)

Создаем алиасы с группой хостов, которые должны выходить через ip, отличающийся от шлюза по умолчанию. Таких может быть несколько. Например, IP_GATE1 IP_GATE2 IP_GATE3, по одному на каждый шлюз.

Система\Маршрутизация\Шлюзы добавляем шлюзы и в свойствах снимаем галки Мониторинг Шлюзов и Действие Шлюза. Если так не сделать - в случае "отваливания шлюза" умная система перенаправит трафик через шлюз по умолчанию, и на другом конце "засветится" ip шлюза по-умолчанию.

Межсетевой экран\Правила\LAN Для каждой группы создаем два правила:

- Разрешить IPv4 протокол любой Источник IP_GATE1, и в расширенных опциях указываем нужный шлюз (GATE1) (слева на правиле в общем списке правил появится шестеренка)

- Ниже: Блокировать IPv4 протокол любой Источник IP_GATE1.


Для остальных - аналогично. Теперь Группа IP_GATE1 будет выходить через GATE1 или вообще не будет выходить в случае отсутствия инета на GATE1.

Применять исключительно для причинения добра!

tags: #networks © by Tagd Tagd

🔔 ➡️
Сегодня про айпишники.

Допустим покупаешь ты себе облачный vps. Этому серверу автоматически назначается IP адрес, по которому ты можешь подключиться по ssh.

Например у AEZA есть услуга: Добавить IP адрес. То есть к серверу можно привязать 2 айпишника.

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

Смотрим сетевые настройки: /etc/networks

auto ens3
iface ens3 inet static
address 62.60.238.33
netmask 255.255.255.255
gateway 10.0.0.1
dns-nameservers 1.1.1.1 8.8.8.8

auto ens3:0
iface ens3:0 inet static
address 62.60.238.133
netmask 255.255.255.255
dns-nameservers 1.1.1.1 8.8.8.8


Всё логично и красиво. Айпишники прописаны статично, никакого dhcp и плавающих адресов с выходом на роутере.

Если я сделаю так:

curl ifconfig.me


То в выхлопе получу первый IP адрес (62.60.238.33).

Про сервисы вроде ifconfig писал в этом посте.


Но как мне выходить в интернет с конкретного IP адреса?

Можно курлыкнуть так:

curl --interface 62.60.238.133 ifconfig.me
curl --interface ens3:0 ifconfig.me


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

Открываем /etc/networks и комментим блок со вторым IP адресом:

auto lo
iface lo inet loopback

auto ens3
iface ens3 inet static
address 62.60.238.33
netmask 255.255.255.255
gateway 10.0.0.1
dns-nameservers 1.1.1.1 8.8.8.8

# auto ens3:0
# iface ens3:0 inet static
# address 62.60.238.133
# netmask 255.255.255.255
# dns-nameservers 1.1.1.1 8.8.8.8


Далее хуячим в терминале:


ip addr add 62.60.238.133/32 dev ens3

iptables -t nat -A POSTROUTING -o ens3 -m statistic --mode random --probability 0.5 -j SNAT --to-source 62.60.238.33
iptables -t nat -A POSTROUTING -o ens3 -m statistic --mode random --probability 0.5 -j SNAT --to-source 62.60.238.133

ip route flush cache


Добавляем второй айпишник на тот-же интерфейс где уже присвоен айпишник. А правила iptables изменяют исходный IP на с вероятностью 50%, когда пакеты проходят через интерфейс ens3.


Проверяем:

for i in {1..5}; do curl https://ifconfig.me; echo ""; sleep 5; done

62.60.238.33
62.60.238.133
62.60.238.133
62.60.238.33
62.60.238.33


ЗАЕБИСЬ! Теперь наш сервер выходит в интернеты с разных IP адресов.

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

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

Всем спасибо и увидимся!

tags: #networks

🔔 ➡️