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

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

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

Курс: @tormozilla_bot

РКН: https://two.su/bashdays
Download Telegram
Еще один частый затык с гитом — у тебя создана чистая репа в гитлабе и локально на машине лежит уже наработанный проект. Но проект еще не под гитом.

Как заебенить проект в репу в гитлабе?

Первый вариант

Самый беспроигрышный и лёгкий вариант — это склонировать себе эту чистую репу в какую-нибудь папку и затем просто перетащит в эту папку все файлы из твоего проекта.

Приватные репы клонируй через git@, а публичные можешь и через https.

Если попробуешь склонировать приватную репу через https, оно запросит у тебя логин и пароль от учетки гитлаба/гитхаба. Но такие вещи обычно делают на ssh ключах, без хуйни и паролей.

git clone git@gitlab.com:linuxfactory/infra.git


Есть еще хороший хак, если в к конце этой команды добавить символ точки «.» через пробел, то репка склонируется в текущую папку (не будет создана папка infra) НО при условии что папка на локальной машине у тебя пустая, иначе получишь по ебалу ошибку.

Ну а дальше по классике:


git add .
git commit -m "initial commit"
git push


Не забываем что однажды получишь сообщение: Author identity unknown, про этот случай я рассказывал вчера.

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

Второй вариант

cd /path/to/project
git init
git add .
git commit -m "initial commit"
git remote add origin https://gitlab.com/username/reponame.git
git push -u origin master


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

fatal: repository not found
remote: HTTP Basic: Access denied
remote origin already exists
Updates were rejected because the tip of your current branch is behind
error: failed to push some refs


Придется гуглить, делать rebase или вообще конфликты решать. А решать конфликты это то еще удовольствие.

Теперь даже если что-то локально нахуевертил в гите, просто ёбни папку .git в проекте. Сделай все по первому способу и всё починится. Это намного быстрее чем разгребать и дебажить неочевидные ошибки.

tags: #git #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
54
И снова здрасти, продолжаем больные темы.

А еще ребят пиздец напрягает каждый раз делать:

git add .
git commit -m "ебальник убивальник"
git push


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

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

Открываешь ~/.bashrc или чо там у тебя ~/.zshrc и пиздяришь:

alias gg="git add . && git commit -m \"$(date +'%d-%m-%Y %H:%M:%S')\" && git push"


Не забываем сделать source ~/.bashrc && ~/.zshrc. Теперь когда нужно что-то закомитить и отправить. Просто пишем «gg» и дело в шляпе.

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

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

А можно еще прям в конфиге гита сделать алиас

[alias]
cm = "commit -m"


либо командой:

git config --global alias.cm "commit -m"


Тогда команда для коммита будет такая:

git cm "initial commit"


Пример файла с нативными алиасами:

тыкни на блок и он раскроется (это спойлер):

[alias]
a = add
aa = add .
c = commit
cm = commit -m
s = status
pl = pull
pu = push
df = diff
b = branch
bl = branch --all
bd = branch --delete
bD = branch -D
bren = branch -m
bdr = push origin --delete
fa = fetch --all
fp = fetch -p
t = tag
tf = fetch --tags
tpu = push origin --tags
tpuacq = push acquia --tags
td = tag -d
tpur = push origin --delete
tpuacq = push acquia --delete
co = checkout
cob = checkout -b
resh = reset --hard
lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --graph
clear = clean -f -d
clearw = checkout -- .


Нихуя сложного, правда же?

А вообще девопс должен знать всего две основных команды: git push и git pull

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

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

Вот так и живем! Пользуйся!

tags: #git #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
87
Такс, по гиту немного прошлись (но еще вернемся), теперь по ssh ключам. Для многих как оказалось тоже большая проблема. Но это база, поэтому нужно с этим научиться жить. Принять и простить.

Задача — хочу с локальной машины подключиться к серверу по ssh используя ключ.


Смысл тут такой: у тебя есть 2 ключа, один приватный, второй публичный.

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

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

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


А если всё хуева… то отправляемся дебажить, как эффектевно дебажить расскажу попозже.

Давай тыкать. Генерим RSA ключ на своей машине.

Про форматы ключей rsa/dsa напишу также отдельно, пока делаем rsa.

ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/bashdays_rsa


Эта команда сгенерит без лишних вопросов новый ключ и положит его в ~/.ssh/.

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

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

Теперь у тебя в папке ~/.ssh/ два ключа bashdays и bashdays.pub.

Соответственно первый это приватный (храним его как свою жопу), второй это публичный (шлюха ключ).

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

ssh-keygen -y -f ~/.ssh/bashdays_rsa > ~/.ssh/bashdays.pub


Дело в шляпе. Тут самое главное не въебать приватный ключ. Ну а если въебал, сочувствую.

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

Делается так:

ssh-copy-id -i ~/.ssh/bashdays.pub root@server


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

➡️ Важно! Этой командой мы добавили на удаленный сервер ключ для пользователя root.

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

ssh-copy-id -i ~/.ssh/bashdays.pub suchka@server


Тут мы поменяли root на suchka.

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

ssh -i ~/.ssh/bashdays_rsa root@server
ssh -i ~/.ssh/bashdays_rsa suchka@server


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

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

Я обычно не пользуюсь ssh-copy-id, а сразу ручусь на сервер под паролем, руками создаю файл /home/user/.ssh/authorized_keys и в него просто копирую содержимое публичного ключа bashdays.pub.

Но тут есть ряд нюансов. У файла authorized_keys должны быть права 600 или 644. Иначе на сервер не пустят. У меня всегда 600.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys


А еще могут возникнуть проблемы с копипастой, не всегда удается скопировать ключик верно. Поэтому рекомендую сразу привыкать к хорошему и пользоваться ssh-copy-id.

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

cat ~/.ssh/bashdays_rsa.pub | ssh username@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"


Вечерком продолжим. Пока мотай на ус.

tags: #git #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
94
На прохождение Cyber Shadow я потратил 20 часов и сдох 727 раз. Что сказать, моя жопа давно так не горела, со времен Ninja Gaiden на Денди. Но своеобразное удовольствие я всё же получил.

Ладно, сегодня продолжаем серию постов #linuxfactory

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

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

Пиздуем на сервер под рутом, на тот самый куда ты закинул публичную часть ключа и открываем на редактирование файл /etc/ssh/sshd_config.

Активируем эти строчки:

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys


Потом делаем так:

ChallengeResponseAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
PermitRootLogin no
UsePAM no


Отключаем пароли, запрещаем вход под рутом, ну и так по мелочи. Мелочи расписал в комментах.

Тут есть нюанс, при PermitRootLogin no ты иногда все равно сможешь зайти под рутом. Тут все дело в невинном файле который порой пихают из коробки.

/etc/ssh/sshd_config.d/50-cloud-init.conf


Этот файл содержит реврайт, в нем будет PermitRootLogin yes.

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


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

sshd -t
systemctl reload sshd


Если первая команда отработала без ошибок, то запускаем reload.

➡️ Важно! Терминал в котором ты всё это настраиваешь — закрывать не стоит, сессия будет жить даже если накосячил.

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

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


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

Ну и еще про конфиги ssh, на сервере есть пару похожих конфигов, их часто путают и делают хуйню.

/etc/ssh/ssh_config
/etc/ssh/sshd_config


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

А второй соответственно это серверные настройки. Твоя локальная машина это клиент, подключается к серверу, сервер берет настройки из /etc/ssh/sshd_config.

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

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

Увидимся, это еще далеко не всё.

tags: #git #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
79
Скинул мне как-то давненько NPC свой ssh ключ, чтобы я прописал его на сервере. Смотрю я на этот ключик и понять не могу — ты блядь через что это сделал?

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAAAAAwA...


И был он гораздо короче тех к которым я привык. Всего 256 бит. А привык я естественно к RSA.

Хуйня! Чем короче тем уязвимее — подумал я и запросил нормальный, тот который ssh-rsa.

Ну а потом спустя какое-то время проресерчив тему, узнал что ed25519 это всего лишь один из видов ключей которые можно пропихать в ~/.ssh/authorized_keys. И всё будет работать!

Причем такой ключ гораздо надежнее чем легаси rsa. Короче не значит хуёвее.

Распространенные типы ключей:

rsa, ecdsa, ed25519, dsa (устаревший), может что-то еще существует, хуй знает, не интересовался.

ssh-rsa AAAAB3NzaC1yc2EAAAABIw...
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTI...
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICm8x...
ssh-dss AAAAB3NzaC1kc3MAAACBAPnsfNOnD...


Чтобы сгенерить такие ключи, нужно прописать их тип в параметр -t

ssh-keygen -t dsa -f ~/.ssh/bashdays_dsa


А дальше делаем всё как написано тут и тут и ходим на сервер по ключам.

Почему «короче» не значит хуёвее?

Давай сразу на примерах.

Представь, что у тебя есть два лабиринта:

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

- В другом лабиринте (хуи дроченые) тебе нужно найти точку на сложной кривой, которая соответствует определенному числу (ED25519).


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

А вот лабиринт с эллиптической кривой (ED25519) будет гораздо более сложным для прохождения, даже если его размеры кажутся меньше, потому что для нахождения решения требуется гораздо больше вычислений. Хотя ED25519 ключ меньше по размеру (256 бит против 2048 бит в RSA), его решение гораздо сложнее из-за самой природы криптографии.

🅰️🅰️

Есть еще ключи в формате ppk, это те ключи которые можно сгенерить с помощью ебанутого PuTTYgen.

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

Чтобы сконвертить такой ppk в нормальный ключ openssh, в самой морде PuTTYgen нужно сделать экспорт:

"Conversions" → "Export OpenSSH Key"


Либо через командную строку:

sudo apt update
sudo apt install putty-tools

puttygen bashdays.ppk -O private-openssh -o id_ed25519
ssh-keygen -y -f id_ed25519 > id_ed25519.pub


Устанавливаем нужный софт, конвертируем, высекаем публичный ключ.

🅰️🅰️

Для меня ed25519 всё равно чуждый, привык что-ли я к rsa, поэтому предпочитаю именно его. Ну а ты сразу привыкай к хорошему.

ED25519 кстати нормально поддерживается в gitlab/github/gitea и отлично подходит для высоконагруженных систем и аутентификации.

tags: #git #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
495
Вот сделал ты все как написано тут и тут и тут, сгенерил ключи и подготовил сервера, но сука все равно что-то какая-то шляпа:

Искал медь, обосрал медведь…

ssh user@server

Permission denied (publickey).


Что я делаю не так?

Всё правильно, твой ssh клиент не знает, что ты пытаешься подключиться по ключам. Он идет на сервер по дефолту и ожидает что запросят пароль.

А вход по паролям-то мы отключили!

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

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


Не ссым, все уже придумали за нас.

➡️ Первый вариант:

ssh -i ~/.ssh/bashdays_rsa user@server


Через ключ -i указываем путь до своего ключа и со свистом залетаем на сервер.

Теперь твой клиент знает — ага, эта бестолочь догадалась указать ключ, ну ок, прогнусь.

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

➡️ Второй вариант:

Захуячиваем ssh-agent

sudo apt-get update
sudo apt-get install openssh-client


Запускаем агент в фоне:

eval "$(ssh-agent -s)"


И добавляем в него нужные ключи:

ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/bashdays_rsa
ssh-add ~/.ssh/ed25519


Смотрим что у нас торчит в агенте:

ssh-add -L


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

Прикол с агентом:

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

Не прикол с агентом:

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

Решение:

Хуярим в ~/.profile (или чо там у тебя) такую конструкцию:

if [ -z "$SSH_AUTH_SOCK" ]; then
eval $(ssh-agent -s) > ~/.ssh/ssh-agent
fi

ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/bashdays_rsa
ssh-add ~/.ssh/ed25519


Теперь при открытии консоли, у тебя будет автоматически запускаться ssh-agent и добавляться нужные ключи.

Для zsh, в конфиге ~/.zshrc прописываем:

plugins=(git ssh-agent)

zstyle :omz:plugins:ssh-agent agent-forwarding on
zstyle :omz:plugins:ssh-agent identities id_rsa bashdays_rsa ed25519
zstyle :omz:plugins:ssh-agent lifetime


Включаем плагин ssh-agent и добавляем все нужные ключи. Теперь из коробки у тебя будет работать агент и в нем будут подгружены ключи.

➡️ Третий вариант:

Через конфиг ~/.ssh/config, открываем этот файл у себя на машине и пишем:

Host bashdays.ru
Hostname bashdays.ru
IdentityFile /home/user/.ssh/bashdays_rsa


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

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

Например, так:

Host github.com
Hostname github.com
IdentityFile ~/.ssh/id_ed25519

Host github.com-bashdays
Hostname github.com
IdentityFile ~/.ssh/bashdays_rsa


➡️ Четвертый вариант:

Сделать алиасы:

alias stage='ssh -i ~/.ssh/bashdays_rsa user@server'
alias prod='ssh -i ~/.ssh/id_ed25519 root@server'


И потом просто в консольке вбивать stage или prod, все автоматически подставится.

🅰️🅰️
Я использую все варианты, в зависимости от ситуации, но в предпочтениях у меня ssh-agent и алиасы.

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

Через конфиг ansible.cfg:

[defaults]
private_key_file = ~/.ssh/bashdays_rsa


Через переменную окружения:

export ANSIBLE_PRIVATE_KEY_FILE=~/.ssh/bashdays_rsa


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

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

С пятницей друзья!

tags: #git #devops #ssh #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
80
Такс, теперь в тему как отлаживать ssh подключения к серверу. К примеру ты все прописал и сделал как тут #linuxfactory, а оно все равно тебя не пускает по ключам.

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

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

Маунтишь корневой раздел и откатываешь конфиги. Заходишь в конфиги (/etc/sshd/) руками и просто откатываешь, то что ты там закомментировал.

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

Запускай команду:

tail -f /var/log/auth.log


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

В 100% там будет ошибка, которая элементарно гуглится. Обычно это просто проблемы с правами на файл ~/.ssh/authorized_keys или папку ~/.ssh/.

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

Распространенные ошибки:

Invalid user
bad ownership or modes for /home/<username>/.ssh
Authentication failed
Connection closed by remote host
Permission denied
Too many authentication failures
Connection refused
PAM authentication errors
User not allowed
Host key verification failed
SSH protocol mismatch
Banner errors
Brute-force attempts
Timeout
Subsystem errors
Resource temporarily unavailable


Не ссым читать логи и находить нужное. А как только нашел что-то вменяемое — гуглим или скармливаем GPT (как ты любишь).

Кстати китайцы тут DeepSeek запустили, мол убийца GPT. Бесплатная и работает в РФ без приколов. Домашку ребенку решать милое дело.


tags: #git #devops #ssh #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
35
Еще немного про отладку ssh ключей, но уже в контексте интеграции со всякими гитлабами/гитхабами.

Чтобы работать с приватными репами ты добавляешь в настройки гитлаба/гитхаба свою публичную часть ключа.

Хорошо если такой ключ один, запутаться особо негде.

Но что если добавлено 20-100 ключей?

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


Ты проверяешь, видишь в табличке «Заголовок» — gitlab-runner-1 и вроде всё хорошо, ключ прописан и в раннере его приватная часть есть. Чо за хуйня?

Тут нам и пригодится команда:

ssh-keygen -l -E md5 -f ~/.ssh/id_rsa


Выполняем ее для ключа с которым подключаемся (работает и для приватной и публичной части одинаково).

И по итогу видим фингерпринт, отпечаток:

2048 MD5:03:62:23:ca:ce:1b:8c:ad:60:1f:66:16:05:43:d8:a7 shuba@server (RSA)


Сравниваем этот отпечаток с тем что прописан в гитлабе/гитхабе и видим что он НЕ совпадает.

А это значит что твой раннер использует не тот приватный ключ для подключения.


Фиксим и радуемся. Как фиксить? Прописать актуальную публичную часть ключа в гитлаб/гитхаб. Дело закрыто.

tags: #git #devops #ssh #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
46
Еще один частый вопрос с LF — а нужно ли менять дефолтный ssh (22) порт на какой-то другой?

Нет! Ну а нахуя? Сократить в логах количество записей про неудачные попытки подломить твой девственный сервак?

В логи ты ходишь — практически никогда! Тем более там logrotate работает и место диске сильно не забьется.

Предположим ты поменял 22 на 2222. Количество записей в логах «сократилось» и теперь ты ебешься с указанием порта.

ssh -p2222 user@server


Охуеть как удобно! Ты скажешь - дак можно же в ~/.ssh/config все это прописать и всё вернуть на свои места.

Host bashdays.ru
HostName bashdays.ru
User user
IdentityFile ~/.ssh/shuba
Port 2222


Справедливо. Но зачем жертвовать своим удобством?

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

Пусть эти писька-боты долбятся и дальше в жопы. Накрайняк воткни fail2ban и устрой им веселую жизу.

Да и боты сейчас умные, если они видят закрытый 22 порт, они сделают nmap -Pn, по итогу получат твой 2222 и продолжат долбиться.

Как не прячься, все равно тебя найдут и насрут в логи.

Получается все манипуляции с портом это бесполезные телодвижения в ущерб удобства.

Соблюдай базовые правила безопасности и всё с твоими серверами будет хорошо.

- отключи вход по паролю
- перейди на ssh ключи
- запрети вход для рута


За всю свою практику я встретил только одну компанию, где меняли 22 порт на какой-то другой, но никакой смысловой нагрузки в этом не было. Так и так эту компанию подломили и спиздили базу данных.

Да, еще был компания, где 22 порт открывался через port knocking. То есть нужно было предварительно стукнуться на 3 определенных порта и если последовательность была соблюдена, то открывался 22 порт.

Ну тоже такое себе решение в ущерб удобства. Любят люди из пушки по воробьям стрелять.

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

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

tags: #devops #ssh #linuxfactory #security

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
187
Очередные грабли на которые в LF многие наступили.

Есть nginx с такой конфигурацией:

server {
listen 80;
server_name _;

location /app {
proxy_pass http://localhost:5000;
}
}


И есть приложение:

from flask import
Flask app = Flask(__name__)

@app.route('/')

def hello():
return 'Привет, Linux Factory!'

if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)


Плюс к нему 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 bashdays .
docker run -d -p 5000:5000 bashdays


Идем в браузере на http://bashdays.ru/app и получаем хуй с маслом:

Not Found. The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.


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

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

А что случилось? Всёж верно? Локейшен в nginx прописан, прокси-пасс тоже присутствует, где ответ от приложения?

Все дело в слэшах!

 location /app {
proxy_pass http://localhost:5000/;
}


В конце порта 5000 ставим слэш и проверяем. Хуяк и оно начинает работать!

Что вообще происходит?

Когда мы делаем локейшен без последнего слэша в прокси-пассе, nginx проксирует запросы на приложение без изменения пути.

То есть приложение app.py получает роут /app а его там естественно нет. А есть просто корень /.

А когда мы добавляем слэш, nginx добавляет путь после /app к целевому урлу.

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

➡️ Без слэша запрос /app проксируется на http://localhost:5000/app, что не совпадает с маршрутом, настроенным в Flask.

➡️ С слэшем запрос /app проксируется на http://localhost:5000, и приложение Flask обслуживает его как корневой путь /.

В общем с конечным слэшем nginx «удаляет» часть пути /app и отправляет запрос на корень приложения Flask.

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

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

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

tags: #nginx #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
115
Вчера многие обратили внимание на конструкцию в nginx:

server_name _;


Что это блядь за «чёрточка» вместо сервер_нейма?

Если техническим языком — это подстановочное имя хоста.

Пусть на сервере прописано так:

server {
listen 80;
server_name _;
return 444;
}

server {
listen 80;
server_name bashdays.ru;
return 200;
}

server {
listen 80;
server_name linuxfactory.ru;
return 200;
}


Если в браузере откроем bashdays.ru или linuxfactory.ru, то получим статус 200.

А как получить 444, тот самый с «чёрточкой»?

Просто! Например, зайти на сервер по его IP адресу. Nginx не сможет сопоставить доменные имена, которые прописаны в конфиге и отдаст статус 444.

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

Обычно эту «чёрточку» прописывают в файле defaults, чтобы тем, кто попал на сервер по IP адресу увидел, то что ты захочешь, а не рандомный сайт который у тебя висит на сервере.

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

А в сочетании с return 444 (No Response) используется для закрытия нежелательных запросов или для обработки некорректных запросов.

Если «чёрточка» не используется, то вместо неё можно просто прописать default_server в директиве listen, и блок будет работать аналогично.

server {
listen 80 default_server;
return 444;
}


Символ _ не имеет специального значения в самом Nginx. Это просто удобное соглашение, принятое сообществом.


Вот так вот и живём, изучай!

tags: #nginx #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
179
Сегодня будем запирать врата ада.

Ситуация: Есть физический сервер, на нём торчит само собой Linux, к нему подключен монитор и кнопки. Короче можно физически подойти к этой машине и ввести логин/пароль.

Ну или при желании понажимать ALT+F1, F2, F3 (чтобы переключать tty).

Надеюсь ты понял о чем я тебе говорю. Ну дак вот!

Задача: Нужно запретить физический вход по логину/паролю, но оставить вход по ssh с ключами.

Как настраивать все эти ключи можешь почитать в серии постов по тэгу: #linuxfactory

Давай теперь отключим физический доступ к tty.

Заходим на сервер и смотрим юниты

systemctl list-units | grep getty


В ответ получаем список активных tty

getty@tty1.service
getty@tty2.service
getty@tty3.service
getty@tty4.service


getty (сокращение от get tty) — это программа в Linux и Unix-подобных системах, которая отвечает за управление терминалами и логин-процессом для пользователей, подключающихся к системе через консоль.


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

systemctl disable getty@tty{1..10}.service
systemctl stop getty@tty{1..10}.service


Всё! Песда! Терминал становится черным, интерактивность потеряна.

Пробуем понажимать ALT+F1, F2, F3 — хуй там плавал!

Перезагружаем сервер и НИЧЕГО! Черная дыра! Пробуем подключиться к серверу по ssh — ХА! Работает сучка!

При отключении getty для терминалов tty1–tty10, это не повлияет на SSH-доступ, так как SSH-сервер работает независимо от getty.


Теперь даже имея физический доступ к серверу, ты нихуя с ним сделать не сможешь. Максимум загрузиться в Recovery mode и починить:

sudo mount /dev/sdXn /mnt
sudo chroot /mnt
sudo systemctl enable getty@tty{1..10}.service
sudo systemctl start getty@tty{1..10}.service


Вот такие приколюхи! Как и где это применять решай сам. Развлекайся.

Про Magic SysRq в Linux писал тут.

Чем терминал отличается от консоли писал тут


tags: #linux #devops

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
1097
Использовать ssh ключи очень удобно, при условии если у тебя в наличии 2-5-10 серверов

А как жить в ситуации когда у тебя 100500 серверов и еще 100500 пользователей?

Этож нужно за всем этим следить, обновлять и отзывать неактуальны (проёбанные) ключи. Всё скатывается в ужасную рутину.

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

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

Центр сертификации (CA).

Работает он так:

1. Ты настраиваешь CA которому доверяют все твои 100500 серверов.
2. Сертификат подписывает ключи пользователей с указанием сроков действия и ограничений.
3. Если сотрудник покидает команду, ты просто отзываешь сертификат, а не удаляешь ключи с каждого сервера.

Давай замутим:

Берем какуюнить линукс машину и делаем из него CA.

ssh-keygen -t rsa -b 4096 -f ~/.ssh/ssh_ca -C "SSH Certificate Authority"


Описывать за что отвечают параметры не буду, всё это уже разжевали, читай посты по тегу #linuxfactory


По итогу получаем 2 ключа, ssh_ca (приватный) и ssh_ca.pub (публичный).

Дальше чтобы сервера могли доверять сертификатам, подписанным нашим CA, добавляем публичный ключ CA (ssh_ca.pub) на все 100500 серверов.

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


Покажу в рамках одного сервера:

scp ~/.ssh/ssh_ca.pub user@bashdays:/etc/ssh/


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

Открываем конфиг /etc/ssh/sshd_config

И пишем в него:

TrustedUserCAKeys /etc/ssh/ssh_ca.pub


Не забываем хуйнуть:

sudo systemctl restart ssh


Теперь сервер будет доверять сертификатам подписанным CA.

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

Для этого копируем на CA машину свой локальный публичный ключ. Тот что у тебя на машине лежит и который ты прописывал ранее в authorized_keys на удаленных серверах.

Подписываем публичный ключ и превращаем его в сертификат.

ssh-keygen -s ~/.ssh/ssh_ca -I "user_cert" -n user -V +1w /tmp/user_key.pub


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

Signed user key /tmp/user_key-cert.pub: id "user_cert" serial 0 for username valid from 2025-02-16T12:02:00 to 2025-02-23T12:02:59


И в папке /tmp появляется файл user_key-cert.pub

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

 error: Certificate invalid: name is not a listed principal


Забираем себе на локальную машину подписанный ключ и пробуем подключиться:

ssh -i ~/.ssh/id_rsa -o CertificateFile=~/.ssh/user_key-cert.pub root@bashdays.com


Вуаля, я залетаю на сервер с подписанным ssh ключом, а на удаленном сервере вижу в логах:

2025-02-16  sshd[958704]: Accepted publickey for root from 11.11.11.11 port 35528 ssh2: RSA-CERT SHA256:Q4SKZ5cRycm79w0SyvRhAQR8 ID user_cert (serial 0) CA RSA SHA256:PtNBUw/+4/gGz4rc/ybu/uNHngcI


Если что-то не получается или не даёт зайти, пиздуешь на сервер к которому подключается и смотришь логи var/logs/auth.log. В этом файле тебе очень информативно подскажут что погуглить.


И да, на удаленном сервере можно снести файл ~/.ssh/authorized_keys от тебе больше не пригодится. Потому что сервак начинает доверять всем ключам, которые подписаны через CA.

Ну а теперь давай отзовем сертификат с ключа

На сервере к которому ты настраивал подключение:

touch /etc/ssh/revoked_certs


В файле /etc/ssh/sshd_config добавляем:

RevokedKeys /etc/ssh/revoked_certs


Добавляем серт в этот файл с отзывами:

ssh-keygen -k -f /etc/ssh/revoked_certs -z 1 user_key-cert.pub


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

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

Завтра про Vault Hashicorp расскажу, в нем все проще делается

tags: #linux #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
2118
Здрасти, сегодня продолжаем издеваться над ssh.

Давай прикрутим 2FA.

Идем на сервер к которому хотим подключmся по ssh и ставим пакеты:

sudo apt update
sudo apt install libpam-google-authenticator


Запускаем конфигуратор:

google-authenticator


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

После запуска конфигуратора, получишь по ебалу:

Do you want authentication tokens to be time-based (y/n)


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

Можно еще всякие ключики использовать:

google-authenticator -t -f -d -w 3 -e 5 -r 3 -R 60


Если интересно: google-authenticator --help

Всю эту инфу куданить себе скопируй чтоб не проебаться.

Дальше сканируем этот QR код, либо берем секретный ключ который он тебе выплюнул и вставляем в vaultwarden в TOTP или на телефоне в апку добавляем.

Тот самый секретный ключ:

Your new secret key is: MAIY4KDCXKWHPDCI


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

После этого оно выплюнет тебе рекавери коды, ну и спросит:

Do you want me to update your "/root/.google_authenticator" file?

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks

и другие


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

В файл /root/.google_authenticator сохранится секретный ключ и коды восстановления. Этот файл не трогаем, без него тоже нихуя не заработает.

Теперь открываем файл /etc/pam.d/sshd

И добавляем в него строчку:

# @include common-auth
auth required pam_google_authenticator.so


По необходимости комментим common-auth если ничего не работает. Есть вариант не комментить, но тогда нужно правильно настроить common-auth, но у нас сегодня не про это.

Закомментировав этот модуль ты отключаешь стандартные механизмы аутентификации и даешь зеленый свет на использование pam_google_authenticator.

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

Дальше добавляем в конфиг: /etc/ssh/sshd_config

UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
PubkeyAuthentication yes
AuthenticationMethods publickey,keyboard-interactive


Вот и всё, настройка 2FA завершена.

Рестартим:

sudo systemctl restart ssh


И пробуем подключиться по ssh к этому серверу:

ssh root@bashdays.ru

(root@bashdays.ru) Verification code:


Ха! А что вводить? Это и есть 2FA, сюда вводим одноразовый код который выплюнул тебе vaultwarden либо аппка на телефоне.

Всё! Залетаем спокойно на сервер. Без кода и ключа хуй ты теперь чо сделаешь.

Как использовать резервные коды?

Да также при запросе в Verification code. НО из файла /root/.google_authenticator они будут отлетать. Тут тоже аккуратнее.

Также можешь включать 2FA для конкретных пользователей, в конфиге /etc/ssh/sshd_config

Match User <имя юзера>
AuthenticationMethods publickey,keyboard-interactive


Настроек там жопой кушай, я тебе лишь концепт показал как эту хуйню можно быстренько настроить.

А как работать с 2FA и QR кодами из консоли, можешь почитать тут.


Главное не спеши и делай всё вдумчиво, чтобы не проебать доступ к серверу. Ну а если все проебал, да и хуй с ним, ебани кофейка и мультики посмотри.

tags: #linux #devops #linuxfactory

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
67
Что делать если я проебал приватный ssh ключ?

Самое главное не ссать!

Если ты рядовой разработчик/qa/cto/шлюха, напиши своему девопс инженеру чтобы прописал новый публичный ключик.

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

Пусть знают с кем связались — бабуины прямоходящие! 🙈

Человек как меч, либо делает свою работу либо тупой.


Тебя конечно же проклянут, но спустя какое-то время ключик пропишут. Доступ к серверам восстановлен. Профит чо!

Это прям идеальный исход событий.

Но если ты и есть девопс инженер да еще и один единственный в команде, то у тебя бааальшие проблемы!

Пеню, все решаемо, напомню — не ссать!

Варианты решения:

➡️ Вариант №1

Если ты осел и у тебя все еще включен доступ по паролю, то зайди на сервер по паролю. Но в 99999999% ты пароль не записал, либо просто его не знаешь/проебал.

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

У Селектела и AEZA такая возможность есть.

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

Через KVM сразу можешь отредачить ssh конфиг и включить доступ по паролю, потом комфортно подключиться к серверу так ssh root@server и добавить свои новые ключики.

Это самый трушный вариант, но работает не всегда + иногда требуется перезагрузка сервера, а это не допустимо.

Про ssh ключи, конфиги и прочее читай по тегу #linuxfactory


➡️ Вариант №2

Если у тебя есть какие-то другие доступы к серверу, например у тебя там поднят IPMI, VNC.

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

➡️ Вариант №3

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

➡️ Вариант №4

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

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

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

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

➡️ Вариант №5

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

Физический доступ к сервакам обычно редкость, но опять же в Селектеле я такое делал много раз через веб-морду, там прям есть пунктик — Rescue Mode. Про аезу не скажу (аеза нас читает, пусть прокомментирует), пока не приходилось с этим сталкиваться.

Минус — придется перезагружать сервер. Будет даун тайм и тебя за это очень быстро выебут (если это какойнить прод).

➡️ Вариант №6

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

Как говорится — Хуем в ладошку и вперёд в путь дорожку!


🙃 Если хочешь проникнуться Ансиблом/Гитлабом/Докером — велком в наш пантеон.

➡️ Вариант №7

➡️ А это твой вариант, напиши про него в комменты.

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

Спасибо за внимание и хороших предстоящих выходных!

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

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
55
Такс, как и обещал притаранил тебе рабочий пайплайн для авто деплоя mkdocs через gitea.

Чтобы всё это заработало, в проекте тебе нужно создать структуру:

.gitea/workflows/deploy.yml


Файл можешь обозвать как угодно.

name: Build and Deploy Bashdays Blog

on:
push:
branches:
- main

jobs:
build:
runs-on: super-runner
container:
image: catthehacker/ubuntu:act-22.04

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install dependencies and build
run: |
pip install -r requirements.txt
mkdocs build

- name: Deploy to Server
uses: https://gitea.com/aquelle1/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
ARGS: "-rlgoDzvc -i --delete"
SOURCE: "site/"
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ secrets.REMOTE_TARGET }}


Давай пробежимся:

Триггер on: push: запускается если что-то запушено в ветку main.

Почему в main а не в master? Читай тут.


Следом запускается джоба build на раннере super-runner, не забываем зарегать себе раннер, без него нихуя не получится.

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


Дальше используем адаптированный контейнер с убунтой 22.04 специально адаптированный под тестирование GitHub Actions через act.

Почему GitHub Actions? Потому что gitea унаследовало синтаксис и пайплайны в теории могут переносится между системами.

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

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

После сборки идет секция с деплоем, я использую этот экшен. Основан он на rsync поверх ssh.

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

SSH_PRIVATE_KEY = Приватный ssh ключ с которым раннер пойдет на твой сервер и подключиться по ssh к нему. Соответственно публичная часть ключа должна быть прописана у пользователя на сервере в файле ~/.ssh/authorized_keys.

Как работать с ssh ключами, читай по тегу #linuxfactory


ARGS = Аргументы для rsync, рекурсивное копирование, сохранение прав доступа, удаление файлов которые не в локальной версии.

SOURCE = Какой каталог со статикой отправляем. В Mkdocs статика генерится по умолчанию в папку site.

REMOTE_HOST & REMOTE_USER = Айпишник или домен продакшена на который деплоим + имя пользователя под которым подключаемся к серверу.

TARGET = В какую папку на проде скинуть содержимое папки site.

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

Вот и всё. Теперь при пуше в main ветку, автоматически запустится пайплайн и на прод выкатятся изменения.

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

Короче хорошего тебе вечера, теперь уже до завтра!

tags: #devops #cicd

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
51
Как из РФ создать новую учётку в Gitlab

У ребят в Linux Factory довольно часто возникает вопрос — а как зарегистрировать новую учетку в Gitlab?

Онож там и карту просит и смс и еще хуй пойми чего.

Вариантов есть много, но работают они 50 на 50. У кого-то работает одно, у кого-то другое, но нет золотой середины.

Сейчас я покажу 100% рабочий вариант.

Регистрируешься в Putsbox. Это сервис для временных почтовых ящиков. Проверен лично мной годами, никогда не косячит.

Про этот сервис я как-то давненько рассказывал здесь.


Тут важно зарегистрироваться, а не просто создать новый ящик.

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

Короче регаешься в putsbox, входишь в учетку и создаешь почтовый ящик.

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

После регистрации на ящик в putsbox приходит код с подтверждением, подтверждаешь. Закрываешь TOR Browser.

Идешь в свой браузер и без проблем залетаешь в Gitlab под новой учёткой.

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

А если запуск пайплайнов требуют верификации, то читаем этот пост.


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

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


Такие дела, тыкай, изучай.

🛠 #linuxfactory #gitlab #services

@bashdays / @linuxfactory / @blog
Please open Telegram to view this post
VIEW IN TELEGRAM
646
Очередные грабли. При клонировании Linux машин, клонированные машины получают по DHCP тот же IP адрес, что и донор. Возникает конфликт интересов.

Проблема распространенная, лечится довольно просто.

1. Меняем MAC адреса на клонах
2. Меняем machine-id на клонах

В первом случае всё просто, делается через морду VBox, либо через консольные команды:

ip link
sudo ip link set dev eth0 down
sudo ip link set dev eth0 address 00:11:22:33:44:55
sudo ip link set dev eth0 up


Новый MAC адрес можешь сгенерить такой командой:

printf '02:%02x:%02x:%02x:%02x:%02x\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))


Во втором случае это файл /etc/machine-id, в нем хранится уникальный идентификатор машины.

ed76c4f179044828b51028aadf9f4981


Удаляем и генерим новый machine-id:

sudo rm /etc/machine-id sudo systemd-machine-id-setup


Перезапускаем виртуальную машину. DHCP выдаёт этой машине новый IP адрес, который не будет конфликтовать с донором.

Вот и вся наука. Пользуйся.

🛠 #linux #linuxfactory

@bashdays / @linuxfactory / @blog
Please open Telegram to view this post
VIEW IN TELEGRAM
85
Распространенный случай в пайплайнах, как ребята пишут в LF:

deploy:
stage: deploy
script:
- ssh ${USER}@${HOST} "docker pull"
- ssh ${USER}@${HOST} "docker down"
- ssh ${USER}@${HOST} "docker up -d"
- ssh ${USER}@${HOST} "....."


🔥 Как и обещал. С сегодняшнего дня в Linux Factory действуют летние скидки. Кто ждал, велком.


То есть на каждую команду, создается отдельная SSH сессий. В большинстве случаев у тебя всё будет работать, но порой можно наступить на грабли.

На сервере может быть установлены лимиты в ssh_configMaxSessions, а плюсом еще работает Fail2ban или нечто подобное.

И по итогу пайплайн будет вечно делать хуйню, внезапно падать и т.п.

Что делать?

Передать команды в рамках одной сессии.

Например, так:

script:
- |
ssh ${USER}@${HOST} << EOF
docker pull ...
docker down ...
docker up -d ...
...
EOF


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


Либо пропихать так:

script:
- ssh ${USER}@${HOST} "docker pull ...; docker down ...; ..."


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

Учись сразу делать нормально и учитывать такие моменты.

Ну и с праздником тебя и твоих ребятишек!

🛠 #devops #linuxfactory #cicd

@bashdays / @linuxfactory / @blog
Please open Telegram to view this post
VIEW IN TELEGRAM
781
Довольно частый вопрос с LFКак жить с gitlab раннерами?

Да просто там всё. Если у тебя основная инфра в кубе, то в кубе и крутим.

Ну а если ламповые сервера, без всей этой кубовой хуйни, то вариантов не много.

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

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

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

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


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

Раннеры можно зарегать на один токен:

Сервер 1

gitlab-runner register \
--url https://gitlab.com/ \
--registration-token ABCDEFG123456 \
--executor docker \
--description "runner-1"


Сервер 2

gitlab-runner register \
--url https://gitlab.com/ \
--registration-token ABCDEFG123456 \
--executor docker \
--description "runner-2"


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

Раннер 1

--description "runner-fast"
--tag-list "docker"


Раннер 2

--description "runner-slow"
--tag-list "docker"


В .gitlab-ci.yml у нас так:

build:
script: echo "Building"
tags:
- docker


Задание пойдет на тот раннер, который раньше освободится. Если оба свободны — гитлаб рандомно сделает выбор, приоритетности нет.

Если важна приоритетность, можно поиграть в юните с параметром GITLAB_RUNNER_PRIORITY.

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


А как деплоить?

Тоже всё просто, ssh/rsync в помощь, раннер подключается к нужному серверу, например по ssh и выполняет все необходимые команды. Затаскивает новый докер образ, стопорит старый, запускает новый.

Как-то так:

deploy:
stage: deploy
script:
- |
ssh $SSH_USER@$SSH_HOST << EOF
docker pull $IMAGE_NAME
docker stop my_app || true
docker rm my_app || true
docker run -d -p 5000:5000 --name my_app $IMAGE_NAME
EOF


Подключаемся под юзером из переменной $SSH_USER к хосту из переменной $SSH_HOST. Ну и запускаем команды.

Важно!

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

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

🛠 #devops #linuxfactory #cicd

@bashdays @linuxfactory @blog
Please open Telegram to view this post
VIEW IN TELEGRAM
454