ServerAdmin.ru
26.4K subscribers
190 photos
24 videos
8 files
2.45K links
Авторская информация о системном администрировании.

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

Второй канал: @srv_admin_live
Сайт: serveradmin.ru
Download Telegram
​​Очень простой и быстрый способ настроить уведомления об успешном SSH подключении к серверу в Telegram. Для этого понадобится свой bot, простенький bash скрипт и изменение конфига PAM для SSH. Будем через него уведомления делать.

Рассказывать про создание бота не буду. Надо создать нового бота, получить его токен. Также понадобится ваш ID. Узнать можно разными способами, например через бота @my_id_bot.

Далее берём простой скрипт:

#!/bin/bash

if [ "$PAM_TYPE" != "close_session" ]; then
  ID=1307682341
  BOT_TOKEN=6327355747:AAEDcFIlhKSIOKS-t2I9ARTdT1usbq2a9W4
  message="$(date +"%Y-%m-%d, %A %R")"$'\n'"SSH Login: $PAM_USER@$(hostname)"
  curl -s --data "text=$message" --data "chat_id=$ID" 'https://api.telegram.org/bot'$BOT_TOKEN'/sendMessage' > /dev/null
fi

Тут мы проверяем переменную PAM_TYPE. Если это что-то отличное от закрытия сессии, то нам подходит. Проверить работу скрипта можно примерно так:

# PAM_TYPE=open_session ./ssh-success.sh

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

Копируем этот скрипт в директорию /etc/ssh/ и выставляем минимальные права:
# chown root /etc/ssh/ssh-success.sh
# chmod 100 /etc/ssh/ssh-success.sh

Далее открываем конфиг /etc/pam.d/sshd и добавляем туда:

# Send a login notification to Telegram via ssh-success.sh
session  optional   pam_exec.so seteuid /etc/ssh/ssh-success.sh

На этом всё. Теперь при успешном SSH подключении вы будете получать уведомление в Telegram.

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

Единственное, что мне хотелось бы сделать, но не получилось - вывести в уведомление IP адрес подключившегося пользователя. Я не нашёл в переменных PAM этой информации. А парсить лог ssh подключений не захотелось. Это делает решение неуниверсальным. В представленном виде сообщения будут такие:

2023-08-07, Monday 15:10
SSH Login: root@debian11

Подробная дата (date +"%Y-%m-%d, %A %R"), имя пользователя ($PAM_USER) и имя сервера (hostname). Можете добавить какую-то ещё информацию по своему усмотрению. Если кто-то знает переменную PAM с информацией об адресе подключившегося, подскажите. Я не нашёл такой информации.

#linux #bash #ssh #security
​​Если вам внезапно захочется запустить кого-нибудь или самому зайти в консоль через web, то предлагаю очень простой и быстрый способ. Воспользуйтесь утилитой ttyd.

Достаточно её скачать из репозитория:
# wget https://github.com/tsl0922/ttyd/releases/download/1.7.3/ttyd.i686
Переименовать и сделать исполняемой:
# mv ttyd.i686 /usr/local/bin/ttyd
# chmod +x /usr/local/bin/ttyd

Запускаем bash через браузер:
# ttyd bash
В консоли увидите порт, на котором запустилась программа. Откройте этот порт в браузере: http://172.22.221.121:7681 и увидите свою консоль.

Таким образом можно открыть не только bash, но и любую другую программу. Например, можно очень просто и быстро вывести через браузер top:
# ttyd top
или mc:
# ttyd mc

Если запустить ttyd без параметров, то увидите все доступные ключи. Можно указать используемый порт, забиндить на какой-то конкретный интерфейс, настроит basic аутентификацию, задать режим read-only и т.д. Там много интересных возмоностей.

Утилита простая и удобная. Люблю такие. Никаких заморочек с настройкой и установкой. Скорее всего прямо сейчас она вряд ли пригодится, но стоит запомнить, что есть такая возможность. Иногда это может быть полезным. Банально тот же top повесить на всеобщий обзор для каких-то целей отладки. Это быстрее, чем настраивать кому-то доступ по ssh.

#bash #terminal
​​Хочу предложить вашему вниманию bash скрипт по проверке статуса работы Nginx. Обращаю внимание именно на него, потому что он классно написан и его можно взять за основу для любой похожей задачи. Сейчас подробно расскажу, что там происходит.

Для начала отмечу, что этот скрипт check_nginx_running.sh из репозитория Linux scripts. Его ведёт автор сайта https://blog.programs74.ru. Я с ним не знаком, но часто пользовался его материалами и скриптами. Всё классно написано и рассказано. Так что рекомендую.

Что делает этот скрипт:
1. Проверяет, запущен ли он под root.
2. Проверяет существование master и worker процессов nginx.
3. Проверяет занимаемую ими оперативную память.
4. Записывает все свои действия в текстовый файл.
5. Перезапускает службу, если она не запущена.
6. Перед перезапуском проверяет конфигурацию на отсутствие ошибок.

Возможность логирования и перезапуска включается или отключается по желанию.

Этот скрипт легко адаптировать под мониторинг любых других процессов Linux. Какие-то проверки можно убрать, логику упростить. Пример с Nginx как раз удобен, так как тут и 2 разных процесса, и проверка конфигурации. Сразу сложный пример разобран.

Если у вас есть какая-то система мониторинга, и она не умеет мониторить процессы Linux, можно использовать подобный скрипт. Проще всего настроить анализ лог файла и выдавать оповещения в зависимости от его содержимого. Не придётся особо ломать голову, как реализовать. Уже всё реализовано.

Например, в Zabbix из коробки для мониторинга служб есть ключи proc.num и proc.mem, которые считают количество запущенных процессов с заданным именем и используемую память. Это всё, что есть встроенного по части процессов. Если нужна какая-то реакция, например, запуск упавшего процесса, то нужно всё равно писать bash скрипт для этого, который будет запускаться триггером.

Соответственно, у вас есть 2 пути по настройке контроля за процессом: использовать скрипт типа этого про крону и в мониторинге наблюдать за ним, либо следить за состоянием процесса через мониторинг и отдельным скриптом совершать какие-то действия. Что удобнее, решать по месту в зависимости от используемой архитектуры инфраструктуры. Позволять через Zabbix запускать скрипты на удалённых машинах не всегда удобно и безопасно. У локального скрипта в cron тоже есть свои минусы. Решать надо по ситуации.

#script #bash #мониторинг
​​Один подписчик поделился полезным сервисом, про который я ранее не слышал:

https://cmdgenerator.phphe.com.

С его помощью можно подготовить итоговую команду для популярных утилит командной строки Linux с набором параметров. Сделано добротно и удобно. Это такая продвинутая замена man, которая позволяет быстрее сформировать нужные параметры. Единственное, заметил, что некоторые ключи не совпадают с ключами этой утилиты в том же Debian. Не понятно, для какой версии они актуальны. Стоило бы указать.

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

https://explainshell.com

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

find-command-generator

Он тоже неплохо сделан и может существенно помочь. У find куча параметров, которые невозможно запомнить. Надо либо готовые команды записывать, либо открывать man и искать нужное. Этот помощник может сэкономить время. Для cron ещё полно похожих сервисов.

#bash #terminal
​​🎓 Сегодня пятница, а пятница — это почти выходной, когда уже не хочется заниматься делами. Лучше это время потратить с пользой и заняться самообразованием. А в этом нам может помочь набор TUI программ для обучения в консоли.

https://github.com/learnbyexample/TUI-apps

Их тут несколько, и я начал с того, что мне показалось наиболее полезным - Linux CLI Text Processing Exercises. Это простенькая оболочка с вопросами на тему обработки текстовых файлов консольными утилитами в Linux. Поставил по инструкции:

# python3 -m venv textual_apps
# cd textual_apps
# source bin/activate
# pip install cliexercises
# cliexercises

Запускаю, первый же вопрос:
Display the first 5 lines for the input file ip.txt.
Для меня это просто. Отвечаю:
head -n 5 ip.txt
Ответ правильный и мне предлагают ещё вариант:
sed '5q' ip.txt
С sed часто работаю, но не знал, что с его помощью можно так просто вывести первые 5 строк. Записал сразу себе в шпаргалку.

Следующий вопрос посложнее, но тоже в целом простой:
Display except the first 5 lines for the input blocks.txt.
Выводим всё, кроме первых 5-ти строк:
tail -n +5 blocks.txt
Я ошибся и срезал только 4 строки. Поправился:
tail -n +6 blocks.txt
Утилита подтвердила, что мой вариант правильный. Честно говоря, я думал, что вряд ли в ней будет вариант с tail, поэтому взял именно его. Но она в виде правильных вариантов предложила как раз с tail и ещё с sed:
sed '1,5d' blocks.txt
Тоже сразу записал в шпаргалку. Решил ещё проверить вариант с awk. Я думал, что именно он и будет предложен, так как первый пришёл в голову:
awk 'NR>5' blocks.txt
Тоже помечен, как правильный. Возможно программа проверяет вывод, используя все доступные системные утилиты, так что правильным будет даже тот вариант, что отсутствует в её базе.

Таких заданий тут много. Конкретно в этой программе 68. Проходить увлекательно и полезно, так что рекомендую для самообразования и пополнения своей коллекции bash костылей. Можно в исходниках сразу всё посмотреть, но не рекомендую. Так ничего не запомнится. А если самому подумать, то лучше отложится в голове.

Вот примерчик из того, что будет ближе к концу:
From blocks.txt extract only the 3rd block. A line containing %=%= determines the start of a block.
То есть файл разделён на блоки, а разделитель блоков - символы %=%=, надо вывести 3-й блок. Для меня это уже сложно, чтобы что-то сходу придумать. Вот решение:
awk '$0 == \"%=%=\"{c++} c==3' blocks.txt

#обучение #terminal #bash
​​🎓 На прошлой неделе я рассказывал про репозиторий с обучающими TUI программами с популярными консольными утилитами. Хочу обратить внимание на тренажёр по awk. Я там увидел много полезных примеров с возможностями awk, про которые я даже не знал.

https://github.com/learnbyexample/TUI-apps/tree/main/AwkExercises

Например, я никогда не использовал awk для того, чтобы вывести строки с определёнными символами. Обычно использовал для этого grep, а потом передавал вывод в awk. Хотя в этом нет никакой необходимости. Awk сам умеет это делать:

# grep 'word' file.txt
# awk '/word/' file.txt

Команды делают одно и то же. Выводят строки со словом word. Понятно, что если задача стоит только в этом, то grep использовать проще. Но если нужна дальнейшая обработка, то уже не так однозначно. Например, нам надо вывести только первый столбец в строках со словом word.

# grep 'word' file.txt | awk '{print $1}'
# awk '/word/{print $1}' file.txt

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

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

# awk '{print $0 "."}' file.txt

Я не понял логику этой конструкции, но работает, проверил. На основе этого примера сделал свой, когда в начало каждой строки ставится знак комментария:

# awk '{print "#" $0}' file.txt

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

# awk '/word/{print "#" $0}' file.txt

Закомментировали строку со словом word. Удобно комментировать какие-то параметры в конфигурационных файлах.

#обучение #bash
​​У меня в управлении много различных серверов. Я обычно не заморачивался с типом файловых систем. Выбирал то, что сервер ставит по умолчанию. Для серверов общего назначения особо нет разницы, будет это XFS или EXT4. А выбор обычно из них стоит. RPM дистрибутивы используют по умолчанию XFS, а DEB — EXT4.

Лично для меня имеют значения следующие принципиальные отличия:

1️⃣ XFS можно расширить, но нельзя уменьшить. EXT4 уменьшать можно. На практике это очень редко надо, но разница налицо.

2️⃣ У EXT4 по умолчанию создаётся не очень много inodes. Я нередко упирался в стандартное ограничение. В XFS их по умолчанию очень много, так как используется динамическое выделение. С проблемой нехватки не сталкивался ни разу.

3️⃣ EXT4 по умолчанию резервирует 5% свободного места на диске. Это можно изменить при желании. XFS если что-то и резервирует, то в разы меньше и это не настраивается.

❗️У меня была заметка про отличия ext4 и xfs. Можете почитать, кому интересно. Рассказать я хотел не об этом. Нередко нужно узнать, какая файловая система используется, особенно, когда закончилось свободное место. Для этого использую команду mount без ключей:
# mount

Она вываливает трудночитаемую лапшу в терминал, где трудно быстро найти корневой или какой-то другой раздел. Конкретный раздел ещё можно грепнуть, а вот корень никак. Я всё думал, как же сделать, чтобы было удобно. Просмотрел все ключи mount или возможности обработки вывода. Оказалось, нужно было подойти с другой стороны. У утилиты df есть нужный ключ:
# df -T
Filesystem   Type    1K-blocks  Used Available Use% Mounted on
udev       devtmpfs  1988408    0   1988408   0% /dev
tmpfs      tmpfs     401244    392   400852   1% /run
/dev/sda2    ext4    19948144 2548048  16361456  14% /
tmpfs      tmpfs    2006220    0   2006220   0% /dev/shm
tmpfs      tmpfs     5120     0    5120   0% /run/lock
/dev/sda1    vfat     523244   5928   517316   2% /boot/efi
tmpfs      tmpfs     401244     0   401244   0% /run/user/0

И не надо мучать mount. У df вывод отформатирован, сразу всё видно.

#bash #terminal
​​В комментариях к заметке, где я рассказывал про неудобочитаемый вывод mount один человек посоветовал утилиту column, про которую я раньше вообще не слышал и не видел, чтобы ей пользовались. Не зря говорят: "Век живи, век учись". Ведение канала и сайта очень развивает. Иногда, когда пишу новый текст по трудной теме, чувствую, как шестерёнки в голове скрипят и приходится напрягаться. Это реально развивает мозг и поддерживает его в тонусе.

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

Структурируем вывод mount:
# mount | column -t
Получается очень аккуратно и читаемо. Ничего придумывать не надо, чтобы преобразовать вывод.

А вот пример column, но с заменой разделителя на двоеточие:
# column -s ":" -t /etc/passwd
Получается удобочитаемое представление. Из него можно без особых проблем вывести любой столбец через awk. Как по мне, так это самый простой способ, который сразу приходит в голову и не надо думать, как тут лучше выделить какую-то фразу. Выводим только имена пользователей:
# column -s ":" -t /etc/passwd | awk '{print $1}'
Каждый пользователь в отдельной строке. Удобно сформировать массив и передать куда-то на обработку.

Утилита полезная и удобная. Главное теперь про неё не забыть, чтобы применить в нужный момент.

#bash #terminal
​​Во времена развития искусственного интеллекта сидеть и вспоминать команды и ключи консольных утилит Linux уже как-то не солидно. Пусть "вкалывают роботы, а не человек".

Идём на сайт https://www.askcommand.cppexpert.online и приказываем железным мозгам выполнять наши команды:

I want to delete 10 first lines in text file.
sed '1,10d' filename

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

I want to find all php files and replace one word there with another.
find ./ -name "*.php" -exec sed -i 's/old/new/g' {} +

Опять сработало. Рабочий вариант предложил. Попробуем ещё усложнить:

I want to find the ten largest files older than thirty days and move them to another directory.
find /source/directory -type f -mtime +30 -exec ls -s {} \; \
| sort -n -r | head -10 | awk '{print $2}' \
| xargs -I '{}' mv '{}' /destination/directory

Я не проверял этот вариант, но навскидку рабочий. Не вижу тут ошибок. Если английский не знаем, то напрягаем другого робота: https://translate.yandex.ru.

Немного запереживал о будущем, которое нас ждёт. На кого переучиваться предстоит? Таксисты и водители автобусов тоже будут не нужны. С программистами и так всё понятно. Тестировал плагин для IDE, который приказывает кремниевым мозгам писать код на JavaScript и, знаете, у него получается 😲.

#сервис #bash
​​Смотрите, какая прикольна штука есть для подключения по SSH из консоли - sshto. Это небольшой bash скрипт, который позволяет через псевдографическое меню управлять преднастроенными SSH подключениями. Хорошее решение для самодельного jumphost.

Это когда вы используете промежуточный сервер для подключения к целевым серверам. Такой подход позволяет гибко управлять доступом на основе пользователей jump севера, логировать команды и записывать вывод консоли. И всё без каких-то специализированных решений. В основном средствами самого Linux и его небольших утилит. У меня в разное время были различные заметки по этой теме. Если интересно, могу собрать их в одну.

Вернёмся к sshto. Как я уже сказал, это bash скрипт, который читает конфигурацию из файла ~/.ssh/config и выводит список серверов оттуда в псевдографическое меню. Вот пример такого файла:

#Host DUMMY #Moscow#

Host server-number-one #First Server
HostName 1.2.3.4
port 22777
user root

Host server-number-two #Second server
HostName 4.3.2.1
port 22888
user username

#Host DUMMY #Saint Petersburg#

Host server-number-three #Third server
HostName 5.6.7.8
port 22
user user01

Host server-number-four #Fourth server
HostName 9.8.7.6
port 22
user user02

Ставим sshto:
# git clone https://github.com/vaniacer/sshto
# cd sshto/
# cp sshto /usr/bin/
Запускаем:
# sshto

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

#ssh #bash #script