ServerAdmin.ru
28.4K subscribers
263 photos
33 videos
12 files
2.59K links
Авторская информация о системном администрировании.

Информация о рекламе: @srv_admin_reklama_bot
Автор: @zeroxzed

Второй канал: @srv_admin_live
Сайт: serveradmin.ru
Download Telegram
​​Раньше были разные варианты перезагрузки системы Linux. Как минимум shutdown -r и reboot. Сейчас всё это не имеет значения, так как реально всем управляет systemd. А если посмотреть на shutdown и reboot, то окажется, что это символьные ссылки на systemctl.

# whereis reboot
reboot: /usr/sbin/reboot

# ls -la /usr/sbin/reboot
/usr/sbin/reboot -> /bin/systemctl

# whereis shutdown
shutdown: /usr/sbin/shutdown

# ls -la /usr/sbin/shutdown
/usr/sbin/shutdown -> /bin/systemctl

То есть не важно, как вы перезагрузите сервер. Всё равно команда будет отправлена в systemd. В некоторых инструкциях и статьях вижу, что сервер перезагружают так:

# systemctl reboot

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

Возникает вопрос, а как systemctl понимает, какую команду надо выполнить? Символьные ссылки одинаковы в обоих случаях и ведут просто в /bin/systemctl. С помощью механизма запуска программ execve можно узнать имя исполняемой команды. Примерно так:

$ bash -c 'echo $0'
bash

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

# systemctl start reboot.target
# systemctl start ctrl-alt-del.target

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

Дам ещё небольшую подсказку в рамках этой темы. И shutdown, и reboot, и systemctl в итоге обращаются к бинарнику на диске. Если у вас какие-то проблемы с диском и не удаётся прочитать этот бинарник, то перезагрузка не состоится. Всё будет продолжать висеть. Если запущена консоль, то можно через неё сразу передать команду на перезагрузку напрямую ядру

# echo b > /proc/sysrq-trigger

Сервер тут же перезагрузится, как будто у него физически нажали reset.

#linux
Файловая система ext4 при создании резервирует 5% всего объёма создаваемого раздела. Иногда это очень сильно выручает, когда система встаёт колом и нет возможности освободить место. А без этого она не может нормально работать (привет zfs и lvm-thin). Тогда можно выполнить простую операцию:

# tune2fs -m 3 /dev/mapper/root
или
# tune2fs -m 3 /dev/sda3

Вместо 5% в резерв оставляем 3%, а высвободившееся место остаётся доступным для использования. На больших разделах 5% может быть существенным объёмом. Очень хочется этот резерв сразу поставить в 0 и использовать весь доступный объём. Сделать это можно так:

# tune2fs -m 0 /dev/sda3

Сам так не делаю никогда и вам не рекомендую. Хотя бы 1% я всегда оставляю. Но чаще всего именно 3%, если уж совсем место поджимает. Меня не раз и не два выручал этот резерв.

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

Создаём swap размером в гигабайт и подключаем:

# dd if=/dev/zero of=/swap bs=1024 count=1000000
# mkswap /swap
# chmod 0600 /swap
# swapon /swap

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

# swapoff -a
# rm /swap

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

# fallocate -l 10G /big_file

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

Может показаться, что это какие-то умозрительные примеры. Но на деле я много раз сталкивался с тем, что кончается место на сервере по той или иной причине, и службы на нём встают. А надо, чтобы работали. Пока разберёшься, что там случилось, уходит время. Я сначала добавляю свободное место из имеющихся возможностей (swap или резерв ext4), а потом начинаю разбираться. Это даёт возможность сразу вернуть работоспособность упавшим службам, а тебе несколько минут, чтобы разобраться, в чём тут проблема. Обычно это стремительно растущие логи каких-то служб.

#linux
Медленно, но верно, я перестаю использовать netstat и привыкаю к ss. У неё хоть и не такой удобный для восприятия вывод, но цепляться за netstat уже не имеет смысла. Она давно устарела и не рекомендуется к использованию. Плюс, её нет в стандартных минимальных поставках дистрибутивов. Надо ставить отдельно. Это как с ifconfig. Поначалу упирался, но уже много лет использую только ip. Ifconfig вообще не запускаю. Даже ключи все забыл.

Самые популярные ключи к ss это tulnp:

# ss -tulnp

Список открытых tcp и udp портов. Может показаться смешным и нелепым, но чтобы запомнить эту комбинацию и не лазить в шпаргалки, я представил её написание как тулуп (tulnp). Он хоть и не совсем тулуп, но это помогло мне запомнить эти ключи и активно использовать. Такие ассоциативные якоря помогают запоминать многие вещи. Я постоянно их использую в жизни.

Из того, что ещё часто используется - просмотр открытых сокетов. Актуально, чтобы быстро глянуть, поднялся ли сокет php-fpm или mariadb:

# ss -l | grep .sock

Вывести только сокеты можно и другой командой:

# ss -ax

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

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

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

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

# ss -ntu

И сразу же практический пример для наглядного анализа каких-то проблем через консоль сервера. Подсчет активных сетевых соединений с каждого IP:

# ss -ntuH | awk '{print $6}' | grep -vE 127.0.0.1 | cut -d: -f1 | sort | uniq -c | sort -n| sed 's/^[ \t]*//'

То же самое, только выводим тех, у кого более 30 соединений с нами:

# ss -ntuH | awk '{print $6}' | grep -vE 127.0.0.1 | cut -d: -f1 | sort | uniq -c | sort -n| sed 's/^[ \t]*//' | awk '{if ($1 > 30) print$2}'

Получаем чистый список IP адресов, который можно куда-то направить. Например, в fail2ban, ipset или nftables. Если вас донимают простым досом какие-то мамкины хакеры, можете таким простым способом от них избавиться. Все эти примеры заработают только на ipv4. Для ipv6 нужно будет изменения вносить. Я пока отключаю везде ipv6, не использую.

Количество активных сетевых соединений с сервером:

# ss -ntuH | awk '{print $6}' | grep -vE 127.0.0.1 | wc -l

Всё то же самое, что делали выше, можно сделать не только для активных соединений, но и всех остальных, добавив ключ a:

# ss -ntua

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

#linux #terminal
Стал регулярно сталкиваться с одной проблемой. Есть сервер с бюджетными SSD дисками. Они для многих задач вполне подходят, несмотря на низкую стоимость и скорость записи. Последнее как раз их узкое место. Но если у вас в основном с дисков чтение, то можно существенно экономить, используя десктопные диски.

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

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

Я использовал утилиту pv:

# apt install pv
# mysqldump --opt -v --single-transaction --databases db01 | pv -L 20m > /mnt/backup/db01.sql

Ограничил скорость записи в 20 MiB/s через ключ -L. Для того, чтобы посмотреть текущую скорость записи, используйте pv без ограничения:

# mysqldump --opt -v --single-transaction --databases db01 | pv > /mnt/backup/db01.sql
............................
 1319MiB 0:00:06 [ 205MiB/s]

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

#linux #terminal
Вчера вскользь упомянул утилиту pv, хотя она вполне заслуживает отдельного рассказа. Знаю её очень давно, но использую не часто. Конкретно в задаче по ограничению скорости записи дампа на диск она очень выручила. Других простых способов я не нашёл, да и никто не предложил ничего лучше.

PV это аббревиатура от pipeviewer. То есть это инструмент для работы с пайпами. Обычно есть в репозиториях всех популярных дистрибутивов:

# apt install pv
# dnf install pv

Чаще всего pv упоминают в контексте прогресс бара при работе с файлами и каталогами. Например, при копировании, перемещении, сжатии. Так как размер файлов заранее известен, а так же видна скорость обработки файлов, pv может предсказать, сколько процесс продлится и когда закончится. Примерно так:

# pv testfile > copy/testfile_copy
 976MiB 0:00:02 [ 344MiB/s] [=======================>] 100

Размер файла, который копировали, известен, скорость тоже, так что прогресс бар нормально отработал.

То же самое для сжатия:

# pv testfile | gzip > testfile.gz
 976MiB 0:00:05 [ 183MiB/s] [=======================>] 100

При этом pv может притормозить этот процесс, если у вас есть в этом потребность. Это очень полезная и практически уникальная возможность. Копируем файл с заданной скоростью:

# pv -L 50m testfile > copy/testfile_copy
 976MiB 0:00:19 [49.9MiB/s] [=======================>] 100

Ограничили скорость записи в 50 Мб в секунду (на самом деле мебибайт, но не суть важно, и зачем только придумали эту путаницу). Подобным образом можно ограничивать скорость любого пайпа.

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

# tar -czf - usr | pv -s $(du -sb /usr | grep -o '[0-9]*') > /tmp/usr.tgz
 126MiB 0:00:16 [9.46MiB/s] [==>                  ] 5% ETA 0:04:18

Наглядно виден процесс сжатия, сколько времени осталось. Мы по сути просто определили размер каталога usr через du и передали этот размер в pv через ключ -s. Можно и напрямую передать туда размер, если он известен. На самом деле со сжатием этот пример практически бесполезен, так как скорость сжатия всегда разная, в зависимости от того, какие файлы сжимаются.

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

# pv -EE /dev/sda > disk-image.img

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

# pv -L 50m -EE /dev/sda > disk-image.img

Можно измерить скорость выполнения дампа СУБД:

# mysqldump --opt -v --databases db01 | pv > db01.sql

🔥 С помощью pv можно посмотреть за работой всех файловых дескрипторов, открытых процессов. Причём не просто список увидеть, но и скорость обработки данных в них:

# pv -d 1404
  3:/prometheus/queries.active: 0.00 B 0:01:40 [0.00 B/s]
  8:/prometheus/lock: 0.00 B 0:01:40 [0.00 B/s]
  9:/prometheus/wal/00000000: 10.9MiB 0:01:40 [4.28KiB/s]
 14:/prometheus/chunks_head/000001: 8.00 B 0:01:40 [0.00 B/s]
 16:/prometheus/chunks_head/000001: 0.00 B 0:01:40 [0.00 B/s]

С помощью pv легко ограничивать скорость передачи данных по сети, если направить их через pipe:

# pv -L 10m /tmp/testfile | ssh user@server02 'cat > /tmp/testfile'

Пример синтетический, так как копировать удобнее через rsync, так как там можно штатно указать ограничение на использование канала. Другое дело, что лично я эти ключи rsync наизусть не помню, надо смотреть. А ключ -L (limit) для pv помню.

Можно и просто скорость по ssh между двух серверов проверить:

# pv /dev/zero | ssh user@server02 'cat > /dev/null'

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

#linux #terminal
Как уменьшить размер файловой системы с ext4?

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

В общем случае вам нужно загрузиться с какого-то LiveCD, примонтировать раздел с ext4 и выполнить одну команду:

# /sbin/resize2fs /dev/sda1 50G

Файловая система на разделе /dev/sda1 будет уменьшена до 50G, если там хватит свободного места для этого. То есть данных должно быть меньше. В общем случае перед выполнением операции и после рекомендуется проверить файловую систему на ошибки:

# /sbin/e2fsck -yf /dev/sda1

Если система смонтирована, то ни уменьшения размера, ни проверка не состоятся:

# /sbin/resize2fs /dev/sda1 50G
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
/sbin/resize2fs: On-line shrinking not supported

# /sbin/e2fsck -yf /dev/sda1
e2fsck 1.47.0 (5-Feb-2023)
/dev/sda1 is mounted.
e2fsck: Cannot continue, aborting.

Если у вас есть возможность загрузиться с LiveCD, то никаких проблем. Загружайте и уменьшайте. А если нет? Я в интернете нашёл интересный трюк, ради которого и пишу эту заметку. Не для того, чтобы именно показать уменьшение файловой системы. Этим лучше вообще не заниматься без крайне нужды, проще переехать. Мне понравился сам подход.

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

Настраивается это так. Создаём исполняемый (❗️) файл /etc/initramfs-tools/hooks/resizefs:

#!/bin/sh

set -e

PREREQS=""

prereqs() { echo "$PREREQS"; }

case $1 in
prereqs)
prereqs
exit 0
;;
esac

. /usr/share/initramfs-tools/hook-functions

copy_exec /sbin/e2fsck
copy_exec /sbin/resize2fs

exit 0


Добавляем ещё один исполняемый файл /etc/initramfs-tools/scripts/local-premount/resizefs:

#!/bin/sh

set -e

PREREQS=""

prereqs() { echo "$PREREQS"; }

case "$1" in
prereqs)
prereqs
exit 0
;;
esac

# simple device example
/sbin/e2fsck -yf /dev/sda1
/sbin/resize2fs /dev/sda1 50G
/sbin/e2fsck -yf /dev/sda1


Сначала копируем e2fsck и resize2fs в initramfs, потом запускаем проверку и уменьшение раздела.

Дальше нам нужно собрать новый initramfs с добавленными хуками. Для этого надо посмотреть список доступных ядер и собрать образ на основе одного из них. Возьму для примера самое свежее:

# ls /boot | grep config
config-6.1.0-12-amd64
config-6.1.0-13-amd64
config-6.1.0-20-amd64
config-6.1.0-22-amd64

# update-initramfs -u -k 6.1.0-22-amd64
update-initramfs: Generating /boot/initrd.img-6.1.0-22-amd64

Ошибок быть не должно. Можно перезагружаться. Для того, чтобы наблюдать процесс, можно подключиться к консоли виртуалки. Если что-то пойдёт не так, то при повторной загрузке можно выбрать другое ядро, где initrams не меняли.

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

Придумал я всё это не сам, подсмотрел вот тут:

https://serverfault.com/questions/528075/is-it-possible-to-on-line-shrink-a-ext4-volume-with-lvm

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

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

Наиболее актуальны сейчас следующие планировщики:

🔹mq-deadline - по умолчанию отдаёт приоритет запросам на чтение.
🔹kyber - более продвинутый вариант deadline, написанный под самые современные быстрые устройства, даёт ещё меньшую задержку на чтение, чем deadline.
🔹CFQ и BFQ - второй является усовершенствованной версией первого. Формируют очередь запросов по процессам и приоритетам. Дают возможность объединять запросы в классы, назначать приоритеты.
🔹none или noop - отсутствие какого-либо алгоритма обработки запросов, простая FIFO-очередь.

В современных системах на базе ядра Linux планировщик может выбираться автоматически в зависимости от используемых дисков. Разные дистрибутивы могут использовать разные подходы к выбору. Посмотреть текущий планировщик можно так:

# cat /sys/block/sda/queue/scheduler
[none] mq-deadline

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

# cat /sys/block/vda/queue/scheduler
[mq-deadline] kyber bfq none

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

# cat /sys/block/sda/queue/scheduler
[none] mq-deadline
# modprobe kyber-iosched
# cat /sys/block/sda/queue/scheduler
[none] mq-deadline kyber
# echo kyber > /sys/block/sda/queue/scheduler
# cat /sys/block/sda/queue/scheduler
mq-deadline [kyber] none

Загрузили модуль kyber-iosched и активировали этот планировщик. Действовать это изменение будет до перезагрузки системы. Для постоянной работы нужно добавить загрузку этого модуля ядра. Добавьте в файл /etc/modules-load.d/modules.conf название модуля:

kyber-iosched

А для применения планировщика создайте правило udev, например в отдельном файле /etc/udev/rules.d/schedulerset.rules:

ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sd?", ATTR{queue/scheduler}="kyber"

В виртуальных машинах чаще всего по умолчанию выставляется планировщик none и в общем случае это оправдано, так как реальной записью на диск управляет гипервизор, а если есть рейд контроллер, то он. К примеру, в Proxmox на диски автоматически устанавливается планировщик mq-deadline. По крайней мере у меня это так. Проверил на нескольких серверах. А вот в виртуалках с Debian 12 на нём автоматически устанавливается none. Хостеры на своих виртуальных машинах могут автоматически выставлять разные планировщики. Мне встретились none и mq-deadline. Другие не видел.

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

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

Некоторые полезные объёмные материалы, которые изучил:
🔥https://selectel.ru/blog/blk-mq-tests/ (много тестов)
https://habr.com/ru/articles/337102/
https://redos.red-soft.ru/base/arm/base-arm-hardware/disks/using-ssd/io-scheduler/
https://timeweb.cloud/blog/blk-mq-i-planirovschiki-vvoda-vyvoda

#linux #kernel #perfomance
​​Всегда смотрел список открытых файлов каким-то процессом с помощью lsof. Неоднократно писал об этом.

# lsof -p <pid>

Вчера случайно заметил, просматривая опции htop, что он умеет делать то же самое. Достаточно выбрать какой-то процесс из списка и нажать клавишу l (латинская л). Удивился и не понял, как я раньше это не замечал. Подумал, что это очередное нововведение последних версий. Htop с некоторого времени начал развиваться и обрастать новыми возможностями.

Открыл старый сервер на Centos 7, там htop версии 2.2.0 от 2019 года и тоже есть эта функция. Скорее всего была она там со стародавних времён, а я просто не замечал. Пользоваться ею удобно.

Вообще, htop крутая программа. Я настолько привык к ней, что чувствую себя неуютно на сервере, если она не установлена. После того, как появилась вкладка с I/O вообще хорошо стало. Не нужно дополнительно iotop или что-то подобное ставить. Достаточно запустить htop и можно сделать всю базовую диагностику в нём.

Если установить strace, то и трейсы можно смотреть прямо в htop:

# apt install strace

Теперь можно выбрать процесс, нажать s и посмотреть все системные вызовы.

Когда пользуешься одним и тем же, привыкаешь к этому и забываешь остальные возможности. В htop по памяти помню только несколько команд, которыми пользуюсь примерно в 90% случаев:

t - включить древовидное отображение
P - отсортировать по потреблению CPU
M - отсортировать по потреблению памяти
F9 - прибить процесс
TAB - переключиться на кладку с I/O и обратно

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

#linux #terminal
​​Настраивал скрипт бэкапа с автоматическим удалением старых копий. Во время отладки и бэкапы, и сам скрипт лежали в одной директории. Напутал с условием удаления и случайно был удалён сам скрипт после выполнения. Так как ещё не успел его никуда сохранить, это была единственная копия.

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

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

# apt install scalpel

Далее нам нужно указать сигнатуры восстанавливаемых файлов. Часть сигнатур есть в самом файле конфигураций - /etc/scalpel/scalpel.conf. Ещё более подробный список можно посмотреть тут в репозитории. Я не совсем понял, какие заголовки должный быть у обычного текстового файла, коим являлся мой скрипт. По идее там особых заголовков и нет, а искать можно по содержимому. Так что я добавил в scalpel.conf следующее:

NONE   y   1000   #!/bin/bash

В данном случае #!/bin/bash это начало моего скрипта. Я их все так начинаю. Запускаем сканирование с выводом результатов в /tmp/restored:

# mkdir /tmp/restored
# scalpel /dev/mapper/zabbix-vg-root -o /tmp/restored

zabbix-vg-root - корневой и единственный lvm раздел этого сервера. Если у вас не используется lvm, то это будет что-то вроде /dev/sda2 и т.д.

Программа минуты за 3-4 просканировала раздел на 50G и вывела результаты в указанную директорию. Там было около сотни различных текстовых скриптов, а нужный мне был где-то в самом начале списка, так что мне даже по содержимому искать не пришлось. Сразу нашёл при беглом осмотре. Всё содержимое файла сохранилось.

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

#restore #linux
​​Полезной возможностью Tmux является расширение функциональности за счёт плагинов. Для тех, кто не знает, поясню, что с помощью Tmux можно не переживать за разрыв SSH сессии. Исполнение всех команд продолжится даже после вашего отключения. Потом можно подключиться заново и попасть в свою сессию. Я в обязательном порядке все более-менее долгосрочные операции делаю в подобных программах. Раньше использовал Screen для этого, но последнее время перехожу на Tmux, так как он удобнее и функциональнее.

Особенно важно выполнять обновление систем в Tmux или Screen, так как обрыв соединения в этот момент может привести к реальным проблемам. Я и сам сталкивался, и читатели присылали свои проблемы по этой же части. У меня были заметки на этот счёт.

Для Tmux есть плагин Tmux Resurrect, который позволяет сохранить состояние Tmux со всеми панелями и окнами и порядком их размещения. Вы сможете подключиться в свою настроенную сессию не только в случае отключения, но и перезагрузки Tmux или всего сервера. То есть вы можете настроить в первом окне несколько панелей, к примеру, с htop, tail каких-то логов, переход в какую-то директорию. Во втором окне что-то ещё. Потом сохранить эту сессию. Даже если сервер будет перезагружен, вы сможете восстановить всё окружение.

Демонстрация, как это работает:
▶️  https://vimeo.com/104763018

Установить Tmux Resurrect можно либо через Tmux Plugin Manager, либо напрямую:

# git clone https://github.com/tmux-plugins/tmux-resurrect

Добавляем в ~/.tmux.conf в самое начало:

run-shell ~/tmux-resurrect/resurrect.tmux

Заходим в сессию Tmux и сохраняем её состояние через prefix + Ctrl-s, по умолчанию префикс это Ctrl-b, то есть жмём Ctrl-b потом сразу Ctrl-s. Внизу будет информационное сообщение, что сессия сохранена. Восстановить её можно будет через комбинацию Ctrl-b потом сразу Ctrl-r.

Интересная возможность, которая позволяет завершать сессию, сохраняя её состояние. У меня привычка не оставлять запущенные сессии в фоне. Если их оставлять, то они накапливаются, забываются и могут месяцами висеть. Я обычно поработаю и все сессии после себя завершаю.

#linux #terminal
​​Вчера очень внимательно читал статью на хабре про расследование паразитного чтения диска, когда не было понятно, кто и почему его постоянно читает и таким образом нагружает:

Расследуем фантомные чтения с диска в Linux

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

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

1️⃣ Через iostat смотрим нагрузку на диск и убеждаемся, что кто-то его активно читает. Сейчас уже не обязательно iostat ставить, так как htop может показать то же самое.

2️⃣ Запускаем blktrace в режиме наблюдения за операциями чтения с выводом результата в консоль:

# blktrace -d /dev/sda1 -a read -o - | blkparse -i -

Вывод примерно такой:

259,0  7   4618   5.943408644 425548 Q RA 536514808 + 8 [questdb-ilpwrit]

В данном случае RA 536514808 это событие чтения с диска начиная с блока 536514808.

3️⃣ Смотрим, что это за блок:

# debugfs -R 'icheck 536514808 ' /dev/sda1

debugfs 1.46.5 (30-Dec-2021)
Block Inode number
536514808 8270377

То есть этот блок имеет номер айноды 8270377.

4️⃣ Смотрим, что это за файл:

debugfs -R 'ncheck 8270377' /dev/sda1
Inode Pathname
8270377 /home/ubuntu/.questdb/db/table_name/2022-10-04/symbol_col9.d.1092

Нашли файл, который активно читает процесс questdb-ilpwrit.

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

Был уверен, что это можно сделать проще, так как я уже занимался подобными вопросами. Вспомнил про утилиту fatrace. Она заменяет более сложные strace или blktrace в простых случаях.

# apt install fatrace

Просто запускаем её и наблюдаем

# fatrace

В соседней консоли откроем лог:

# tail -n 10 /var/log/syslog

Смотрим в консоль fatrace:

bash(2143): RO /usr/bin/tail
tail(2143): RO /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
tail(2143): O  /etc/ld.so.cache
tail(2143): RO /usr/lib/x86_64-linux-gnu/libc.so.6
tail(2143): C  /etc/ld.so.cache
tail(2143): O  /usr/lib/locale/locale-archive
tail(2143): RCO /etc/locale.alias
tail(2143): O  /var/log/syslog
tail(2143): R  /var/log/syslog

Результат тот же самый, что и выше с blktrace, только намного проще. В fatrace можно сразу отфильтровать вывод по типам операций. Например, только чтение или запись:

# fatrace -f R
# fatrace -f W

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

# fatrace -s -t 30 -o /tmp/fatrace.log

Не хватает только наблюдения за конкретным процессом. Почему-то ключ -p позволяет не задать конкретный пид процесса для наблюдения, а исключить из результатов операции процесса с этим pid:

# fatrace -p 697

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

Рекомендую заметку сохранить, особенно про fatrace. Я себе отдельно записал ещё вот это:

# debugfs -R 'icheck 536514808 ' /dev/sda1
# debugfs -R 'ncheck 8270377' /dev/sda1

#linux #perfomance
​​В репозиториях популярных дистрибутивов есть маленькая, но в некоторых случаях полезная программа progress. Из названия примерно понятно, что она делает - показывает шкалу в % выполнения различных дисковых операций. Она поддерживает так называемые coreutils - cp, mv, dd, tar, gzip/gunzip, cat и т.д.

Progress по смыслу немного похожа на pv, но принцип работы там совсем другой. Pv берёт информацию из пайпов, соответственно, надо заранее направить поток в неё, чтобы что-то увидеть. А progress сканирует каталог /proc, находит там поддерживаемые утилиты, далее идёт в fd и fdinfo, находит там открытые файлы и следит за их изменениями.

Для того, чтобы посмотреть прогресс той или иной команды, не обязательно запускать утилиту progress вместе с выполнением. Это можно сделать в любой момент времени. Например, запустили упаковку или распаковку большого архива gz и хотите посмотреть, как она выполняется. Достаточно открыть вторую консоль и там посмотреть. Мне это часто актуально, когда большие дампы sql распаковываю. Иногда это прям очень долго, особенно, когда однопоточный gzip используется.

Покажу сразу на примере. Создадим файл:

# dd if=/dev/urandom of=testfile bs=1M count=2048

За процессом, кстати, тоже можно следить с помощью progress, только не будет отображаться % выполнения, потому что утилита ничего не знает о конечном размере. Будет отображаться только скорость записи в режиме реального времени.

Жмём файл:

# gzip testfile

Открываем вторую консоль и там смотрим за процессом:

# watch -n 1 progress -q
[34209] gzip /tmp/testfile
    6.5% (132.2 MiB / 2 GiB)

Если запустить без watch, то progress выведет только текущую информацию и сразу же закроется. То есть не получится наблюдать в режиме реального времени.

То же самое будет и с распаковкой:

# gunzip testfile.gz

В соседней консоли смотрим:

# watch -n 1 progress -q
[35685] gzip /tmp/testfile.gz
    76.1% (1.5 GiB / 2.0 GiB)

Progress очень маленькая утилитка, написанная на чистом C (вспоминается песня "Папа может в C"). Размер - 31K. Из зависимостей только небольшая библиотека ncurses для вывода информации от сишных программ в терминал. Есть почти под все линуксы:

# apt install progress
# dnf install progress

Исходники

#terminal #linux
Собрал в одну заметку замечания по настройке службы SSHD, которая обеспечивает подключение к серверам по SSH. Эта служба присутствует практически во всех серверах. Сказал бы даже, что во всех. Я не припоминаю ни одной виртуалки или железного сервера, куда бы не было доступа по SSH. По возможности, доступ к этой службе лучше закрывать от публичного доступа, но иногда это либо затруднительно, либо вообще невозможно.

Настройки этой службы обычно живут в конфигурационном файле /etc/ssh/sshd_config.

1️⃣ Аутентификация по паролю. Включать или отключать, каждый решает сам для себя. Я лично всегда аутентификацию по паролю оставляю. Просто на всякий случай. Если пароль несловарный, то подобрать его всё равно практически нереально. Проблем с безопасностью это не вызывает.

PasswordAuthentication yes

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

2️⃣ Аутентификация с использованием публичных ключей. По умолчанию она включена и какой-то отдельной настройки не требует. Решил добавить этот пункт, чтобы лишний раз напомнить про ed25519 ключи. Они более надёжны и, что полезно на практике, более короткие. С ними удобнее работать. У меня была отдельная заметка про их использование.

PubkeyAuthentication yes

3️⃣ Разрешение на аутентификацию пользователю root. Тут тоже не буду ничего рекомендовать. Каждый сам решает, разрешает он руту аутентификацию или нет. Если я работаю на сервере один, то обычно аутентификацию разрешаю и работаю всегда под root. Я туда только для этого и захожу, мне не нужны другие пользователи с ограниченными правами. Если же вы работаете не один, то разумнее разделять пользователей, работать через sudo и логировать действия всех пользователей. Так что универсального совета быть не может.

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

PermitRootLogin no

4️⃣ Ограничение на подключение на уровне группы или пользователей. Только пользователи определённой группы или явно указанные смогут подключаться по SSH. Я на практике именно для SSH не пользуюсь этой возможностью, а вот пользователей, которые подключаются по SFTP, обычно завожу в отдельную группу и разрешаю по SFTP подключаться только им. Но это другая настройка. Будет ниже.

AllowGroups sshgroup
AllowUsers user01 user02

5️⃣ Порт, на котором работает служба. Стандартный - 22. Большого смысла менять его нет. Как только первые боты разузнают, что у вас на каком-то порту работает служба, начнут туда долбиться, так же, как и на 22-й. Да и в shodan скорее всего информация об этом появится. Я по привычке порт меняю, если он доступен публично. Хуже от этого не будет, особенно если вы от сканирования портов тоже закрылись. Если служба закрыта от публичного доступа, то оставляю, как есть.

Port 22

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

MaxAuthTries 3

Пользователь подключился, 3 раза неправильно ввёл пароль, его отключает. После этого нужно устанавливать новое соединение.

7️⃣ Ограничение сессий внутри одного SSH-подключения. Не путать с ограничением на количество параллельных сессий с одного хоста. Этот параметр отвечает не за это. Если вы просто подключаетесь к серверу и его администрируете, то вам хватит и одной сессии.

MaxSessions 1

8️⃣ Принудительный запуск какой-то конкретной команды после регистрации пользователя в системе. Например, запускаем не стандартную оболочку, а прокладку, которая будет логировать все действия пользователей. Вот пример с log-user-session. А вот с принудительным запуском подсистемы sftp. Показываю сразу рабочий пример с подключением по sftp заданной группы пользователей, с chroot в конкретную директорию и с umask 002 для новых файлов.

Subsystem sftp internal-sftp -u 002
Match User sftpusers      
ChrootDirectory /var/www    
ForceCommand internal-sftp -u 002

#linux #security
​​Я уже как-то упоминал, что последнее время в репозитории популярных дистрибутивов попадают современные утилиты, аналоги более старых с расширенной функциональностью. Я писал о некоторых из них:

▪️ duf как замена df
▪️ bat как замена cat
▪️ hyperfine как замена time

В этот список можно добавить exa как замена ls. Я про exa уже писал несколько лет назад, но тогда её не было в стабильном репозитории. А сейчас приехала и туда:

# apt install exa

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

более информативная расцветка
умеет показывать расширенные атрибуты файлов (xattrs)
🔥иерархичное древовидное отображение
отображает статус файлов в git репозитории (изменён или нет со времени последнего коммита)
может выводить в несколько колонок информацию

Все привычные ключи ls тоже поддерживает. Мне лично только расцветка понравилась и древовидное отображение:

# exa -T /var/log

├── alternatives.log
├── alternatives.log.1
├── alternatives.log.2.gz
├── alternatives.log.3.gz
├── alternatives.log.4.gz
├── apt
│ ├── eipp.log.xz
│ ├── history.log
│ ├── history.log.1.gz
│ ├── history.log.2.gz
......................................

Можно ограничить максимальный уровень вложенности:

# exa -T -L 2 /var/log

Привычные ключи ls, как я уже сказал, поддерживаются, поэтому можно алиасом заменить ls на exa:

# echo 'alias ls=exa' >> ~/.bashrc
# source ~/.bashrc
# ls -la

❗️К сожалению, exa больше не развивается, потому что автор куда-то пропал. В репозитории есть об этом информация. Предлагают переходить на форк eza, но его пока нет в репозиториях для Debian 12, но планируется в Debian 13. В Ubuntu 24 уже есть eza. Так что всё написанное актуально и для неё. Если в вашем дистрибутиве она уже есть, то имеет смысл поставить именно её. Там есть ряд небольших правок багов и некоторые улучшения функциональности. Я себе поставил в WSL как замену ls.

Исходники / Сайт

#linux #terminal
▶️ Очередная подборка авторских IT роликов, которые я лично посмотрел и посчитал интересными/полезными. Как обычно, ниже те видео из моих подписок за последнее время (обычно беру период в 2 недели), что мне показались интересными и полезными.

FreeBSD in 100 Seconds
Очень короткий ролик про FreeBSD. Там нет ничего особенного. Интересен будет только тем, кто не знает, что это за система, но хочет иметь о ней представление. В конце ролика реклама, ради которой он и записывался, можно не досматривать. На этом канале много видео в таком же стиле, где за 100 секунд кратко рассказывают о каком-то продукте. Можно смело смотреть с синхронным переводом от Яндекса. Всё понятно.

Secure your HomeLab for FREE // Wazuh
Информативное и подробное видео про настройку open source SIEM-системы Wazuh. Автор выполнил single-node установку через docker на домашнем сервере, настроил доступ к веб интерфейсу через traefik. Потом установил агентов на Windows и Linux сервер. Далее показал, как выглядит анализ конфигурации систем на соответствие рекомендациям CIS. В конце рассказал про обнаружение вирусов и вторжений.

Настройка Suricata в OPNsense
Недавно делал заметку по мотивам ролика от этого автора на тему настройки Zenarmor в OPNsense. Теперь то же самое, только про бесплатную Сурикату.

Запуск Llama 405b на своем сервере. vLLM, docker.
Подробное описание того, как запустить самую мощную открытую нейросеть Llama 405b на своем сервере. Там и про объём данных, системные требования, где можно взять в аренду сервер (стоимость аховая 🙈) и т.д. В общем, всё. Хорошая инструкция. Было интересно посмотреть для общего развития. Подписался на канал.

Установка Docmost на Synology в контейнер Docker
Видео про установку и настройку бесплатной open source замены Notion, заблокировавшей всех пользователей из РФ. Автор ставит на Synology, но так как продукт запускается с помощью docker-compose, не принципиально, где это будет запущено. Если хочется просто посмотреть, как выглядит Docmost, мотайте сразу на 8-ю минуту.

My NEW HomeLab storage server!
Бодрое видео от весёлого блогера, который собрал себе новый сервер хранения, установил туда unraid и рассказал об этом. Будет интересно тем, кто любит такой формат. Пользы там нет, чисто развлечение. Я люблю смотреть такие видео. Может у самого когда-то появится время собирать себе домой какие-то сервера. Сейчас не до этого.

Zabbix Meetup online, August 2024: Synthetic browser monitoring in Zabbix 7.0
Рассказ с недавнего митапа Zabbix о том, как работает новый мониторинг веб сайтов в Zabbix 7.0. Наглядной практики в записи нет, в основном теория и описание возможных настроек.

Сети для несетевиков // OSI/ISO, IP и MAC, NAT, TCP и UDP, DNS
Хорошее обзорное видео по основам сетевых технологий. Даётся база для тех, кто почти нулевой в этой теме: модель OSI, MAC адреса, IP адреса, порты, NAT и т.д. У автора явно есть потенциал, желание и знания для создания хороших роликов, но он почему-то пошёл по самым азам, по которым уже есть много материала в интернете и в ютубе в частности. Было бы интереснее, если бы он в какую-то практическую область сместился. Надеюсь, до него как-то дойдёт этот посыл.

Какой роутер взять для NAS и дома (подкаст)
Личное мнение автора по выбору роутера для дома. Интересно послушать рассуждения, а не какие-то пересказы. Он делает акцент на Wifi и считает, что отталкиваться надо от этих возможностей железа. Всё остальное вторично. Я с этим не согласен, так как везде стараюсь тянуть провод, а по WiFi работают в основном смартфоны, которым некритична скорость подключения.

#видео
Небольшая заметка про одну команду, которая у меня уже вошла в привычку и используется почти каждый день. Возможно и вам она будет полезна. Я недавно делал заметку про netstat и ss. Рассказал, что постепенно почти перешёл на ss, но не нравится широкий вывод команды. На узком терминале разъезжается одна строка на две и вывод выглядит ненаглядно.

В комментариях один человек посоветовал использовать утилиту column. Что самое интересное, я про неё знаю, писал заметку. Тоже посоветовали в комментариях. Но с ss не догадался её попробовать. А это удобно. Вывод получается более компактный и наглядный:

# ss -tulnp | column -t
# ss -nte | column -t

А самое главное, что я cразу эту конструкцию запомнил и теперь постоянно пользуюсь, так как и ss, и column есть во всех дистрах из коробки. Рекомендую попробовать. Я column привык с mount использовать для удобного вывода:

# mount | column -t

Теперь вот и с ss. Про netstat стал забывать. Не использую почти, перешёл на ss. Один неприятный нюанс всё равно остался. Даже с column в ss бывают длинные строки, если поле с users очень длинное, типа такого:

users:(("smtpd",pid=1680589,fd=6),("smtpd",pid=1680587,fd=6),("smtpd",pid=1680585,fd=6),("smtpd",pid=1678705,fd=6),("smtpd",pid=1678348,fd=6),("smtpd",pid=1675803,fd=6),("master",pid=1837,fd=13))

Netstat вообще не выводит пользователей, только название процесса. В ss тоже можно убрать, например вот так (заменили p на e):

# ss -tulne

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

#linux #terminal
Вчера случайно заметил очень любопытную вещь в Debian, которая касается различий между apt и apt-get. Я всегда был уверен, что различия там в основном организационные в плане названия команд. Apt объединил в себе возможности apt-get и apt-cache, добавился прогресс бар, и что важно apt list --upgradable.

Я обычно использую apt, потому что короче набирать и в целом удобнее. Оказалось, что команды apt upgrade и apt-get upgrade тоже отличаются. Фактически разницы между apt upgrade и apt full-upgrade нет, а она должна быть. Напомню, что команда upgrade обновляет только текущую версию пакета, ничего не удаляя. В то же время full-upgrade может удалить текущую версию пакета и установить новую. Поэтому эта команда используется при обновлении с релиза на релиз. Там без удаления не обойтись.

А заметил я разницу, когда установил на Debian 12 версию php 8.2 и захотел обновить её до 8.3, подключив сторонний репозиторий. Покажу наглядно по шагам, что сделал.

Сначала полностью обновил систему и установил туда php 8.2 из стандартного репозитория:

# apt update && apt upgrade
# apt install php

Далее подключил репозиторий sury, а точнее его зеркало в домене на su, так как автор ограничил к нему доступ из РФ:

# wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.su/php/apt.gpg
# sh -c 'echo "deb https://packages.sury.su/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

В репозитории есть версия php 8.3. Пробую обновиться через apt:

# apt update && apt upgrade

Предлагает установить php 8.3 и удалить 8.2:

The following packages were automatically installed and are no longer required:
 libapache2-mod-php8.2 php8.2 php8.2-cli php8.2-common php8.2-opcache php8.2-readline
Use 'apt autoremove' to remove them.
The following NEW packages will be installed:
 debsuryorg-archive-keyring libapache2-mod-php8.3 php8.3 php8.3-cli php8.3-common php8.3-opcache php8.3-readline

Делаю full-upgrade:

# apt full-upgrade

Вывод один в один как для upgrade. Предлагает удалить 8.2 и поставить 8.3. Я выполнил обе эти команды и убедился, что результат идентичный. Они отработали обе как full-upgrade. Я получил в системе php 8.3.

Делаю то же самое, только с apt-get:

# apt-get upgrade

The following packages will be upgraded:
 libapache2-mod-php8.2 php8.2 php8.2-cli php8.2-common php8.2-opcache php8.2-readline

Предлагает только обновить 8.2, что от него и ожидаешь. Выполняю full-upgrade:

# apt-get full-upgrade

The following packages were automatically installed and are no longer required:
 libapache2-mod-php8.2 php8.2 php8.2-cli php8.2-common php8.2-opcache php8.2-readline
Use 'apt autoremove' to remove them.
The following NEW packages will be installed:
 debsuryorg-archive-keyring libapache2-mod-php8.3 php8.3 php8.3-cli php8.3-common php8.3-opcache php8.3-readline

Вывод такой же, как у apt full-upgrade. То есть в apt-get upgrade и full-upgrade работают ожидаемо, как и описано в документации. А вот с apt мне непонятна ситуация. Не так часто приходится в рамках одной системы переходить на другую ветку ПО, поэтому раньше не обращал на это внимание. А теперь буду.

Вот отличия apt upgrade от apt full-upgrade согласно man:

▪️ upgrade - upgrade is used to install available upgrades of all packages currently installed on the system from the sources configured via sources.list(5). New packages will be installed if required to satisfy dependencies, but existing packages will never be removed.

▪️ full-upgrade - full-upgrade performs the function of upgrade but will remove currently installed packages if this is needed to upgrade the system as a whole.

Apt-get ведёт себя согласно описанию, а вот apt - нет. Не знаю, баг это или особенность конкретно веток php и подключенного репозитория. Если бы оба apt-get и apt вели себя одинаково, я бы не обратил на это внимания. Но тут разница в поведении налицо. Их поведение не идентично не только в плане синтаксиса и некоторых ключей, но и функциональности.

#linux
И вновь возвращаемся к рубрике с современными утилитами, которые можно использовать в качестве альтернативы более старым, потому что они уже поселились в официальных репозиториях. Речь пойдёт об уже упоминаемой мной несколько лет назад программе fd, которую можно использовать вместо find. Она приехала в стабильные репы:

# apt install fd-find

Короткое название fd использовать не получится, потому что оно уже занято. Придётся использовать fdfind. Под Windows она, кстати, тоже есть:

> winget install sharkdp.fd

В чём особенность fd? Авторы называют её более быстрой и дружелюбной к пользователю программой, по сравнению с find. В принципе, с этим не поспоришь. Ключи и синтаксис find нельзя назвать дружелюбным. Я по памяти могу только какие-то самые простые вещи делать. Всё остальное ищу в своих шпаргалках. Не понимаю, как подобные конструкции можно запоминать, если каждый день с ними не работаешь.

Ищем файл syslog в текущей директории:

# fdfind syslog

Ищем файл в конкретной директории:

# fdfind syslog /var/log

Ищем файл по всему серверу:

# fdfind syslog /

Вот то же самое, только с find:

# find . -name syslog
# find /var/log -name syslog
# find / -name syslog

По умолчанию find найдёт только полное совпадение по имени. Файл должен будет точно называться syslog, чтобы попасть в результаты поиска. Fd в примере отобразит все файлы, где встречается слово syslog. Это и интуитивнее, и проще для запоминания. Хотя этот момент субъективен. С find такой же поиск будет выглядеть вот так:

# find / -name '*syslog*'

Отличия от find, которые отмечают авторы:

◽️Более скоростной поиск за счёт параллельных запросов. Приводят свои измерения, где это подтверждается.
◽️Подсветка результатов поиска.
◽️По умолчанию поиск ведётся без учёта регистра.
◽️Итоговые команды в среднем на 50% короче, чем то же самое получается с find.
⚠️ Отдельный ключ --exec-batch или -X в дополнение к традиционному --exec. Разница в том, что --exec выполняется параллельно для каждого результата поиска, а с помощью --exec-batch можно во внешнюю команду передать весь результат поиска. Это важный момент, который где-то может сильно выручить и упростить задачу. Даже если вам сейчас это не надо, запомните, что с fd так можно. Где-то в скриптах это может пригодиться.

Несколько простых примеров для наглядности. Поиск файлов с определённым расширением:

# fdfind -e php -p /var/www

Найти все архивы и распаковать их:

# fdfind -e zip -p /home/user -x unzip

Найти файлы с расширением gz и удалить одной командой rm:

# fdfind -e gz -p /var/log -X rm

Вызванный без аргументов в директории, fd рекурсивно выведет все файлы в ней:

# cd /var/log
# fdfind

Это примерно то же самое, что с find:

# find -name '*'

Только у fd вывод нагляднее, так как уже отсортирован по именам. А find всё вперемешку выводит. Ему надо sort добавлять, чтобы то же самое получилось:

# find -name '*' | sort

Fd умеет результаты выводить не по одному значению на каждую строку, а непрерывной строкой с разделением с помощью так называемого NULL character. Все символы воспринимаются буквально, не являются специальными, их не надо экранировать. Актуально, когда результаты поиска имеют пробелы, кавычки, косые черты и т.д. Например, xargs умеет принимать на вход значения, разделённые NULL character. У него для этого отдельный ключ -0, --null.

Покажу на примере, как это работает:

# touch 'test test.log'
# fdfind -e log
...
test test.log

# fdfind -e log | xargs wc -l
...
wc: test: No such file or directory
wc: test.log: No such file or directory

Xargs не смог обработать файл с пробелом. А вот так смог:

# fdfind -0 -e log | xargs -0 wc -l
...
0 ./test test.log

И ничего экранировать не пришлось. Полезная возможность, стоит запомнить. Find то же самое делает через ключ -print0:

# find . -name '*.log' -print0 | xargs -0 wc -l

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

#terminal #linux #find
На всех серверах на базе Linux, а раньше и не только Linux, которые настраиваю и обслуживаю сам, изменяю параметры хранения истории команд, то есть history. Настройки обычно добавляю в файл ~/.bashrc. Постоянно обращаюсь к истории команд, поэтому стараюсь, чтобы они туда попадали и сохранялись. Покажу свои привычные настройки:

Для того, чтобы сразу же сохранять в историю введённую команду, использую переменную bash - PROMPT_COMMAND. Содержимое этой переменной выполняется как обычная команда Bash непосредственно перед тем, как Bash отобразит приглашение. Соответственно, команда history -a сохраняет историю команд этого сеанса в файл с историей.

PROMPT_COMMAND='history -a'

Сохранение метки времени вместе с самой командой и вывод её в определённом формате (2024-09-25 16:39:30):

export HISTTIMEFORMAT='%F %T '

Увеличение числа строк в файле с историей. По умолчанию хранится вроде бы только 500 последних команд, более старые удаляются. Я увеличиваю этот размер до 10000 строк. Ни разу не было, чтобы этого не хватило:

export HISTSIZE=10000

Некоторые команды не сохраняю в истории, так как они не представляют какой-то ценности, только отвлекают и занимают место. Вы можете свой список таких команд вести:

export HISTIGNORE="ls:history:w:htop:pwd:top:iftop"

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

export HISTCONTROL=ignorespace 

Для применения настроек можно выполнить:

# source ~/.bashrc

Посмотреть свои применённые параметры для истории можно вот так:

# export | grep -i hist

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

❗️Для поиска по истории нажмите сочетание клавиш Ctrl+r и начните вводить команду. Для перебора множественных совпадений продолжайте нажимать Ctrl+r, пока не найдёте то, что ищите. Я лично привык просто грепать, а не искать в истории:

# history | grep 'apt install'

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

⚡️Расскажу про один нюанс, связанный HISTIGNORE, который не раз меня подставлял. У меня в исключениях, к примеру, есть команда htop. Она в историю не попадает. Бывало такое, что я перезагружал сервер командой reboot. Потом загружался и первым делом вводил команду htop, что-то смотрел, закрывал htop. Потом нужно было запустить htop снова. Я на автомате нажимаю стрелку вверх, чтобы запустить последнюю команду, там выскакивает reboot, потому что htop не сохранился, и я тут же жму enter. И сокрушаюсь, что на автомате выполнил не ту команду. Реально много раз на это попадался, правда без последствий. В основном это во время какой-то отладки бывает, там и так перезагрузки идут.

#linux #terminal #bash

🦖 Selectel — дешёвые и не очень дедики с аукционом!
Please open Telegram to view this post
VIEW IN TELEGRAM
Одной из обязательных настроек, которую делаю на новом сервере, касается ротации текстовых логов. Несмотря на то, что их активно заменяют бинарные логи systemd, я предпочитаю возвращать текстовые логи syslog. Для этого на чистый сервер устанавливаю rsyslog:

# apt install rsyslog

Далее выполняю некоторые настройки, которые относятся к ротации логов с помощью logrotate. В первую очередь в фале /etc/logrotate.conf включаю параметр:

dateext

Он нужен, чтобы в имени файла была указана дата, когда лог-файл был ротирован. С этой настройкой связан один очень важный момент, если вы хотите ротировать логи чаще, чем раз в сутки. По умолчанию logrotate во время ротации лога с этой настройкой переименовывает текущий лог файл, назначая ему имя вида access.log.20241001.gz. То есть в имени файла будет указан текущий день. Второй раз в этот день ротация закончится ошибкой, так как logrotate скажет, что не могу переименовать лог, так как файл с таким именем уже существует. Для тех логов, что точно будут ротироваться чаще, чем раз в сутки, нужно обязательно добавить параметр:

dateformat -%Y-%m-%d_%H-%s

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

Далее в обязательном порядке нужно настроить запуск logrotate чаще, чем раз в сутки. По умолчанию в Debian запуск logrotate настроен в /etc/cron.daily и запускается не чаще раза в сутки. Я обычно просто добавляю запуск в /etc/crontab каждые 5 минут:

*/5 * * * * root logrotate /etc/logrotate.conf

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

Все возможные настройки файлов logrotate можно почитать в man. Там довольно подробно всё описано. Если не хочется читать man, можно воспользоваться простым конфигуратором:

🌐 https://scoin.github.io/logrotate-tool

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

/web/sites/*/logs/*.log {
  create 644 angie webuser
  size=50M
  dateext
  dateformat -%Y-%m-%d_%H-%s
  missingok
  rotate 30
  compress
  notifempty
  sharedscripts
  postrotate
if [ -f /run/angie.pid ]; then
kill -USR1 $(cat /run/angie.pid)
fi
  endscript
}

Маска /web/sites/*/logs/*.log захватывает все виртуальные хосты веб сервера, где логи располагаются в директориях:

◽️/web/sites/site01.ru/logs/
◽️/web/sites/site02.ru/logs/
и т.д.

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

#linux #logs #logrotate #webserver
Please open Telegram to view this post
VIEW IN TELEGRAM