ServerAdmin.ru
28K subscribers
220 photos
25 videos
10 files
2.54K links
Авторская информация о системном администрировании.

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

Второй канал: @srv_admin_live
Сайт: serveradmin.ru
Download Telegram
​​У меня в управлении много различных серверов. Я обычно не заморачивался с типом файловых систем. Выбирал то, что сервер ставит по умолчанию. Для серверов общего назначения особо нет разницы, будет это 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
​​Вы знали, что curl умеет отправлять почту через внешние smtp серверы? Я в целом знаю, что curl умеет всё, что только можно придумать про передачу данных, но конкретно вопрос не прорабатывал, хотя вскользь уже упоминал об этом, но в рамках решения другой задачи, поэтому особо не погружался в тему. Поэтому для отправки почты из консоли всё время ставлю какую-то дополнительную утилиту, типа mailx. На самом деле это не обязательно. Сейчас покажу, как отправлять почту через curl, не светя пароль в консоли.

Сразу ссылка на документацию. Оправляем почту полностью через ключи curl:

# curl -v --url "smtp://mail.server.ru:25" --mail-from "root@server.ru" --mail-rcpt "user@gmail.com" --user 'root@server.ru:password123' --upload-file ~/mail.txt

Содержимое mail.txt примерно следующее:

From: "Vladimir" <root@server.ru>
To: "User" <user@gmail.com>
Subject: Mail from curl

Hello! How are you?

Причём с помощью curl очень удобно управлять адресом отправителя. В mail.txt его любой указать можно, а не тот, от которого идёт отправка. Впрочем, как и другие заголовки.

Не очень хорошая идея светить почтовый пароль в консоли. Можно его спрятать в .netrc файл. Для этого его надо создать в домашней директории пользователя ~/.netrc. Содержание такое:

machine mail.server.ru login root@server.ru password password123
machine mail.server02.ru login user@server02.ru password password12345

Каждый сервер на новой строке. Удобно, если используется отправка через несколько разных серверов. В соответствии с указанным smtp сервером берутся настройки учётной записи из файла .netrc. Команда на отправку с использованием .netrc будет такая:

# curl -v --url "smtp://mail.server.ru:25" --mail-from "root@server.ru" --mail-rcpt "user@gmail.com" --netrc --upload-file ~/mail.txt

Так как мы используем ключ -v, в консоли видим весь лог общения с почтовым сервером, что может быть удобно для отладки. Если не указывать никаких ключей для TLS, то будет использоваться нешифрованное соединение. Если нужно только шифрованное, то можно добавить ключ --ssl-reqd, а если хотите чтобы при поддержке сервером шифрование использовалось, а если поддержки нет, то нет, тогда добавьте ключ --ssl.

Если используется шифрованное соединение и порт 465, то достаточно просто указать адрес сервера в виде smtps://mail.server.ru. Отдельно указывать порт и ключи для ssl не обязательно.

Для того, чтобы явно указать HELO / EHLO при отправке, добавьте его через слеш после адреса сервера. Примерно так:
smtp://mail.server.ru/client_helo.server.ru

#terminal #curl
​​Когда готовил материал по отправке email сообщений через curl, подумал, он же наверное и читать умеет. И не ошибся. Curl реально умеет читать, и не только, почту по imap. Это открывает очень широкие возможности по мониторингу почтовых серверов с помощью утилиты.

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

Но с curl всё получается намного проще. Она много чего умеет. Расскажу по порядку. Сразу важная сноска, которая сильно затормозила меня в этом вопросе. Когда будете пробовать, возьмите свежую версию curl. Более старые некоторые команды для imap не поддерживают. Я сначала наткнулся на это в старом сервере Centos 7. Потом уже перешёл на современный Debian и там всё получилось.

Сразу перенесём логин с паролем в отдельный файл ~/.netrc:

machine mail.server.tld login username password supersecretpw

Проверяем количество сообщений в imap папке INBOX:

# curl "imap:/mail.server.tld" -n -X 'STATUS INBOX (MESSAGES)'
* STATUS INBOX (MESSAGES 405)

Получили число 405. Посмотрим, сколько из них непрочитанных:

# curl "imap://mail.server.tld" -n -X 'STATUS INBOX (UNSEEN)'
* STATUS INBOX (UNSEEN 147)

147 непрочитанных сообщений. Думаю, идею вы поняли. С помощью curl можно напрямую передавать серверу команды imap.

Смотрим список директорий в ящике:

# curl "imap://mail.server.tld" -n -X 'LIST "" "*"'
* LIST (\HasNoChildren \Marked \Trash) "/" Trash
* LIST (\HasNoChildren \UnMarked \Junk) "/" Junk
* LIST (\HasNoChildren \UnMarked \Drafts) "/" Drafts
* LIST (\HasNoChildren \Sent) "/" Sent
* LIST (\HasChildren) "/" INBOX

Или просто:

# curl "imap://mail.server.tld" -n

Ищем в ящике письма с темой test:

# curl "imap://mail.server.tld/INBOX?SUBJECT%20test" -n
* SEARCH 62 404 405 406
или так:
# curl "imap://mail.server.tld/INBOX" -n -X 'SEARCH HEADER Subject test'

Сообщения от определённого адресата:

# curl "imap://mail.server.tld/INBOX" -n -X 'SEARCH From vladimir@zeroxzed.ru'
* SEARCH 292 404 405 406

Получили UIDs писем. Смотрим содержание письма с конкретным UID. Для этого надо добавить ключ -v, так как оно передаётся в отладочной информации, как и все остальные ответы сервера:

# curl -v "imap://mail.server.tld/INBOX" -n -X 'FETCH 406 BODY[TEXT]'
или так:
# curl -v "imap://mail.server.tld/INBOX;UID=406/;BODY=TEXT" -n

И так далее. Письмо после проверки можно пометить прочтённым, переместить в другую директорию, удалить. Чтобы осмысленно дёргать imap сервер, достаточно посмотреть описание протокола. Информация по нему легко находится в поиске.

Команды imap рассмотрены в упоминаемом недавно курсе по сетям от Созыкина Андрея. Вот конкретный урок: ▶️ Протокол IMAP. Вообще, было интересно во всём этом разобраться. Если надо будет настроить мониторинг очередного почтового сервера, попробую что-то применить с помощью curl.

Первое, что приходит в голову в плане мониторинга - отправлять письмо с меткой времени в теле, а потом забирать его и анализировать эту метку. Если метка старая, значит письма не ходят. Это надёжнее, чем просто проверять статус служб и доступность портов. Тут и smtp, и imap сервер проверяются. И реализуется полностью с помощью curl и zabbix.

#curl #terminal
​​Когда на тестовом стенде разворачиваешь что-то кластерное и надо на нескольких хостах выполнить одни и те же действия, внезапно может помочь tmux. У него есть режим синхронизации панелей. С его помощью можно делать одновременно одно и то же на разных хостах.

Работает это так. Ставим tmux:

# apt install tmux

Запускаем на одном из хостов и открываем несколько панелей. По одной панели на каждый хост. Делается это с помощью комбинации клавиш CTRL-B и дальше либо %, либо ". Первое - это вертикальное разделение, второе - горизонтальное. Переключаться между панелями с помощью CTRL-B и стрелочек. В общем, всё стандартно для тех, кто работает с tmux.

После этого в каждой панели нужно подключиться по SSH к нужному хосту. У вас получится несколько панелей, в каждой отдельная консоль от удалённого хоста. Теперь включаем режим синхронизации панелей. Нажимаем опять префикс CTRL-B и дальше пишем снизу в командной строке tmux:

:setw synchronize-panes

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

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

#linux #terminal
​​Как бы вы решили следующую задачу.

Как проверить, есть ли обращение клиента на порт TCP 22 сервера с определённого IP адреса и порта?

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

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

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

# netstat -ntu
# ss -ntu

Нужный адрес и порт можно грепнуть:

# netstat -ntu | grep ':22'

Менее очевидный вариант с помощью lsof:

# lsof -ni TCP:22

Если же речь вести про прошлые, а не активные соединения, то первое, что мне приходит на ум из подручных системных средств - логирование с помощью firewall. В iptables я это делаю примерно так:

# iptables -N ssh_in
# iptables -A INPUT -j ssh_in
# iptables -A ssh_in -j LOG --log-level info --log-prefix "--IN--SSH--"
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Сделал отдельную цепочку для логирования и отправил туда запись всех пакетов с портом назначения 22. Логи будут по умолчанию собираться в системном логе syslog. При желании можно в отдельный файл вынести через правило в rsyslog. Отдельную цепочку для каждой службы я обычно не делаю. Вместо этого создаю три цепочки - input, output, forward, куда добавляю правила для тех адресов и портов, которые я хочу логировать.

Это всё, что мне пришло в голову по данному вопросу. Если знаете ещё какие-то способы, то напишите. Будет интересно посмотреть.

Пока заканчивал материал, вспомнил про ещё один:

# cat /proc/net/nf_conntrack | grep 'dport=22'

В принципе, это тот же самый ss или netstat. Они скорее всего отсюда и берут информацию.

#network #terminal
​​Перебираю иногда старые публикации в поисках интересной и актуальной информации. Каналу уже много лет и что-то из старого не потеряло актуальность, а аудитория с тех пор выросла в разы. Нашёл утилиту bat, как аналог cat и less одновременно.

Со времён первого упоминания утилиты bat не было в базовых репозиториях Debian (была в sid) и ставить приходилось вручную бинарник. Очевидно, что это неудобно и не располагает к регулярному использованию. С тех пор ситуация изменилась и теперь эту удобную программу можно поставить из стандартного репозитория:

# apt install bat

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

# batcat /etc/passwd
# batcat /var/log/syslog

Короткий файл она целиком выводит в терминал с подсветкой и нумерацией строк, а длинный, который не умещается на экран, подгружает по мере прокрутки вниз, как less. То есть по сути она заменяет две эти стандартные утилиты.

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

При просмотре больших файлов, горячие клавиши такие же, как у less, так что привыкать не придётся:

▪️ Стрелка вверх – перемещение на одну строку вверх
▪️ Стрелка вниз – перемещение на одну строку вниз
▪️ Пробел или PgDn – перемещение на одну страницу вниз
▪️ b или PgUp – переместить на одну страницу вверх
▪️ g – переместить в начало файла
▪️ G – переместить в конец файла
▪️ ng – перейти на n-ю строку

Ещё bat умеет:
хранить свои настройки в файле конфигураций
интегрироваться с git
показывать непечатаемые символы (ключ -A или настройка в конфиге)
интегрироваться с разными утилитами (find, tail, man и другими)
использовать разные темы и подсветки синтаксиса

В общем, утилита удобная. Быстро набрала популярность, кучу звёзд на github, поэтому приехала в стандартные репозитории почти всех популярных дистрибутивов Linux. И даже во FreeBSD и Windows. Не нашёл только в RHEL и его форках. Единственный заметный минус - если нужно будет скопировать какую-то строку, то будет захватываться псевдографика с нумерацией строк. Так что для просмотра удобно, для копирования длинных строк - нет.

Исходники / Описание на русском

#terminal
Небольшая шпаргалка с командами, которая пригодится, когда у вас закончилось свободное место на дисках на сервере под управлением Linux.

🟢 Смотрим, что у нас вообще по занимаемому месту:

# df -h

🟢 Если в какой-то точке монтирования занято на 100% свободное место, можно быстро посмотреть, в каких конкретно директориях оно занято. Тут может быть много разных вариантов:

# du -h -d 1 / | sort -hr
# du -hs /* | sort -hr
Ограничиваем вывод:
# du -h -d 1 / | sort -hr | head -10
Смотрим топ 20 самых больших директорий:
# du -hcx --max-depth=6 / | sort -rh | head -n 20
Смотрим топ 20 самых больших файлов:
# find / -mount -ignore_readdir_race -type f -exec du -h "{}" + 2>&1 \
> | sort -rh | head -n 20

🟢 На всякий случай проверяем inodes. Иногда свободное место заканчивается из-за них:

# df -ih

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

# lsof | grep '(deleted)'
# lsof +L1

Если увидите там файлы большого размера, то посмотрите, какая служба их держит открытыми и перезапустите её. Обычно это помогает. Если служба зависла, то грохните её принудительно через kill -9 <pid>.

🟢 Ещё один важный момент. Может получиться так, что du оказывает, что всё место занято. В файловой системе напрямую вы не можете найти, чем оно занято, так как сумма всех файлов и директорий явно меньше, чем занято места. Среди удалённых файлов тоже ничего нет. Тогда проверяйте свои точки монтирования. Бывает так, что у вас, к примеру, скриптом монтируется сетевой диск в /mnt/backup и туда копируются бэкапы. А потом диск отключается. Если по какой-то причине в момент бэкапа диск не подмонтируется, а данные туда скопируются, то они все лягут на корневую систему, хоть и в папку /mnt/backup. Если после этого туда смонтировать сетевой диск, то ранее скопированные файлы будут не видны, но они будут занимать место. Ситуация хоть и кажется довольно редкой, но на самом деле она иногда случается и я сам был свидетелем такого. И читатели писали такие же истории. Вот одна из них. Поэтому если скриптом подключаете диски, то всегда проверяйте, успешно ли они подключились, прежде чем копировать туда файлы. Вот примеры, как это можно сделать.

#bash #terminal
​​Нравятся тенденции последних лет по принятию разных полезных современных утилит в базовые репозитории популярных дистрибутивов. Недавно рассказывал про hyperfine и bat. К ним можно теперь добавить утилиту duf, как замену df. Она теперь тоже переехала в базовый репозиторий:

# apt install duf

Когда первый раз про неё писал, её там не было. Качал бинарник вручную. Рассказывать про неё особо нечего. Так же, как и df, duf показывает использование диска разных устройств и точек монтирования. Вывод более наглядный, чем в df. Плюс, есть несколько дополнительных возможностей, которые могут быть полезны:

▪️ Умеет делать вывод в формате json:
# duf -json

▪️ Умеет сразу сортировать по разным признакам:
# duf -sort size
# duf -sort used
# duf -sort avail

▪️ Умеет группировать и сортировать устройства:
# duf --only local
# duf --only network
# duf --hide local
# duf --only-mp /,/mnt/backup
и т.д.

То есть эта штука удобна не только для визуального просмотра через консоль, но и для использования в различных костылях, велосипедах и мониторингах. Не нужно парсить регулярками вывод df, а можно отфильтровать, выгрузить в json и обработать jq. Написана duf на GO, работает шустро. Хороший софт, можно брать на вооружение.

#linux #terminal
​​Для тех, кто не любит читать многостраничные man, существует его упрощённая версия, поддерживаемая сообществом — tldr. Аббревиатура как бы говорит сама за себя — Too long; didn't read. Это урезанный вариант man, где кратко представлены примеры использования консольных программ в Linux с минимальным описанием.

Для просмотра информации из tldr можно использовать консольный клиент, либо просто пользоваться веб версией. Описание каждой программы умещается в одну страницу. Авторы, судя по всему, последователи чеховского принципа: "Краткость сестра таланта".

Вот пример выдачи для lsof:

lsof — Lists open files and the corresponding processes. Note: Root privileges (or sudo) is required to list files opened by others. More information: https://manned.org/lsof.

● Find the processes that have a given file open:
lsof path/to/file
● Find the process that opened a local internet port:
lsof -i :port
● Only output the process ID (PID):
lsof -t path/to/file
● List files opened by the given user:
lsof -u username
● List files opened by the given command or process:
lsof -c process_or_command_name
● List files opened by a specific process, given its PID:
lsof -p PID
● List open files in a directory:
lsof +D path/to/directory
● Find the process that is listening on a local IPv6 TCP port and don't convert network or port numbers:
lsof -i6TCP:port -sTCP:LISTEN -n -P

В принципе, всё основное охватили. Кому интересно, может посмотреть мою подборку с примерами использования lsof. Я тоже люблю такие краткие выжимки с примерами. Надо будет собрать их все в одну публикацию. На канале уже много набралось по многим популярным утилитам.

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

▪️ cheat.sh — он удобнее организован, можно информацию получать через curl сразу в консоль, без установки клиента
▪️ explainshell.com — тут немного другой принцип, на основе man выдаёт описание длинных команд с разными ключами

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

🔥 shellcheck.net — проверка синтаксиса shell скриптов

#linux #terminal