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

Ну, еще одна статейка для укрепления нервов.

Напоминаю: БЕЗДУМНАЯ ПРАВКА СИСТЕМНЫХ ФАЙЛОВ МОЖЕТ ПРИВЕСТИ НЕРАБОТОСПОСОБНОСТИ СЕРВЕРА.


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

sudo usermod -L username


Эта команда добавляет знак «!» перед полем пароля, что делает его недопустимым, тем самым блокируя.

Все это дело происходит в файле /etc/shadow, где хранятся зашифрованные пароли пользователей.

Читаем man shadow:

Если поле пароля содержит строку, которая не удовлетворяет требованиям crypt(3), например содержит «!» или, то пользователь не сможет использовать этот пароль unix для входа (но может войти в систему под другими паролями).


Ахренеть. Я тут пользователя блокернул, а он войти может.

Проверяем. Точно, по ssh, через ключ, входит и выходит. Замечательно выходит!

Лирическое отступление: В мане shadow также написано, что пароль вообще может быть пустым, но некоторые программы могут запретить его использование.

Понимаете для чего нужна опция PermitEmptyPasswords в файле /etc/ssh/sshd_config?

Напоминаю, что если установить пользователю оболочку /usr/sbin/nologin, то иногда этот пользователь может получить доступ к файлам через sftp (при установленной подсистеме internal-sftp).

➡️ Что делать для полной блокировки пользователя?

Воспользоваться "оболочкой /usr/bin/false" Она просто возвращает код ошибки.

Резюмирую:

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

/usr/sbin/nologin иногда дает доступ к файлам
/usr/bin/false не дает, стерва.

man usermod shadow sshd_config

tags: #linux #security © by Tagd Tagd

🔔 ➡️
Включаем режим параноика.

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

Но почему-то многие думают, что это касается только ссылок http:// https:// ftp://.

Тут на недавно проскакивала тема про Консольные онлайн Telnet/SSH игры.

Посмотрим на это глазами параноика: Что происходит, когда вы подключаетесь к ссылке вида ssh user.dom. Ну, ничего страшного.

Просто в логах сервера отобразится ваш IP. Ситуация усугубляется, когда вы заходите на ссылку вида ssh addr.dom.

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

Прикиньте, есть ip и уже есть логин. Осталось подобрать пароль. Я бы на месте малышей-плохишей специально рыскал бы по github в поисках всякой прикольной фигни и собирал пары ip/login.

Да и логин, не какой-то там test, а реально используемый - сам по себе ценный ресурс.

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

Прошу прощениt за тему, которая и так всех задолбала.

tags: #linux #security © by Tagd Tagd

🔔 ➡️
Хелоу! А какую команду ты запускаешь первой, когда поднял linux сервак/десктоп (vps/vds, виртулка, бареметал и т.п.)?

У меня руки на автомате вбивают: apt update && apt upgrade && apt install mc.

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

А как делаешь ты? Камон в комменты обсудим, интересно на твои паттерны посмотреть.

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

🔔 ➡️
Здрасти. Как-то я писал про strace и как применять инъекции. Если пропустил, то читай тут и тут.

Ниже скрипт который автоматически прономерует системные вызовы для последующих инъекций.

#!/usr/bin/perl

use strict;
use warnings;

my %numbs;
select STDERR;
while(<STDIN>) {
if( /^[0-9]++\s++([a-z0-9_]++(?=\())/ ) {
my $t = ++$numbs{$1};
s/\s+/ \e[31m$t\e[m /;
die $! if( keys %numbs == 1000 );
}
print;
}
exit(0);


Сохраняем это безобразие в файл num_syscalls и делаем chmod +x, ну а дальше запускаем в связке с strace:

strace -o'|./num_syscalls' -yf sh -c 'ls|cat'


Теперь получаем такой выхлоп:

456107 48 close(3</usr/) = 0
456107 52 rt_sigreturn({mask=[]})
456107 63 openat(AT_FDCWD</usr/local/sbin>)
456107 53 newfstatat(3)
456107 64 openat(AT_FDCWD</usr/local/sbin>)


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

Например, возьмем системный вызов openat, видим 63, 64. Это значит что openat был вызван 64 раза. А newfstatat 53.

Теперь берем нужный номер системного вызова и применяем инъекцию. Как это сделать и для чего, опять же показывал на примерах (ссылки в начале этого поста).

Тема крутая, не нужно ебаться и считать руками.

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

А чтобы получить только трассировку, можно сделать так:

strace -o'|./num_syscalls' -yf ls > /dev/null


Если бесит подсветка, выпили из перловского скрипта управляющий символ «\e[31m\[em».

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

tags: #linux #debug

🔔 ➡️
Мало кто знает что у cloudflare есть фича, которая раньше называлась Argo Tunnel, а сейчас это просто Tunnels. И да, она бесплатная.

А чо делает?

Смотри, к примеру у тебя локально поднят виртуалбокс (proxmox), а в нем крутятся виртуалки. В какой-то момент тебе понадобилось прокинуть эту виртуалку в интернет. А у тебя дома несколько роутеров, NAT, нет белого айпишника, короче полный набор подводных камней и хуйни.

В теории можно прокинуть на роутере порты, задействовать через API привязку динамического IP адреса к домену. Ну или в крайнем случае воспользоваться ngrok и т.п. решениями.

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

Tunnels — позволяет поднять туннель до cloudflare и сделать что-то вроде приватной сети, где все нужные сервисы за NAT в домашней сети ты без труда повесишь на домен и выставишь жопой в интернет. Причем вообще не напрягаясь.


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

Как настроить?

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

Читаем 👇

➡️ Как настроить Tunnels от Cloudflare.

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

Такие дела!

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

🔔 ➡️
За пост спасибо нашему коллеге и подписчику - Страйфи Ленджок


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

X11 Forwarding через SSH

Один из самых простых методов — использование X11 Forwarding через SSH. Для этого достаточно базового пакета openssh. Подключение осуществляется командой:

ssh -X -p [порт] [пользователь]@[IP_сервера]


Флаг -X включает проброс X11. После подключения можно запускать графические приложения, например:
firefox &

Однако этот метод имеет значительные недостатки. Интерфейс и ввод отображаются с заметной задержкой, особенно при воспроизведении видео или работе с 3D-графикой. Это связано с тем, что X11 Forwarding передаёт по сети каждое действие с окном без оптимизации и сжатия данных.

RDP в Docker с поддержкой GPU

Более современный и эффективный подход — использование RDP-сервера в контейнере Docker с поддержкой GPU. Протокол RDP изначально разработан для работы с удалённым рабочим столом через сеть и использует алгоритмы сжатия и кэширования элементов интерфейса.

Для настройки поддержки GPU в Docker необходимо установить драйверы и nvidia-container-toolkit, а затем настроить Docker для работы с GPU Nvidia:

sudo apt install nvidia nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker


Для AMD

sudo apt install "linux-headers-$(uname -r)" "linux-modules-extra-$(uname -r)"
sudo usermod -a -G render,video $LOGNAME
wget https://repo.radeon.com/amdgpu-install/6.2.1/ubuntu/noble/amdgpu-install_6.2.60201-1_all.deb
sudo apt install ./amdgpu-install_6.2.60201-1_all.deb
sudo apt update
sudo apt install amdgpu-dkms rocm
sudo reboot
sudo apt install rocminfo
# Добавить в файле `/etc/environment` PATH="/opt/rocm/bin"
docker run --device=/dev/kfd --device=/dev/dri --security-opt seccomp=unconfined <image>


Здесь:


--device=/dev/kfd — предоставляет доступ к основному интерфейсу вычислений.
--device=/dev/dri — предоставляет доступ к интерфейсу прямого рендеринга.
--security-opt seccomp=unconfined — отключает ограничения seccomp для контейнера, что необходимо для корректной работы с GPU.

Далее запускается контейнер с RDP-сервером, например, с использованием образа. После запуска контейнера можно подключиться к нему с помощью RDP-клиента, такого как Remmina, настроив SSH-туннель для безопасности и сжатия трафика.

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

tags: #linux © by Страйфи Ленджок

🔔 ➡️
Недавно прочитал статью Страйфи Ленджок и решил поделиться многолетним опытом использования rdp.

Сразу оговорюсь, что я пытался использовать rdp на linux для замены виндового сервера при работе с 1с.

OC - debian, потому что в debian rdp есть в репозитариях. А, вообще живет он здесь.

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

sudo apt install xrdp
sudo dpkg-reconfigure xserver-xorg-legacy

# выбрать подключения "от кого угодно"


Все настройки в /etc/xrdp основной файл xrdp.ini .)

В качестве DE использовал XFCE и LXDE по причине малых ресурсов. LXDE - лучше.

В качестве клиента (и на клиенте) использовал xfreerdp из пакета freerdp2-x11.

sudo apt install freerdp2-x11


Пробовал remmina, но она подглюкивает. Проще всего использовать алиас для подключения. У меня такой:

alias rdp='function _rdp(){ xfreerdp /h:700 /w:1300 /cert-ignore /v:"$@";}; _rdp '


700x1300 - размеры окна /cert-ignore - нужно для подключения к виндовым серверам, поскольку они раз в 120? дней меняют сертификаты, и приходится ручками удалять хэш из файла.

Подключаюсь так:

rdp 192.168.1.100

# или так

rdp 192.168.1.100 /u:username


Ну, а теперь опыт использования:

1. Окно аутентификации можно настраивать. (xrdp.ini Поставить логотип конторы и прописать название сервера в заголовке окна. Удобно.)

2. Любит забивать папки пользователей логами (.xsession-errors .xorgxrdp.log) Решается отключением логирования в ini или ссылкой этих файлов в /dev/null.

3. В XFCE проблемы с переключением раскладки клавиатуры при переподключениях.

4. В LXDE проблемы с раскладкой при входе под одним пользователем с разных машин (нужно войти в свойства клавиатуры и выбрать "модель клавиатуры".

5. Firefox, Thunderbird, Libreoffice - работают прекрасно при входе пользователя только по RDP.

6. Программы из п.3 не работают, если тот же пользователь вошел "локально" (винда проблему решает "выбрасыванием" одной сессии).

7. 1с работает плохо. На некоторых серверах наблюдались проблемы с печатью форм (некоторые буквы в НЕКОТОРЫХ формах печатаются квадратиками и накладываются друг на друга). Причем под одним пользователем проблемы, под другим пользователем проблем нет.

8. При подключении с винды при работе с 1с, часто наблюдается "зависание интерфейса" на несколько минут. Что делает работу практически невозможной.

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

➡️ man xfreerdp

tags: #linux #networks © by Tagd Tagd

🔔 ➡️
Не одевай 3.14зду в лапти, она и так смешная

Такс, давай покончим с сигналами реального времени (СРВ) и выйдем на новый уровень написания Bash скриптов, мыж с тобой уже взрослые.

Вчера мы выяснили СРВ имеют условный индекс 34-64 (в разных дистрибутивах может быть по-разному, проверяй)

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

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

Задача: у меня есть серверный процесс, который должен получить уведомление от клиента с некоторыми данными (например, номер задачи).

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


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

Пишем сервер signal_listener.sh

#!/bin/bash

handle_signal() {
echo "Получен сигнал $1"
echo "Переданные данные: $2"
}

trap 'handle_signal SIGRTMIN+0 "Task 1 выполнена"' RTMIN+0
trap 'handle_signal SIGRTMIN+1 "Task 2 выполнена"' RTMIN+1

echo "Слушатель запущен. PID: $$"
echo "Ожидаем сигналы..."

while true; do
sleep 1
done


Пишем клиент signal_sender.sh


#!/bin/bash

if [ $# -ne 2 ]; then
echo "Использование: $0 <PID> <TASK>"
echo "TASK может быть 1 или 2"
exit 1
fi

PID=$1
TASK=$2

if [ "$TASK" -eq 1 ]; then
kill -RTMIN+0 $PID
echo "Отправлен сигнал SIGRTMIN+0 (Task 1) процессу с PID $PID"
elif [ "$TASK" -eq 2 ]; then
kill -RTMIN+1 $PID
echo "Отправлен сигнал SIGRTMIN+1 (Task 2) процессу с PID $PID"
else
echo "Ошибка: TASK должен быть 1 или 2"
exit 1
fi


trap = перехватываем сигналы, для СРВ пишем: RTMIN+0 и RTMIN+1

kill -RTMIN+N = отправляет СРВ. Номер сигнала (например, RTMIN+0) задаёт, какой именно сигнал будет обработан.

chmod +x signal_listener.sh signal_sender.sh


Запускаем первый скрипт, видим его PID:


Слушатель запущен. PID: 20821


Во втором терминале запускаем второй скрипт:

./signal_sender.sh 20821 1

Отправлен сигнал SIGRTMIN+0 (Task 1) процессу с PID 20821


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

После отправки СРВ, в терминале где запускали первый скрипт видим:

Получен сигнал SIGRTMIN+0
Переданные данные: Task 1 выполнена


Вот это нихуя се! То есть signal_sender подключился к процессу 20821 и передал в него данные.

В нашем случае данные это 1 или 2. А скрипт signal_listener успешно это схавал и переварил исходя из логики.

Использование СРВ открывает ОГРОМНЫЕ возможности, чтобы несколько скриптов или приложений взаимодействовали друг с другом на низких уровнях не использую велосипеды и прокладки.


А когда какой сигнал использовать?

Хе… 34-64… Если у тебя не сложная логика, можешь использовать любой индекс в этом диапазоне. Но если логика совсем ебанутая, то логичнее использовать СРВ с разными индексами для передачи данных.

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

Типа такого:

SIGRTMIN+0 (34): "Начать обработку данных"
SIGRTMIN+1 (35): "Обновить конфигурацию"
SIGRTMIN+2 (36): "Выебать медведя в жопу"
SIGRTMIN+3 (37): "Остановить обработку данных"


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

А можно обрабатывать в порядке приоритета. СРВ обрабатываются в порядке их номеров (от SIGRTMIN к SIGRTMAX). Это заебись если у тебя задачи с разным приоритетом.

SIGRTMIN+0: Высший приоритет (аварийная задача)
SIGRTMIN+1: Средний приоритет (регулярные уведомления)
SIGRTMIN+2: Низший приоритет (обновление статистики)


Если сигналы поступают одновременно, сначала обработается SIGRTMIN+0, потом SIGRTMIN+1 и т.д.

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

Если что-то еще вспомню, накидаю отдельным постом.

Удачи тебе и береги себя!

про сигналы писал ранее тут и тут и тут и тут


tags: #linux

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

Сегодня рассмотрим утилиту vlock.

Устанавливается так: apt install vlock

Vlock блокирует виртуальную консоль/ли и требует ввода пароля.

Короче сидишь ты такой, на ascii картинки рукоблудишь в терминале, заходит мамка и ты такой — vlock бля!

Консоль моментально превращается в сообщение — This TTY is now locked. Please press [ENTER] to unlock.

Вот и всё! Это типа WIN+L или как там на маках CMD+CTRL+Q, но только для консоли. Локскрин! На случай если у тебя иксов нет, или ты в серверной живешь.

А чем отличается консоль от терминала я писал в этом посте и да, это не одно и тоже!


Чо там этот vlock умеет?

Основное:

-c lock only this virtual console, allowing user to switch to other virtual consoles.

-a lock all virtual consoles by preventing other users from switching virtual consoles.

-n allocate a new virtual console before locking,implies --all.

-s disable SysRq while consoles are locked to prevent killing vlock with SAK

-t run screen saver plugins after the given amount of time.


🅰️🅰️
Из сочного тут -s отключает сочетания клавиш SysRq, лично не проверял, но будем верить что если на заборе написано — хуй, значит он там есть.
🅰️🅰️

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


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

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

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

Короче я показал, ты почитал. На этом и закончим. Мож где-то пригодится. Давай краба!

tags: #utilites #linux

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

Алгоритм простой. Используем 10 сигналов (SIGRTMIN+0 - SIGRTMIN+7 для передачи битов, SIGRTMIN+8 - признак окончания символа, SIGRTMIN+9 признак окончания сообщения).

Передаются только "единичные биты". SEND_CHAR - "разбирает символ по битам и передает" SEND_MESSAGE - разбирает сообщение по символам и отдает SEND_CHAR.

Сохраняем скрипты, chmod +x serv.sh cli.sh

В одном терминале ./serv.sh (он выдаст что-то вроде Listener process 340527).

В другом терминале ./cli.sh 340527 (нужно подставить ваш номер процесса).

При старте клиент сразу передает серверу сообщение "BashBays" А потом можете передать привет медведю. Пустое сообщение завершает клиента. Сервер останавливается через CTRL-C.

#/bin/bash

#serv.sh

declare -i ASC=0
declare MSG=
declare DELAY=0.01
handle_signal() {
case "$1" in
W) MSG=${MSG}$(printf "\x$(printf %x $ASC)")
ASC=0 ;;
M) echo $MSG;MSG=;;
*) ((ASC+=$1));;
esac
}
#RTMIN=34
trap 'handle_signal 1' RTMIN+0
trap 'handle_signal 2' RTMIN+1
trap 'handle_signal 4' RTMIN+2
trap 'handle_signal 8' RTMIN+3
trap 'handle_signal 16' RTMIN+4
trap 'handle_signal 32' RTMIN+5
trap 'handle_signal 64' RTMIN+6
trap 'handle_signal 128' RTMIN+7
trap 'handle_signal W' RTMIN+8
trap 'handle_signal M' RTMIN+9
echo Listener process $$
while :;do
sleep $DELAY
done


#!/bin/bash

#cli.sh

if [[ -z $1 ]];then
echo Need server PID
exit
fi
declare -ir SERV_PID=$1
declare MESSAGE=BashBays
declare -ir RTM=34

function DELAY(){ sleep 0.02;}

function SEND_CHAR(){
local -i i ASC
CUR_CHAR=${1:-" "}
printf -v ASC "%d" "'$CUR_CHAR"
for i in {0..7};do
if [[ $(($ASC%2)) -eq 1 ]];then
# echo kill '-'$(($i+$RTM)) $SERV_PID
kill '-'$(($i+$RTM)) $SERV_PID
DELAY
fi
((ASC/=2))
done
# echo kill '-'$((8+$RTM)) $SERV_PID
kill '-'$((8+$RTM)) $SERV_PID
DELAY
}
function SEND_MESSAGE(){
local CUR_CHAR
local MESSAGE=${1:-BashDays}
local i
echo Send message \"$MESSAGE\" to Server PID=$SERV_PID
for ((i = 0 ; i < ${#MESSAGE} ; i++));do
SEND_CHAR ${MESSAGE:$i:1}
done
# echo kill '-'$((9+$RTM)) $SERV_PID
kill '-'$((9+$RTM)) $SERV_PID
DELAY
}

while [[ $MESSAGE ]];do
SEND_MESSAGE "$MESSAGE"
read -p "Input new message:" MESSAGE
done


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

1. Обработка сигналов (по крайней мере SIGRTMIN не прерывает выполнение команд bash). Т.е если выполняется sleep 10m. То обработки можно ждать долго.

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

tags: #linux © by Tagd Tagd

🔔 ➡️
В рот мне логи! suqo

Здрасти короче.

Все знают команду cat, но не все знают про tac.

Так, так, так… Чо это?

Этот тот же cat только из Австралии наоборот. Оно выводит содержимое файла или стандартного ввода — в обратном порядке по строкам.

Команда tac входит в состав пакета GNU coreutils, и, как правило, она предустановлена на большинстве Linux-дистрибутивов.


Ща покажу. Есть у нас злой файл:

ножка на ножку и залупа в ладошку
eбутся утки вторые сутки
хуй сосали на вокзале


Запускаем:

tac file.txt

хуй сосали на вокзале
eбутся утки вторые сутки
ножка на ножку и залупа в ладошку


Поняли? Ну либо так:

echo -e "строка 1\nстрока 2\nстрока 3" | tac

строка 3
строка 2
строка 1


А можно прям разделитель указать:

echo "слово1:слово2:слово3" | tac -s ":"

слово3
слово2
слово1


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

Да где хочешь, можешь логи смотреть, можешь в bash скрипты пихать, можешь из csv бигдату собирать и т.п.

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

tags: #utilites #linux

🔔 ➡️
Привет, давай напишем очередной велосипед на Bash.

А напишем мы своё подобие команды cat, но с потоками.

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

Вот что у меня получилось:

#!/bin/bash

file=$1

threads=4

process_line() {
line="$1"
echo $line
}

export -f process_line

fifo="/tmp/fifo"
mkfifo "$fifo"
exec 3<>"$fifo"
rm "$fifo"

for ((i = 0; i < threads; i++)); do
echo >&3
done

while IFS= read -r line; do
read -u 3
{
process_line "$line"
echo >&3
} &
done < "$file"

wait
exec 3>&-


Не забываем chmod +x pcat

Запускать так: ./pcat.sh input.txt

➡️ Теперь разбираемся:

threads указываем количество потоков для чтения текстового файла.

process_line = функция, которая будет обрабатывать строку, у меня это простое echo, но можно накручивать любую логику.

export -f = экспортируем функцию, чтобы функция была доступна в subprocess (этот момент ранее в постах мы с тобой уже разбирали, ссылку не дам, по поиску найдешь если интересно).

fifo = задействуем FIFO для контроля потоков (чуть ниже объясню что это такое за хуйня).

mkfifo = создаём именованный канал /tmp/fifo для контроля количества одновременно запущенных потоков.

for ((i = 0; = заполняем каналы «семафора» чтобы ограничить потоки.

while IFS = читаем файл построчно и обрабатываем строки.

read -u 3 = ждем свободный слот «семафора», каждый поток блокируется до тех пор, пока не освободится место в «семафоре».

wait exec 3>&- = ждем завершение всех потоков

Что такое FIFO?

FIFO = «первым пришёл — первым ушёл».


Представляем ебейшую очередь в магазине:

1. Бабки встают в очередь
2. Первым обслуживают ту бабку, что пришла первой
3. Никто не может сказать — мне только спросить и пройти первым

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

Если ты складываешь книги в стопку и потом начинаешь снимать их, то ты будешь использовать LIFO (Last In, First Out).

Но если ты встал в очередь к кассе — это FIFO.

Думаю ты ты понял, тут все просто.

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

строка4
строка1
строка2
строка3
строка5
строка6


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

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

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

tags: #bash #linux

🔔 ➡️
Добрый вечер, здрасти. За чо купил, за то и продаю.

На повестке — direnv.

Эт полезная хуёвина для расширения оболочки. И она достаточно известна среди населения в загнивающем западе.

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

Грубо говоря — позволяет не засирать .profile всяким дерьмом.

Работает так: перед каждым запуском оно проверяет наличие файла (.envrc или .env) в текущем или родительском каталоге.

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

Работает с большой четверкой: bash, zsh, fish, tcsh

Суть — используем переменные среды для конкретного проекта, не трогая при этом ~/.profile.


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

Для убунты ставится так: apt install direnv

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


Подключаем так, добавляем в ~/.bashrc:

eval "$(direnv hook bash)"


Для других шелов смотрим тут.


Не забываем перечитать файл ~/.bashrc чтобы изменения вступили в силу.

Так, поставили, молодцы! Проверяем чо получилось:

cd /tmp
mkdir my-project

echo ${FOO-bashdays}


На экран выдалось: bashdays

Переменная среды FOO не вывелась, логично, дальше:

echo export FOO=foo > .envrc


Ёпта, ошибка direnv: error /tmp/my-project/.envrc is blocked. Run `direnv allow` to approve its content.

Сработала защита от дурака, которая запретила нам использовать .envrc. Хе, ща пофиксим!

direnv allow .


Во! Лепота!

direnv: loading /tmp/my-project/.envrc
direnv: export +FOO


Повторяем первую команду:

echo ${FOO-bashdays}


Хуяк и получаем: foo

Что и требовалось доказать, direnv отлично справилась с поставленной задачей.

Теперь выходим из проекта и смотрим:

cd ..

direnv: unloading

echo ${FOO-bashdays}


Ииии барабанная дробь, у нас вывелось — bashdays!

Какая же красота и любовь с первого взгляда!

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

➡️ Проект на гитхабе: https://github.com/direnv/direnv

⭐️ Star 12.6k

tags: #bash #linux

🔔 ➡️
Как-то мы с тобой познакомились с etckeeper, ну дак вот, есть еще такая штука — ChezMoi.

Это херня для управления dotfiles (конфигурационными файлами, которые обычно начинаются с точки, например, .bashrc, .vimrc, .gitconfig) на нескольких устройствах.

Я сейчас такие файлы просто в гит руками херачу. Из основного у меня это конфиг для вима и zshrc со всякими алиасами и настройками.

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

На убунту ставится так: snap install chezmoi --classic

Для других операционок мануальчик здесь.

Ну поставили и чо дальше? А дальше запускаем:

chezmoi init


Добавляем например .bashrc

chezmoi add ~/.bashrc


Эта команда скопирует bashrc в ~/.local/share/chezmoi/dot_bashrc

Теперь отредактируй файл:

chezmoi edit ~/.bashrc


И посмотрим изменения:

chezmoi diff


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

Запускаем:

chezmoi -v apply


Нажимаешь к пример «o» = overwrite.

Хоба! И bashrc успешно восстанавливается. Прекрасно!

Теперь как с гитом работать:

chezmoi cd
git add .
git commit -m "Initial commit"


git remote add origin git.com:$GITHUB_USERNAME/dotfiles.git
git branch -M main
git push -u origin main


В принципе стандартная практика, первой командой переходим в каталог ~/.local/share/chezmoi ну а дальше база гита.

Затем на другой машине делаем:

chezmoi init https://github.com/$GITHUB_USERNAME/dotfiles.git


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

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

Сайт проекта: https://www.chezmoi.io/
На гитхабе: https://github.com/twpayne/chezmoi

tags: #utilites #linux

🔔 ➡️
🤩 Пятница — это продакшн, который уже не твоя проблема.

Частенько для установки какого-то софта в линукс, предлагают использовать какой-то snap.

snap install chezmoi


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

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

Короче snap это пакетный менеджер, кто бы мог подумать.

Фишка snap — пакеты работают на любом дистрибутиве Ubuntu, Fedora, Arch, Debian и др. без необходимости адаптации под конкретный дистрибутив.

То есть создается один пакет с софтиной и он подходит под все дистрибутивы. Красота!

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

А еще такой софт запускается в песочнице. Тут безопасники сразу ставят плюсик.

А еще установленные пакеты автоматически обновляются в фоне и они всегда актуальны.

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

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

Ну ты понял… а когда применять apt, а когда snap?

➡️ snap хорошо подходит для:

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

➡️ apt предпочтительнее для:

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

Вот и всё! Не такой snap и страшный. Вечерком еще покажу кое-что интересное (не письку).

tags: #linux

🔔 ➡️
👀 Один рубит - семеро в хуй трýбят!

Попросил сегодня на собесе кандидата зачистить nginx логи. Кандидат на роль девопс (мидл) на вилку 200-250к.

Зачистил rm /var/log/nginx/access.log

Мде блядь… это будет интересно!

Задаю следующий вопрос — Серёжа, а почему файл access.log пропал и больше не появляется? Nginx то в данный момент работает, запросы на него идут.

Где карта Билли? Нам нужна карта!

Внятного ответа не получил, что-то на уровне — он появится спустя сутки, когда logrotate отработает. Дада… будем сутки без логов сидеть. А если нет logrotate?

Короче, если хочешь зачистить файл, есть несколько безопасных способов.

Первый способ:

sudo > /var/log/nginx/access.log


Тут мы перезаписываем лог-файл с помощью оператора редиректа «>».

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

Ключевая фраза — дескриптор не изменится. А когда ты этот файл через rm ёбнул само собой дескриптор потерялся и nginx охуевает.

Второй способ:

sudo truncate -s 0 /var/log/nginx/access.log


-s 0 = обрезать файл до нулевого размера. В этом случае дескриптор также не будет потерян и nginx продолжит писать непотребности.

Третий способ:

Некоторые сервисы, например, apache или nginx, позволяют отправить сигнал процессу для того, чтобы он закрыл текущий лог-файл и открыл новый (сигнал USR1). В этом случае процесс продолжит работать, но логи будут записываться в новый файл.

sudo kill -USR1 <pid>


Где <pid> = PID процесса. После выполнения этой команды файл с логов превратится в access.log.1 и откроется новый access.log.

Четвертый вариант — тот самый logrotate, но его рассматривать не будем.

Я пользуюсь первым вариантом с символом перенаправления «>». Стильно, модно, молодежно!

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

А какие способы обнуления знаешь ты? Про аклкашку не пишите, этот способ знают все.

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

🔔 ➡️
Верной дорогой идёте товарищи...

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

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

Заинтриговал? Мозг немного взорвался? Короче, делаем ssh-прокси.

⁉️ Для чего это нужно?

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

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

Поехали!

Понадобится 2 машины: Бастионная (Jump-сервер, ssh-прокси) - машина, которая торчит открытым портом ssh в интернет.

И Тупиковая - машина (возможно виртуалка), с открытым в локалку портом ssh, на которой будет работать пользователь. И у которой нет доступа в инет (закрыт на периметровом маршрутизаторе. Или не прописаны шлюзы.

Основное условие у пользователя не должно быть root, а то сменит IP/MAC, пропишет шлюзы...). (допустим ее локальный ip 10.10.10.10).

С Бастионной машины должен быть доступ к Тупиковой по ssh, внутри локалки.

НА БАСТИОННОЙ МАШИНЕ. (аутентификация по ключам уже настроена, ssh защищена от быстрого перебора)

1. Заводим пользователя, например, Tagd83j6 с паролем >=20 символов (не пригодится)

2. Добавляем публичный ключ Пользователя. (Он обычно с парольной фразой) в ~/.ssh/authorized_keys

3. Генерим ключ без пароля для доступа к Тупиковой машине. (лучше ed25519).

4. Домашней папке Tagd83j6 создаем файл типа shell10.sh (666 root:root)


#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
ssh $USER.10.10.10 2>/dev/null

sudo usermod -s /home/Tagd83j6/shell10.sh Tagd83j6


НА ТУПИКОВОЙ МАШИНЕ (аутентификация по ключам уже настроена)

1. Заводим пользователя Tagd83j6 с паролем >=20 символов (не пригодится)

2. добавляем публичный ключ(с Бастионной машины. п3) в ~/.ssh/authorized_keys

Все. Теперь, если на Бастионной машине от root набрать

su Tagd83j6


Сразу должны попасть на Тупиковую машину.

Собственно все.

Аутентификация пользователя производится на Бастионной машине!!!

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

Вопросы, критика, плюсики приветствуется.

tags: #networks #linux © by Tagd Tagd

🔔 ➡️
Интересно, но часто получаю вопрос: чем vi отличается от vim?

Если коротко, то все форки vi это стероидные штуки, со своими свистоперделками, обвесами и т.п. А vi давно уже в деприкейтед.

VIM = VI iMproved, то есть — «VI Улучшенный»

Прям готовое погоняло для викинга.


Сейчас в современных дистрибутивах предустановлен именно vim. Даже в CentOS 7 был предустановлен vim вместо vi (без симлинков).

Так что ничего тут такого нет. Отличия — в функциональности.

Банально открой какой-нибудь index.py в vi и потом в vim, сразу увидишь что в vi отсутствует подсветка синтаксиса + в vi если память не изменяет — не было визуального режима.

Но если будешь проверять, убедись что открывается именно vi, потому что в 99999% у тебя отроется vim.

Такие дела. Вечерком залетит пост попизже от Tagd про права.

Хорошей всем рабочий недели!

tags: #linux

🔔 ➡️
Тут меня попросили подробнее рассказать про права 330 на каталог.

🔤🔤🔥🔤🔤🔤🔤

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

Конкретно дело касается права "X". Это то же самое, что "x" но касается только каталогов.

То есть chmod -R +X ./ установит возможность поиска во всех подкаталогах текущего, но не сделает все файлы исполняемыми!

Ну, ладно, я отвлекся. 330.

Тут в чате Alex (генератор идей) правильно назвал права «черной комнатой». Клаcсная аналогия.

Короче, я баню зловредов, которые ломятся ко мне на ssh. Баню в разных филиалах. И филиалы сваливают ежедневные отчеты мне, в головной по sftp.

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

Но и паранойю никто не отменял. А если ломанут один филиал, и как начнут данные отравлять... :-)

В общем принял решение, что все работают под одной учеткой. Поставил права на папку 330 (-wx-wx---).

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

Файлы сваливаются с суффиксом, например filXXX_Ohd1Ul.txt Имя файла для каждого филиала всегда одно и то же, префикс - название филиала, суффикс набор букв (защита от перебора).

То есть на сервере в головном от root я вижу все файлы, а филиалы не видят не то что соседние файлы, но даже свой.

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

Да, знаю, сейчас опытные админы набегут и начнут рассказывать про rsync. Я архивы шифрую. А при работе с шифрованными архивами rsync работает хуже, чем sftp. (Ну, сначала контрольные суммы, потом сравнение, потом синхронизация).

А что там сравнивать... они всегда разные. Блин, опять скатился на больное... В общем, при одной учетке, формально можно считать sftp сервер анонимным, но с кругом пользователей, ограниченным ключами :-).

Применение прав 330 позволяет упростить заливку файлов с обеспечением некоторой секьюрности.

Для освежения памяти очень рекомендую статью chmod в википедии.

tags: #security #linux

🔔 ➡️
Сегодня настроение ныть почему-то нет, поэтому научимся открывать файл на нужной строке в разных редакторах.

А нахуя это нужно? Ну ХЗ, я обычно этим не пользуюсь, открываю полностью файл и ищу нужную мне строку. Но это вкусовщина, кто как привык.

Вообще я встречал людей, которые так открывают файлы, когда видят нечто подобное:

Error in file "script.py" on line 42: NameError: name 'variable' is not defined


Хуяк и открыл script.py сразу на 42 строке.

Короче давай посмотрим как это сделать.

Создаем файл для теста:

( printf '%s\n' {A..Z}-$[++I] > /tmp/bashdays.txt )


Получаем такое содержимое:

A-1
B-2
C-3
D-4
E-5
F-6
G-7
H-8
I-9
...


Ну и теперь давай открывать это:

➡️ mcedit

mcedit +7 /tmp/bashdays.txt


➡️ less

less -w +11 /tmp/bashdays.txt


➡️ nano

nano +14 /tmp/bashdays.txt


➡️ vim

vim +4 /tmp/bashdays.txt


Вот такие пироги. А какие еще редакторы ты знаешь в которых можно открыть файл на определенной строке? Камон в комменты!

tags: #linux #tricks #bash

🔔 ➡️
👍1