ServerAdmin.ru
31.3K subscribers
669 photos
55 videos
22 files
2.87K links
Авторская информация о системном администрировании.

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

Второй канал: @srv_admin_live
Сайт: serveradmin.ru

Регистрация в РКН: https://vk.cc/cG1Urj
Download Telegram
​​Для того, чтобы начать собирать логи в Elasticsearch не обязательно поднимать полный ELK stack. Я сейчас кратко покажу, как быстро запустить сбор логов из Nginx в Elasticsearch помощью Vector. А в качестве веб интерфейса для работы с еластиком буду использовать легковесный Elasticvue.

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

Запускаем Elasticsearch:

# docker run -d -p 9200:9200 -p 9300:9300 \
-e "http.cors.enabled=true" \
-e "http.cors.allow-origin=https://172.30.245.222:8080" \
-e "discovery.type=single-node" \
--name elastic \
elasticsearch:8.13.0

Здесь 172.30.245.222 - это IP адрес сервера, на котором будет запущен веб интерфейс Elasticvue. В моём случае это та же машина, где запускается еластик. Дожидаемся запуска контейнера и забираем из него конфиг службы:

# docker cp elastic:/usr/share/elasticsearch/config/elasticsearch.yml ~/

Всё, что касается настроек xpack.security заменяем true на false. Возвращаем изменённый конфиг:

# docker cp ~/elasticsearch.yml elastic:/usr/share/elasticsearch/config/elasticsearch.yml

Перезапускаем контейнер:

# docker restart elastic

Дожидаемся запуска и проверяем работу:

curl https://172.30.245.222:9200

Должны увидеть информацию о кластере elasticsearch. Его имя будет docker-cluster. Запускаем тут же в докере веб интерфейс:

# docker run -d -p 8080:8080 --name elasticvue cars10/elasticvue

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

Идём в веб интерфейс по IP адресу сервера и порт 8080. Настраиваем подключение к кластеру. Указываем настройки:
No authorization
docker-cluster
https://172.30.245.222:9200

Убеждаемся, что всё работает.

Теперь ставим Vector, который будет отправлять логи Nginx в кластер. Он, соответственно, должен быть установлен на веб сервере. Для Debian установка из пакетов такая:

# bash -c "$(curl -L https://setup.vector.dev)"
# apt install vector

Открываем конфиг /etc/vector/vector.yaml и приводим к такому виду:

sources:
 nginx_access_logs:
  type: file
  include:
   - /var/log/nginx/access.log
sinks:
 elastic:
  type: elasticsearch
  inputs:
   - nginx_access_logs
  endpoints:
   - https://172.30.245.222:9200

Следите за форматированием файла yaml. При копировании в пост она ломается. У вектора очень хорошая документация. Там есть все примеры использования. Можно у меня заметки на канале посмотреть. Было несколько штук с его настройкой. Очень приятная и легковесная программа. Я последнее время почти всегда вектором собираю логи.

Перезапускаем вектор:

# systemctl restart vector

По умолчанию, он пишет логи в системный syslog. Проверьте на всякий случай, что он запустился и начал отправлять логи в elastic. Идём в его веб интерфейс. Там должен появиться индекс вида vector-2024.04.22, в нём строки из лога Nginx.

Простейшие действия по управлению кластером Elasticsearch можно делать в Elasticvue. Можно обойтись и без Kibana. Вот такая простая и быстрая настройка. Если вы не отключите HTTPS и аутентификацию, то вам придётся дополнительно сделать следующее:

Создать пароль для пользователя elastic через команду внутри контейнера /bin/elasticsearch-reset-password.
Соответственно во всех запросах использовать basic аутентификацию с этой учёткой.
Для работы Elasticvue вам нужно будет забрать сертификат Elasticsearch из /usr/share/elasticsearch/config/certs/http_ca.crt и добавить его в доверенные CA в том браузере, где вы его будете запускать. Далее нужно будет посмотреть, какие имена хоста указаны в сертификате сервера и добавить их в hosts, чтобы браузер не ругался на несоответствие имени в сертификате и адресной строке.

Я всё это настраиваю, если надо, но занимает чуть больше времени, поэтому упростил руководство.

#elk
👍63👎3
​​Для тестирования производительности PostgreSQL есть относительно простая утилита pgbench, которая входит в состав установки PostgreSQL. Ставить отдельно не придётся. Даже если вы несильно разбираетесь в тюнинге СУБД и не собираетесь им заниматься, pgbench хотя бы базово позволит сравнить разные конфигурации VM, разных хостеров, разное железо. Например, сравнить, на какой файловой системе или на каком дисковом хранилище будут лучше показатели быстродействия. Просто создайте две разные виртуалки и сравните.

Тест выполняет на существующей базе данных. В ней создаются служебные таблицы и наполняются данными. Покажу, как это выглядит на практике. Ставим postgresql:

# apt install postgresql

Проверяем, что работает:

# systemctl status postgresql

Создаём базу данных:

# su - postgres
$ psql
$ create database test_db;
$ \q

Наполняем тестовую базу данными, увеличив стандартный набор в 10 раз:

$ pgbench -i test_db -s 10

Запускаем тест в 5 клиентов, в 2 рабочих потока, на 60 секунд с отсечкой результата каждые 5 секунд, чтобы в консоли интересно наблюдать было. Если будете в файл выводить результаты, то это делать не надо.

$ pgbench test_db -c 5 -j 2 -P 5 -T 60

transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 5
number of threads: 2
maximum number of tries: 1
duration: 60 s
number of transactions actually processed: 219950
number of failed transactions: 0 (0.000%)
latency average = 1.362 ms
latency stddev = 0.661 ms
initial connection time = 8.368 ms
tps = 3665.930847 (without initial connection time)

СУБД обработала 219950 транзакций со средней скоростью 3665.930847 транзакций в секунду. Эти данные и стоит сравнивать.

По умолчанию pgbench запускает смешанный TPC-B (Transaction Processing Performance Council) тест, который состоит из пяти команд SELECT, UPDATE и INSERT в одной транзакции. Сценарий можно менять, создавая собственные скрипты для тестирования. Все возможности pgbench подробно описаны на русском языке в документации от postgrespro.

Из любопытства перекинул тестовую виртуалку с обычного одиночного SSD на RAID10 из 4-х HDD. Настройки в Proxmox те же, кэширование гипервизора отключено (Default (No cache)). Прогнал этот же тест.

tps = 2262.544160

Получилось на ~40% медленнее при идентичных настройках.

#postgresql
👍110👎3
​​У браузера Firefox и всех остальных, что созданы на его основе, есть отличительная особенность, которая кому-то нравится, кому-то нет. Всё зависит от ситуации. У этого браузера своё собственное хранилище сертификатов, куда можно добавлять доверенные центры сертификации, минуя системное хранилище ОС. Для централизованного управления это скорее минус, а для индивидуального использования больше плюс.

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

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

Всё это можно сделать. Но, к примеру, у меня наберётся с десяток одиночных гипервизоров, где я не буду всего этого делать, потому что нет смысла. Доступ из интернета к ним открывать не буду. Я работаю с ними один, к ним нет доступа из интернета. Они принадлежат разным проектам и не объединены между собой. Мне проще забрать с этих гипервизоров pve-root-ca.pem, добавить в браузер, чтобы не засорять систему и сохранить учётки для быстрого входа. Доступ к ним всё равно закрыт списками IP адресов на файрволе.

Для того, чтобы настроить доверие для самоподписанного сертификата Proxmox, который создаётся во время установки гипервизора, надо зайти в веб интерфейсе в раздел System ⇨ Certificates. Выбрать сертификат pve-root-ca.pem, открыть его исходный текст. Скопировать и сохранить его в любой текстовый файл, указав ему расширение .crt.

Далее идём в браузер на основе Firefox. Я использую портированный LibreWolf. Переходим в Settings ⇨ Privacy & Security ⇨ Certificates ⇨ View Certificates. Там делаем Import сохранённого сертификата. Теперь из этого браузера при входе на веб интерфейс Proxmox не будет предупреждения. У вас появится возможность сохранить данные аутентификации.

#proxmox
👍124👎4
​​Расскажу про очень простую и функциональную систему отправки уведомлений во все современные каналы - Apprise. Она представляет из себя консольное приложение, в которое через параметры командной строки можно передавать настройки для отправки уведомлений.

Apprise поддерживает Telegram, Discord, Mattermost, NextcloudTalk, Revolt, Rocket.Chat, Slack, WhatsApp и т.д. Помимо мессенджеров сообщения можно доставлять в Syslog, Pushover, ntfy, Mailgun, обычную почту и кучу других сервисов, в том числе пуши на комп можно отправлять. Они все перечислены в репозитории. Список очень большой.

Работает это примерно так. Ставим Apprise из pip:

# apt install python3-pip
# pip install apprise --break-system-packages

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

# uptime | apprise -vv \
  'tgram://1393668911:AAHtETAKqxUH8ZpyC28R-wxKfvH8WR6-vdNw/211805263'

От правили вывод утилиты uptime в Telegram. Формат конфигурации такой:

tgram://bottoken/ChatID

или для нескольких чатов

tgram://bottoken/ChatID1/ChatID2/ChatIDN

Понятно, что только для Telegram это не имеет смысла. Туда можно и напрямую слать. Идея в том, что у тебя один инструмент объединяет все каналы. Можно сделать конфиг, в котором будут указаны разные каналы. Отправив информацию в apprise, он сам разошлёт по всем указанным направлениям. Ну и как плюс, более простая настройка, так как формат настроек разных направлений примерно одинаковый. Это просто удобно.

С помощью Apprise легко настроить отправку пушей через сервис pushover.net. У него бесплатный тарифный план позволяет отправлять 10,000 в месяц. Для многих задач этого будет заглаза.

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

Система простая в настройке. Не надо изучать и разбираться с API сторонних сервисов. В Apprise они уже все собраны, а работа с ними унифицирована с помощью встроенного API или конфигураций. У продукта есть подробная wiki.

Исходники / Docker

#мониторинг
👍117👎5
​​С момента перехода на Windows 11 я неизменно страдал (не сильно) от глючащего переключения раскладки клавиатуры. Оно по неведомой мне причине иногда не срабатывало. Как-то отследить и понять закономерность не получалось. То сразу переключает, то со второго или третьего раза.

Терпел я это долго, так как с наскока не получалось решить проблему. Причём переключение по комбинации клавиш win+пробел срабатывало всегда. А по настроенному мной левому ctrl+shift через раз. Так как я использую Punto Switcher, то выходил из ситуации относительно просто. Автоматом менял раскладку уже напечатанного текста, когда не сработало переключение.

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

https://www.elevenforum.com/t/horrible-keyboard-input-language-switch-lag-after-win-11-22h2-update.11418/

Там же есть демонстрация этого глюка в виде записи экрана. Я сразу понял, что проблема один в один как у меня. Как оказалось, причина тормозов с переключением - новое окошко, которое выскакивает при переключении раскладки. Снизу прикреплена картинка с этим окном. Из-за того, что подтормаживает его отрисовка, не всегда переключается раскладка при быстром нажатии клавиш. Если зажать клавиши и подержать секунду, то гарантированно переключается.

Адекватного решения проблемы средствами Windows, как я понял, не существует. Люди просто отключают переключение раскладки в винде и переключают раскладку сторонним софтом. Я так и сделал. Включил переключение раскладки по кнопке Caps Lock через Punto Switcher. Я всё равно её не использую. Так переключать даже удобнее. Уже привык.

Сколько сюрпризов и неудобств привнесла Windows 11. Если бы знал о них заранее, оставался бы на десятке. Я тут кое о чём писал уже. Например, о неработающей аутентификации с учётной записью Администратор, или о невозможности перенести панель задач на правую сторону экрана.

#windows
👍115👎8
​​На днях вышло обновление Proxmox 8.2, в котором появилось несколько интересных нововведений. Самое полезное на мой взгляд - импорт виртуальных машин из VMware ESXi. Я не сразу понял, как это реализовано. Обновил тестовый гипервизор, всё там пересмотрел и не нашёл импорт. Полез в документацию.

1️⃣ Работает он следующим образом. В списке Storage, доступных для добавления, появился новый тип - ESXi. Для добавления нужно указать его адрес и рутовую учётку. После этого в списке этого хранилища будут отображаться виртуальные машины хоста ESXi, откуда можно быстро выполнить импорт. Сделано удобно с минимум необходимых телодвижений. Жду, когда то же самое появится для Hyper-V. Лично для меня это более актуально.

2️⃣ Второе значительное изменение - появилась возможность в качестве встроенного файрвола использовать nftables, а не iptables. Пока это надо явно включить. Переход на nftables только прорабатывают, собирают обратную связь. В будущих релизах он заменит iptables окончательно. Так что можно потихоньку переползать. Кто не знаком с nftables, у меня есть небольшая статья по базовым правилам.

3️⃣ Третье важное дополнение. В настройках встроенных бэкапов появилась новая вкладка Advanced с дополнительными настройками процесса снятия бэкапов. Туда переехали настройки по ограничению ширины канала при бэкапе. А также добавилась новая настройка Backup fleecing, которая включает режим буферизации на локальный диск. Перед передачей на внешнее хранилище, бэкап работающей машины может кэшироваться на отдельном локальном storage, который можно выбрать из подключенных. Это снизит нагрузку на работающую VM во время снятия бэкапа и в целом ускорит процесс, так как кэшировать можно на наиболее ненагруженное хранилище. Возможно будет иметь смысл выделить отдельное хранилище под это дело.

Остальные изменения не такие существенные, поэтому перечислю их кратко:
появилась утилита proxmox-auto-install-assistant для подготовки установочного образа с готовыми настройками для установки без участия человека;
в веб интерфейс добавлена возможность настройки проброса устройств в lxc контейнеры;
в настройках ACME можно добавить любой другой удостоверяющий центр, отличный от Let's Encrypt;
изменились некоторые настройки веб интерфейса: не активируется режим редактирования полей при попытке скопировать данные оттуда, актуально, к примеру, для поля Notes с описанием VM, также изменилось положение кнопки с отменой введённых настроек.

Посмотреть, как все изменения выглядят в веб интерфейсе, можно вот в этом видео:

▶️ https://www.proxmox.com/en/services/videos/proxmox-virtual-environment/whats-new-in-proxmox-ve-8-2

Нравится, как команда Proxmox оформляет все свои обновления. Максимально подробно и текстом, и в виде роликов. Другим компаниям бы брать пример.

#proxmox
👍160👎3
​​В продолжение темы с уведомлениями в Apprise. Есть продукт на его основе, который умеет конвертировать email сообщения в уведомления apprise. Называется Mailrise. По своей сути это SMTP gateway для apprise.

Он поднимается как обычный SMTP сервер. Принимает сообщения и переадресует их в зависимости от настроек в необходимые каналы уведомлений. И речь тут может идти не только об уведомлениях в мессенджеры, смс, пуши и т.д. Например, mailrise может отправить email в формате JSON через HTTP POST запрос. Может в Syslog сделать запись с заголовком и текстом письма, может переслать на другой SMTP сервер. Продукт универсальный.

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

Покажу на примере, как это работает. Для начала установим Mailrise. Сделать это можно либо через pip, либо запустить в Docker. Я беру второй вариант, поэтому сразу подготовим конфигурационный файл, который мы передадим в контейнер.

Я буду принимать почту и отправлять уведомление в Telegram и Syslog. Для этого готовлю такой конфиг mailrise.conf в формате yaml :

configs:
 telegram:
  urls:
   - tgram://1393668911:AAHtETAKqxUH8ZpyC28R-wxKfvH8WR6-vdNw/211805263
 rsyslog:
  urls:
   - rsyslog://172.30.245.222

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

# docker run -d -p 8025:8025 --restart always \
-v ~/mailrise/mailrise.conf:/etc/mailrise.conf \
--name mailrise \
yoryan/mailrise

Почтовый сервер готов принимать почту на порту 8025. Отправляю тестовое сообщение. Проще всего это сделать через PowerShell:

> send-mailmessage -from "admin@local" -to "Telegram <[email protected]>","Rsyslog <[email protected]>" -subject "Message from Mailrise" -body "Test Message" -smtpserver 172.30.245.222 -port 8025

В данном случае адреса [email protected] и [email protected] вымышленные. Имеет значение только название перед @. Оно должно соответствовать названиям конфигов в mailrise.conf. То есть если отправить почту только на [email protected], то оповещение придёт только в Telegram. То есть вот так:

> send-mailmessage -from "admin@local" -to "Telegram <[email protected]>" -subject "Message from Mailrise" -body "Test Message" -smtpserver 172.30.245.222 -port 8025

В Linux через консоль с указанием релея отправки проще всего использовать ssmtp. Для этого её надо установить и нарисовать простой конфиг:

# apt install ssmtp

В конфиг /etc/ssmtp/ssmtp.conf пишем:

root=admin@local
mailhub=172.30.245.222:8025
hostname=debian12.homelab.local

Отправляем почту через mailrise:

# echo "Test Message" | mail -s "Message from Mailrise" [email protected] [email protected]

Оповещение прилетит в Telegram и Rsyslog. В последнем будет примерно такая запись в логе:

2024-04-25T14:55:20.717270+03:00 172.17.0.2 - 1 - Message from Mailrise (admin@local): Test Message

Соответственно, можно указать отдельный facility и настроить в rsyslog.conf приём этих уведомлений в отдельный файл.

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

Если нужна аутентификация, то добавить её можно следующими настройками в конфиге:

smtp:
 auth:
  basic:
   user01: password01

Исходники / Видеообзор

#mailserver
👍61👎1
​​Пока прошлые статьи писал про сертификаты и Proxmox, возник вопрос. А как добавить в доверенные сертификат от Proxmox Backup Server, чтобы браузер не ругался? У него почему-то нет CA сертификата в веб интерфейсе, как в VE, который можно добавить в доверенные.

Немного поискал информацию и нашёл в официальной wiki на эту тему отдельную статью. Меня в ней привлекло вот что. В самом конце рассматривается случай, когда PBS и VE стоят на одной машине (Using Certificates from Proxmox VE). Авторы предлагают для PBS использовать тот же сертификат, что и для VE.

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

Пошёл смотреть документацию по установке PBS. Там есть отдельный раздел Install Proxmox Backup Server on Proxmox VE. Так что технически никаких проблем нет. Можно ставить PBS на хост виртуализации. Есть единственное предупреждение:

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

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

В целом, я бы всё же не рекомендовал ставить на один хост и PBS, и VE. Мне кажется, лучше в виртуалке (или в lxc) поднимать. Я не сторонник что-то настраивать на самих гипервизорах. Тогда они становятся невзаимозаменяемыми. Если есть возможность, лучше всё переносить в виртуальные машины. Если умрёт сервер, то простое восстановление виртуальных машин из бэкапа вернёт всю функциональность. А если что-то на гипервизоре настроено, то надо восстанавливать, и предварительно бэкапить, его настройки. Где-то это может быть оправдано, где-то нет.

Я если что-то и делаю на гипервизоре, так это только iptables настраиваю с nat. Все настройки - это единственный конфиг для iptables. Нетрудно сохранить.

#proxmox
👍68👎3
▶️ Всем хороших выходных в праздники. Сначала думал в выходные сделать подборку видео, но в итоге передумал. Сделаю сейчас, а в выходные отдохну в том числе и от компа. Как обычно, ниже те видео из моих подписок за последнее время, что мне показались интересными.

Протокол HTTP | Компьютерные сети 2024 - 10
Очередной урок с обновлённого курса по сетевым технологиям от Андрея Созыкина. Коротко, доступно и наглядно дана база.

Best Docker Containers in 2024
Обзор Docker контейнеров для дома, которые автор посчитал полезными в повседневной жизни. Среди них Plex, Pi-Hole, Dashy, Uptime Kuma, Mailrise, Adguard Home и другие.

Мониторинг веб-сервера Angie с помощью Prometheus
Разбор мониторинга Angie через готовый экспортер Angie и их же дашборда для Grafana. Очень простая и лёгкая настройка. Я его уже тоже попробовал и написал заметку.

Web logs are super easy with - GoAccess
Обзор удобной и функциональной утилиты GoAccess для просмотра логов веб сервера через веб интерфейс. Утилита известная, я делал про неё заметку. Если не знакомы - посмотрите и возьмите на вооружение. Логи в ней смотреть - одно удовольствие.

Prometheus - Все Основы Мониторинга, как всё это работает и зачем он вообще нужен?
Prometheus - Как установить Prometheus Сервер на Линукс?
Prometheus - Как установить Node Exporter на Linux серверах?
На канале ADV-IT вышли три ролика на тему Prometheus. Автор снимает отличные ролики. Так как живёт в Канаде и работает там же, большинство его проектов в облаке AWS, так что последнее время его видео были для меня неактуальны, не смотрел. А эти уже в тему. Посмотрел с удовольствием. Там база для новичков.

Zstd (Zstandard): новый стандарт сжатия текста. Полный тест
Стандарт сжатия zstd можно использовать на веб серверах. В Angie есть готовый модуль, так что настроить очень просто. В видео автор рассматривает этот метод, его настройку и сравнивает с существующими популярными методами gzip и brotli для динамического сжатия. Zsdt показал очень хороший результат. По этому ролику сделаю отдельную заметку.

Trigkey S7 Pro Review runs VMware and Proxmox perfectly // Home Lab Server
Обзор производительного неттопа на базе AMD Ryzen 7. Сначала подумал, что какая-то дорогая экзотика, но на самом деле нет. Голый, без памяти и дисков, на али стоит в районе 20 т.р. Хорошее решение для тестового гипервизора домой.

QoS: управление сетевым трафиком, маркировка и приоритизация
Длинный вебинар про QOS в Микротике. Я его не слушал, пролистал. Знаю, что у этого автора всегда хорошие видео, так что если вам интересная данная тема, в том числе и подробная теория по ней, то рекомендую.

More POWER for my HomeLab! // Proxmox Cluster
Автор первый раз собрал свой кластер Proxmox и рассказал об этом. Добавил вторую ноду к основному серверу. Рассказал, как разбирался, как настраивал, как ошибки исправлял. Показал, как работает живая миграция без остановки VM. Буквально 3 пакета ping теряются во время перехода с одной ноды на другую.

#видео
👍68👎2
🔝 ТОП постов за прошедший месяц. Все самые популярные публикации по месяцам можно почитать со соответствующему хэштэгу #топ. Отдельно можно посмотреть ТОП за прошлый год (https://t.iss.one/srv_admin/3379).

Пользуясь случаем, хочу попросить проголосовать за мой канал, так как это открывает некоторые возможности по настройке (не только публикацию историй): https://t.iss.one/boost/srv_admin.

📌 Больше всего просмотров:
◽️Заметка про последовательное параллельное соединение розеток rj45 (10930)
◽️Уязвимость CVE-2024-3094 в OpenSSH сервере (10694)
◽️Игра JOY OF PROGRAMMING (10435)

📌 Больше всего комментариев:
◽️Баг с переключением раскладки в Windows (316)
◽️Заметка про последовательное параллельное соединение розеток rj45 (184)
◽️Заметка про покупку монитора 27" с разрешением 2K (163)

📌 Больше всего пересылок:
◽️Подборка команд и полезных ссылок для Docker (826)
◽️Создание и использование TLS сертификатов через свой CA (716)
◽️Конфигуратор для СУБД PostgreSQL (533)
◽️Обучающая платформа KodeKloud (491)

📌 Больше всего реакций:
◽️Мем Позовите системного администратора (273)
◽️Олдскульный Small HTTP server на С++. (233)
◽️Заметка про покупку монитора 27" с разрешением 2K (198)
◽️Подборка команд и полезных ссылок для Docker (195)

#топ
👍34👎2
​​Сегодня прям сходу после праздников расскажу про необычную систему автоматизации. Я несколько раз за неё брался и каждый раз откладывал, потому что не мог быстро с ней разобраться. В этот раз было побольше доступного времени, поэтому постарался объять и кратко рассказать так, чтобы было понятно.

Речь пойдёт про систему Kestra.io. Сразу скажу, для тех, кто знаком с n8n.io, что она на него немного похожа, но более функциональна. Это такой комбайн по автоматизации всего и вся с управлением через веб интерфейс с участием встроенных процедур и модулей. Эдакий заменитель самописных костылей. Приведу сразу пример задач, которые можно решать с его помощью:

💡Вы получаете pdf файл с таблицей. Вам надо её распознать и занести значения таблицы в базу данных SQL или в CVS файл для дальнейшей выгрузки в Excel. Похожая задача с получением pdf файла, его распознаванием и сохранением текстовой версии.

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

💡Вам необходимо скачать json файл, отфильтровать некоторые данные, обработать их и вывести в веб интерфейсе Kestra.

💡Вы можете создать публичную веб форму, куда после ввода данных будет отправлено уведомление в какой-то чат. Человек в чате посмотрит эти данные и подтвердит их, после чего они будут через веб хук куда-то добавлены. Саму форму можно будет создать в Kestra.

💡Можно запустить shell скрипт и забрать его вывод в веб интерфейсе. За скриптом Kestra умеет ходить по хостам сама. В одном месте можно собрать все cron с хостов и управлять ими из одного места.

💡Можно по HTTP API забрать данные, обработать и положить в формате json в S3, или пульнуть в Zabbix API.

💡Kestra умеет запускать Ansible плейбуки и Terraform файлы, работать с GIT. Можно склонировать репу по какому-то событию и что-то запустить из неё.

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

Всю платформу можно полностью развернуть на своём железе без каких-то ограничений. Всё упаковано в Docker контейнер. Запускать так:

# docker run --pull=always --rm -it -p 8080:8080 --user=root \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /tmp:/tmp kestra/kestra:latest-full server local

И можно идти в веб интерфейс на порт 8080. Сразу всё увидите там.

В платной версии дополнительные энтерпрайзные штуки, типа SSO, RBAC, хранение секретов и т.д.

Kestra по сути такой вспомогательный инструмент, который может работать вместе с системами CI/CD, мониторинга, сбора логов, интегрировать их с какими-то бизнес метриками и получать обработанные данные в человекочитаемом виде, куда-то отправлять их, уведомлять.

В то же время он же может помочь и одному человеку в выполнении какой-то ежедневной рутины. Например, по аналитике каких-то данных из множества источников. Но чтобы разобраться во всём этом, нужно будет потрудиться. Если писали пайплайны, то это будет просто, так как по своей сути задачи (flows) это те же пайплайны в формате yaml. Писать можно прямо в веб интерфейсе. Редактор удобный.

▶️ Несколько видео с примерами задач, которые я посмотрел:
⇨ обработка и работа с pdf
⇨ подробный обзор системы и несколько простых примеров
⇨ обзор от неизвестного итальянца (Я.Браузер отлично перевёл)

Не смог придумать осмысленного тэга для этой системы и других подобного рода. Пусть это будет #автоматизация.

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

#автоматизация
👍89👎2
​​Расскажу про необычную комбинацию клавиш в консоли bash, о которой наверняка многие не знают, а она иногда бывает полезной. Это из серии советов, когда те, кто про него знают, думаю, что тут такого, зачем об этом писать. А кто-то вообще об этом никогда не слышал.

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

Нажимаем комбинацию Alt+Shif+3. После этого к команде автоматически добавляется в самое начало # и команда как-бы выполняется, но на самом деле не выполняется, потому что стоит #. При этом команда улетает вместе с # в history. После этого её можно там посмотреть, либо быстро вызвать через поиск по Ctrl+R. Если искать по #, то она первая и выскочит.

Такой вот маленький трюк. Если не знали, то запомните. Облегчает работу в консоли.

#bash
👍325👎2
​​Существует эффективный стандарт сжатия zstd. Не так давно современные браузеры стали его поддерживать, так что можно использовать в веб серверах. Разработчики Angie подсуетились и подготовили модуль для своего веб сервера, так что включить сжатие zstd максимально просто и быстро. Достаточно установить модуль в виде deb пакета и добавить настройки в конфигурацию, которые идентичны настройкам gzip, только название меняется на zstd.

По этому поводу вышел очень информативный ролик на ютубе:

Zstd (Zstandard): новый стандарт сжатия текста. Полный тест

Автор не только показал, как настроить zstd на веб сервере, но и сравнил его эффективность с привычными gzip и brotli. Результаты тестирования в динамическом сжатии получились очень любопытные. Zstd оказался лучше всех. Но если разница с brotli не сильно заметна, то вот gzip на фоне остальных выглядит очень медленным. Буквально в разы в некоторых случаях.

Я решил провести свои тесты, чтобы убедиться в такой большой разнице. Сразу скажу, что если не настроено https, то браузеры не будут использовать ни brotli, ни zstd. Не знаю, с чем это связано, но я потратил некоторое время, пока не разобрался с тем, почему не работает ничего, кроме gzip. И второй момент. Если на веб сервере настроены все 3 типа сжатия, то разные браузеры выбирают разное сжатие: либо brotli, либо zstd. Gzip не выбирает никто.

Тестировал так же, как и автор ролика. Установил Angie и оба модуля сжатия:

# curl -o /etc/apt/trusted.gpg.d/angie-signing.gpg https://angie.software/keys/angie-signing.gpg

# echo "deb https://download.angie.software/angie/debian/ `lsb_release -cs` main" | tee /etc/apt/sources.list.d/angie.list > /dev/null

# apt update && apt install angie angie-module-zstd angie-module-brotli

Подключил оба модуля в angie.conf:

load_module modules/ngx_http_zstd_static_module.so;
load_module modules/ngx_http_zstd_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
load_module modules/ngx_http_brotli_filter_module.so;

И добавил для них настройки:

  gzip on;
  gzip_static on;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/x-icon image/svg+xml application/x-font-ttf;
  gzip_comp_level 4;
  gzip_proxied any;
  gzip_min_length 1000;
  gzip_vary on;

  brotli on;
  brotli_static on;
  brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/x-icon image/svg+xml application/x-font-ttf;
  brotli_comp_level 4;

  zstd on;
  zstd_static on;
  zstd_min_length 256;
  zstd_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript image/x-icon image/svg+xml application/x-font-ttf;
  zstd_comp_level 4;

Если использовать ванильный Nginx, то придётся самостоятельно собирать его с нужными модулями 🤷‍♂️

Тестировал с помощью ab, передавая ему метод компрессии через заголовок:

# ab -n 1000 -k -c 1 -H "Accept-Encoding: zstd" https://10.20.1.36/scripts.js

Не буду приводить свои результаты, так как они получились примерно такие же, как у автора ролика, только разница между zstd и brotli с компрессией 4 поменьше. Zstd по rps (247) быстрее всех. Brotli чуть лучше жмёт в плане объёма, то есть трафик будет ниже, но и rps (211) немного меньше, чем у zstd.

В Angie очень легко настроить и brotli, и zstd, и gzip, так что имеет смысл это сделать. Клиент пусть сам выбирает, какой тип сжатия он будет использовать.

Один важный момент, который я вынес из этой темы. Не нужно ставить сжатие выше 3 или 4. Дальше идёт очень существенное падение производительности при незначительном уменьшении размера файлов. Я раньше бездумно ставил 9 и думал, что современные процессоры и так нормально вытягивают, если сервер не нагружен в потолок. Это не так. Смысла в высокой компрессии нет.

#webserver #angie
👍84👎1
This media is not supported in your browser
VIEW IN TELEGRAM
Одна из лучших песен по тексту и музыке на тему системных администраторов. Своеобразный гимн, как у программистов. Это перепевка песни "Атланты" Александра Городницкого.

Песня из далёких 90-х годов. Может начало 2000-х. Не смог найти точную инфу. Я её с двухтысячных знаю. Причём, она не кажется сильно устаревшей. Если убрать оттуда зарплату, которую не платят (сейчас в IT всем платят), а сервер заменить на cloud, то и не поймешь, что это глубокая старина.

#юмор #музыка
👍87👎27
​​Решил сделать шпаргалку для копипасты по отправке email с аутентификацией из консоли через внешний smtp сервер. Нередко приходится этим заниматься как напрямую в консоли, так и в каких-то скриптах.

🔹В Linux самый простой вариант через Curl. Но там есть один нюанс, который создаёт неудобство, если вы хотите быстро отправить письмо через консоль. Заголовки и тело письма задаются через отдельный текстовый файл. Чтобы всё это уместить в одну команду, приходится использовать примерно такую конструкцию:

# echo -e "Subject: Test Subject \nTest body message." > /tmp/body.txt && curl -v --url "smtp://mail.server.ru:25" --mail-from [email protected] --mail-rcpt [email protected] --user '[email protected]:password123' --upload-file "/tmp/body.txt"

🔹Если вы будете использовать подобную отправку регулярно, либо где-то в скрипте, то скорее всего захочется вести лог передачи, отслеживать статус отправки и т.д. В таком случае проще всего настроить локально postfix или ssmtp. Для них нужно будет подготовить простой конфиг. Пример для postfix:

# apt install postfix mailutils

Добавляем в конфиг /etc/postfix/main.cf

relayhost = mail.server.ru:25
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may

Создаём файл /etc/postfix/sasl_passwd с данными для аутентификации в таком формате:

mail.server.ru:25 [email protected]:password123

Создаем db файл.

# postmap /etc/postfix/sasl_passwd

Теперь можно перезапустить postfix и проверить работу.

# systemctl restart postfix
# echo "Test body message." | mail -s "Test Subject" [email protected]

Лог отправки, в том числе ответ принимающего сервера, будет в системном логе /var/log/syslog или /var/log/mail.log. Удобно для отладки или мониторинга.

🔹Ниже пример отправки почты через ssmtp.

# apt install ssmtp

В конфиг /etc/ssmtp/ssmtp.conf пишем:

mailhub=mail.server.ru:25
hostname=mail.server.ru
[email protected]
[email protected]
AuthPass=password123
UseSTARTTLS=YES
UseTLS=YES

Отправляем почту:

# echo "Test body message." | mail -s "Test Subject" [email protected]

Утилита mail отправит почту через ssmtp. Я чаще отдаю предпочтение postfix, потому что у него лог кажется более информативным и привычным.

🔹В Windows можно использовать для этих же целей PowerShell. Вот как выглядит там отправка:

> Send-MailMessage -From [email protected] -To [email protected] -Subject "Test Subject" -Body "Test body message." -SmtpServer mail.server.ru -Port 25 -Credential (Get-Credential)

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

#mailserver
👍96👎3
​​В популярных файловых системах на Linux есть одна полезная особенность. Любой файл или каталог можно сделать неизменяемым с помощью атрибута immutable. Его ещё называют immutable bit. Его может установить только root. Он же его может и убрать.

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

Бороться с этим можно разными способами. Например, проверять перед копированием монтирование с помощью findmnt. А можно просто с помощью флага immutable запретить запись в директорию:

# chattr +i /mnt/backup

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

# > /mnt/backup/file.txt
bash: /mnt/backup/file.txt: Operation not permitted

Убираем бит и пробуем ещё раз:

# chattr -i /mnt/backup
# > /mnt/backup/file.txt
# ls /mnt/backup/file.txt
/mnt/backup/file.txt

Посмотреть наличие этого бита можно командой lsattr. Для директории необходимо добавлять ключ -a, для отдельных файлов он не нужен.

# lsattr -a /mnt/backup
--------------e------- /mnt/backup/..
----i---------e------- /mnt/backup/.

Буква i указывает, что immutable bit установлен. Про псевдопапки точка и две точки читайте отдельную заметку.

Можно придумать разное применение этого бита. В основном это будут какие-то костыли, которыми не стоит сильно увлекаться. Например, можно очень просто запретить изменение паролей пользователям. Достаточно установить immutable bit на файл /etc/shadow:

# chattr +i /etc/shadow

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

# passwd root
passwd: Authentication token manipulation error
passwd: password unchanged

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

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

Если знаете ещё какое-то полезное применение immutable, поделитесь в комментах. Я видел, что некоторые /etc/hosts или /etc/resolve.conf им защищают от изменений.

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

#linux
👍197👎4
​​Если вдруг вам хочется чего-нибудь странного, то могу вам кое-что предложить. Например, запустить контейнеры Docker в LXC контейнере Proxmox. Я изначально думал, что это так просто не сработает. Всегда запускаю контейнеры в виртуалках. Тут решил попробовать в LXC, сразу заработало.

Создаёте обычный LXC контейнер с нужными ресурсами. В параметрах через веб интерфейс необходимо установить nesting=1. Далее запускаете его и устанавливаете Docker:

# apt install curl
# curl https://get.docker.com | bash -
# docker run --rm hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

Всё работает. Никаких дополнительных настроек делать не пришлось. Проверял на Proxmox VE 8.2.2. В принципе, удобно. Получается можно спокойно в LXC изолировать контейнеры и запускать их. Мне казалось, что раньше это так не работало.

#proxmox #docker
👍97👎3
​​Недавно один из подписчиков, видя мои посты про прокси по ssh, посоветовал расширение для браузера SwitchyOmega. Я когда-то давно искал подобное, но ничего не нашёл, что устроило бы меня. В итоге просто использовал разные браузеры под разные прокси.

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

Я уже мельком рассказывал, как использую прокси сам. Расскажу ещё раз поподробнее. У меня есть несколько VPS, к которым я могу подключаться по SSH с пробросом портов на локальную машину. Если нужен HTTP прокси, то пробрасываю порт установленной локально на VPS privoxy, если сойдёт и SOCKS, то напрямую подключаюсь через SSH с ключом -D.

На этих VPS открыт только SSH порт с доступом откуда угодно. Сами прокси в интернет не смотрят, поэтому там нет аутентификации, не надо отдельно следить за безопасностью этих прокси. На своей рабочей машине под Windows открываю WSL, там подключаюсь по SSH примерно так:

# ssh -L 192.168.99.2:3128:localhost:8118 [email protected]

или так:

# ssh -D 192.168.99.2:3128 [email protected]

где 1.2.3.4 и 4.3.2.1 - IP VDS, а 192.168.99.2 - IP адрес внутри WSL. В браузере в качестве прокси указываю 192.168.99.2, порт 3128. В зависимости от подключенной VPS, работает та или иная локация для доступа в интернет.

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

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

#ssh #proxy
👍102👎5
​​Для нагрузочного тестирования сайтов существует популярное и удобное решение от Grafana - k6. Я уже когда-то давно рассказывал про него, но тогда не сделал акцент на том, что он удобен в том числе благодаря интеграции с Grafana через хранение метрик в Influxdb. Покажу, как это выглядит на практике.

K6 много чего умеет. Он вообще очень развитый и продвинутый инструмент, где тесты можно писать в том числе на JavaScript. Продукт позиционирует себя как Tests as code. Его легко поднять и начать тестирование, используя готовые примеры. Показываю на практике.

Поднимаем связку Grafana + Influxdb:

# git clone https://github.com/grafana/k6 && cd k6

Там готовый docker-compose.yml. В принципе, можно ничего не менять, конфиг простой, без необходимости указания переменных. Запускаем связку:

# docker compose up -d influxdb grafana

Можно сходить, проверить графану по стандартному урлу и порту: https://server-ip:3000/login. Учётка стандартная - admin / admin. В графане уже должен быть настроен в Data sources myinfluxdb с урлом из соседнего контейнера.

Теперь нужно выбрать Dashboard. Их очень много разных для k6, выбирайте любой. Наиболее функциональный и удобный вот этот, за счёт того, что там есть группировка по тэгам, группам, урлам. Идём в Dashboards ⇨  Import ⇨  ID 13719.

Всё готово для запуска тестов. В репозитории, в директории examples очень много примеров. Эта директория мапится в контейнер с k6 в docker-compose. Тест можно запустить вот так:

# docker compose run k6 run /scripts/stages.js

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

# k6 run --out influxdb=https://1.2.3.4:8086 stages.js

Вот пример простого конфига для теста в 10 потоков в течении 30 секунд:

import http from 'k6/http';
import { sleep } from 'k6';
export let options = {
 vus: 10,
 duration: '30s',
};
export default function () {
 http.get('https://test.k6.io');
 sleep(1);
}

Соответственно, конфиг легко расширяется дополнительными урлами, тестами, выполняемыми действиями. У продукта хорошая документация и много готовых примеров. Знать JavaScript не обязательно.

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

#нагрузочное_тестирование
👍74👎3
Давно ничего не писал на отстранённые темы. Но сегодня хочу немного поделиться своими мыслями. К тому же повод соответствующий появился. Про День Победы сказать особо нечего. Поздравлять кого-то, кроме ветеранов, тех, кто вывез эту войну и принёс победу на своих плечах, не имеет смысла. Нам остаётся только чтить их память.

Я хочу напомнить, что основа всех войн - ненависть, вражда, раздор. Убери их, и войны не будет. Это фундамент. Сейчас наглядно видно, как работает технология по разжиганию вражды. Не по книгам, каким-то историям и воспоминаниям, а в реальном времени можно наблюдать, как применяют технологию. Изучать и исследовать её.

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

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

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

В завершение своих слов хочу привести стихотворение про доброту, человечность и единство народов одного из своих любимых современных исполнителей и поэтов Игоря Растеряева - Дед Агван. Стих написан на основе реальной истории реального ветерана ВОВ:

▶️ Игорь Растеряев. Дед Агван.(стих)
⇨ Описание реальной истории и человека из стихотворения
📜 Текст

.......
Его уж нет, а я большой.
И вдруг я докумекал:
В тот день был самый главный бой
За звание человека.

#разное #мысли
👍333👎87