⚠️ Эта команда Docker даёт хакеру права root на хосте
Привет, цифровой архитектор!
Флаг
Используйте принцип минимальных привилегий (least privilege), отключая ненужные возможности ядра (capabilities).
1. Почему
Запуск контейнера в привилегированном режиме позволяет ему смонтировать корневую файловую систему хоста или получить уровень контроля, аналогичный процессам хоста.
2. Принцип минимальных привилегий (Least Privilege)
Если контейнеру не нужны все возможности
3. Запуск от имени непривилегированного пользователя
Если приложение не требует привилегий
💡 Вывод:
Флаг
#DevOps #Docker #Безопасность #root #CLI #Privileges
Привет, цифровой архитектор!
Флаг
--privileged в Docker — это прямая угроза безопасности. Он даёт контейнеру доступ ко всем устройствам хоста и может обеспечить злоумышленнику права root.Используйте принцип минимальных привилегий (least privilege), отключая ненужные возможности ядра (capabilities).
1. Почему
--privileged — это опасно?Запуск контейнера в привилегированном режиме позволяет ему смонтировать корневую файловую систему хоста или получить уровень контроля, аналогичный процессам хоста.
# Опасная команда: получает полный доступ к хост-системе
docker run --rm -v /:/host -t -i debian bash
root@e51ae86c5f7b:/# cd /host
root@e51ae86c5f7b:/host# ls bin dev home
# Атакующий видит корневую ФС хоста, включая /bin, /dev, /etc, /root.
2. Принцип минимальных привилегий (Least Privilege)
Если контейнеру не нужны все возможности
root (которые являются комбинацией 40 отдельных CAP_ возможностей Linux), их следует отключить. Docker по умолчанию и так удаляет многие возможности.# Сброс всех возможностей и добавление только необходимых
# CAP_NET_BIND_SERVICE нужна для привязки к портам ниже 1024
docker run --cap-drop all --cap-add NET_BIND_SERVICE alpine:latest sh
# Пример удаления опасных возможностей SUID/SGID
docker run -it --rm --cap-drop SETUID --cap-drop SETGID ...
# Дополнительное ограничение: запрет на получение новых привилегий
docker run --security-opt=no-new-privileges ubuntu bash
3. Запуск от имени непривилегированного пользователя
Если приложение не требует привилегий
root, оно не должно от него запускаться. Это предотвращает повышение привилегий (privilege escalation) в случае взлома.# В Dockerfile: переключаем пользователя
RUN groupadd -r app_grp && useradd -r -g app_grp app
USER app
💡 Вывод:
Флаг
--privileged следует избегать. Используй --cap-drop и USER в Dockerfile, чтобы контейнер не получил прав root на хосте, даже если его взломают.#DevOps #Docker #Безопасность #root #CLI #Privileges
👍8
🔑 Hardening: 4 ключевых правила iptables для любого сервера
Привет, хакер безопасности!
У тебя открыт лишний порт? Базовый принцип — запрещать всё. Сначала установи политику
Вывод: Эти четыре команды — основа для любого безопасного сервера.
#Безопасность #iptables #CLI #Hardening
Привет, хакер безопасности!
У тебя открыт лишний порт? Базовый принцип — запрещать всё. Сначала установи политику
DROP, затем разреши необходимое.# 1. Запрещаем весь входящий трафик по умолчанию
iptables -P INPUT DROP
# 2. Разрешаем внутренний трафик (loopback)
iptables -A INPUT -i lo -j ACCEPT
# 3. Разрешаем ответы на наши запросы (stateful firewall)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 4. Открываем SSH для управления (TCP порт 22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Теперь сохраняем правила, чтобы они пережили перезагрузку
service iptables save
Вывод: Эти четыре команды — основа для любого безопасного сервера.
#Безопасность #iptables #CLI #Hardening
👍6👎3
📘 Энциклопедия Docker: 10 лучших практик для production
Привет, цифровой архитектор!
У тебя нет времени искать тонкости настройки Docker?
Собрал для тебя 10 ключевых команд и приёмов из архитектурных гайдов, которые обязательно нужно сохранить для работы в production.
1. Безопасность: Непривилегированный пользователь
Никогда не запускай контейнеры от имени
2. Ограничение возможностей ядра (Capabilities)
Docker по умолчанию включает много возможностей, но лучше их отключить и добавить только необходимые.
3. Оптимизация Dockerfile: Слияние RUN
Каждая инструкция
4. Управление томами (Volumes)
Для сохранения постоянных данных используй тома (
5. Очистка системы
Для избежания беспорядочного роста образов и контейнеров (
6. Режимы работы с сетью
Docker по умолчанию использует режим
7. Работа с образами и тегами
Для контроля версий всегда используй конкретные теги, а не
8. Использование
Не запускай SSH-демон внутри контейнера. Для отладки используй
9. Настройка ресурсов (cgroups)
Ограничивай ресурсы (CPU, Memory), чтобы избежать DoS-атак или утечек памяти.
10. Постоянный контроль состояния
Для избежания проблем, связанных с перезапуском и изменяемостью.
#Docker #DevOps #Security #CLI #Hardening
Привет, цифровой архитектор!
У тебя нет времени искать тонкости настройки Docker?
Собрал для тебя 10 ключевых команд и приёмов из архитектурных гайдов, которые обязательно нужно сохранить для работы в production.
1. Безопасность: Непривилегированный пользователь
Никогда не запускай контейнеры от имени
root. Атакующий может получить права root на хосте.# В Dockerfile создаем группу и непривилегированного пользователя 'app'
RUN groupadd -r app_grp && useradd -r -g app_grp app
USER app # Всегда переключаемся на непривилегированного пользователя
2. Ограничение возможностей ядра (Capabilities)
Docker по умолчанию включает много возможностей, но лучше их отключить и добавить только необходимые.
# Сбрасываем все Capabilities (CAP_DROP ALL)
docker run -ti --cap-drop ALL debian /bin/bash
# Добавляем только возможность привязки к низким портам (<1024)
docker run --cap-drop all --cap-add CAP_NET_BIND_SERVICE alpine:latest sh
# Запрет на повышение привилегий (hardening)
docker run --security-opt=no-new-privileges ubuntu bash
3. Оптимизация Dockerfile: Слияние RUN
Каждая инструкция
RUN создает новый уровень (layer), увеличивая размер образа. Объединяйте команды с && для минимизации слоев.# Плохо: 3 отдельных слоя
RUN apk update
RUN apk add nodejs nodejs-npm
RUN mkdir -p /app/public
# Хорошо: одна инструкция, один слой
RUN apk update && \
apk add nodejs nodejs-npm && \
mkdir -p /app/public /app/server
4. Управление томами (Volumes)
Для сохранения постоянных данных используй тома (
VOLUME).# Создание тома на хосте (local driver по умолчанию)
docker volume create my_data_vol
# Просмотр информации о томе (включая путь на хосте)
docker volume inspect my_data_vol
# Удаление всех неиспользуемых томов (используй с осторожностью!)
docker volume prune
5. Очистка системы
Для избежания беспорядочного роста образов и контейнеров (
image sprawl).# Удаление остановленных контейнеров
docker rm $(docker ps -aq -f status=exited)
# Удаление неиспользуемых (висячих) образов
docker rmi $(docker images -q -f dangling=true)
# Полная очистка: контейнеры, образы, сети, тома
docker system prune -a
6. Режимы работы с сетью
Docker по умолчанию использует режим
bridge (мост), который изолирует контейнеры в частной сети.# Просмотр активных сетевых режимов (по умолчанию: bridge, none, host)
docker network ls
# Запуск контейнера в режиме хоста (убирает изоляцию, но дает скорость)
docker run --net=host -d my_app
# Создание изолированной сети, чтобы контейнеры видели друг друга по имени
docker network create my_custom_net
docker run --network my_custom_net --name redis_db redis
7. Работа с образами и тегами
Для контроля версий всегда используй конкретные теги, а не
latest.# Получение образа с конкретным тегом
docker pull debian:jessie
# Построение образа с явным указанием тега
docker build -t my_app:v1.2 .
# Использование дайджеста для абсолютной гарантии версии
FROM redis@sha256:3479bbcab384fa343b52743b933661335448f8166203688006...
8. Использование
docker exec вместо SSH-демоновНе запускай SSH-демон внутри контейнера. Для отладки используй
docker exec.# Запуск bash внутри активного контейнера (интерактивно)
docker exec -it <CONTAINER_ID> /bin/bash
# Запуск команды внутри контейнера без входа в оболочку
docker exec -it my_web_container ls -l /var/log
9. Настройка ресурсов (cgroups)
Ограничивай ресурсы (CPU, Memory), чтобы избежать DoS-атак или утечек памяти.
# Ограничение памяти (128 Мб)
docker run -it --rm -m 128m my_app
# Ограничение использования CPU (только ядра 0 и 1)
docker run -it --rm --cpuset=0,1 -c 2 my_app
10. Постоянный контроль состояния
Для избежания проблем, связанных с перезапуском и изменяемостью.
# Просмотр запущенных контейнеров
docker ps
# Просмотр всех контейнеров (включая остановленные)
docker ps -a
# Просмотр подробной конфигурации контейнера (JSON)
docker inspect <CONTAINER_ID>
# Получение журналов (STDOUT/STDERR)
docker logs <CONTAINER_ID>
#Docker #DevOps #Security #CLI #Hardening
👍12🔥1
🔥 Собери свой
Привет, системный траблшутер!
Если у тебя что-то "легло" или тормозит, нужно моментально получить срез состояния системы. Ты не хочешь запускать 10 разных команд.
Объедини ключевые команды (
🐧 Скрипт
Вывод: Ты можешь использовать эту заготовку как основу, чтобы быстро диагностировать проблемы с CPU, памятью или диском, а затем добавить
#Мониторинг #Bash #CLI #Скрипт #uptime #free
top: скрипт для моментальной диагностики LinuxПривет, системный траблшутер!
Если у тебя что-то "легло" или тормозит, нужно моментально получить срез состояния системы. Ты не хочешь запускать 10 разных команд.
Объедини ключевые команды (
uptime, free, ps) в одну функцию, которая быстро покажет тебе, где узкое место.🐧 Скрипт
check_status.sh#!/bin/bash
# Используем hostname для получения имени сервера
SERVER_NAME=$(hostname)
# Создание функции, чтобы избежать повторов кода
function get_quick_status() {
echo "--- СТАТУС СЕРВЕРА: ${SERVER_NAME} ---"
# 1. Аптайм и Load Average
echo "Load Average (1, 5, 15 мин) и Uptime:"
uptime
# Load Average > 1.0 часто указывает на проблемы
# 2. Использование памяти (в удобном формате)
echo "Использование RAM и SWAP (free -h):"
free -h
# free -h выводит информацию о памяти и swap
# 3. Использование корневого раздела
echo "Использование диска (df -h /):"
df -h / | tail -n 1 | awk '{print "Used: " $3 ", Avail: " $4 }'
# df показывает использование файловой системы
# 4. Топ-5 активных процессов по CPU
echo "Топ-5 активных процессов (PID, %CPU, COMMAND):"
ps -e --no-header -o pid,%cpu,comm | sort -nr -k 2 | head -5
# ps -e отображает информацию о текущих запущенных процессах
}
# Запускаем функцию
get_quick_status
Вывод: Ты можешь использовать эту заготовку как основу, чтобы быстро диагностировать проблемы с CPU, памятью или диском, а затем добавить
vmstat или iostat для глубокого анализа, если это требуется.#Мониторинг #Bash #CLI #Скрипт #uptime #free
👍19
💾 Bash-антигайд: Удаляй tmp-файлы даже после kill -9
Хей, защитник хоста!
Если твой скрипт аварийно завершается, временные файлы (
Чтобы гарантировать удаление, используй ловушку EXIT.
Вывод:
#Bash #Автоматизация #Скрипты #trap #CLI
Хей, защитник хоста!
Если твой скрипт аварийно завершается, временные файлы (
/tmp) остаются.Чтобы гарантировать удаление, используй ловушку EXIT.
#!/bin/bash
# Создай уникальное имя для временного файла
TMP_FILE=$(mktemp)
# 1. Ловушка EXIT (сигнал 0) сработает при ЛЮБОМ выходе
trap "rm -f $TMP_FILE" EXIT
# 2. Здесь идет твой основной код
echo "Лог пишется в $TMP_FILE" >> $TMP_FILE
# 3. Дополнительно можно перехватить SIGINT (2) и SIGTERM (15)
trap "rm -f $TMP_FILE; exit 1" INT TERM
Вывод:
trap...EXIT обеспечивает, что функция очистки выполнится всегда, даже при ошибке.#Bash #Автоматизация #Скрипты #trap #CLI
🔥4
🔐 Секреты Pro-Docker: 4 хака, которые сделают твои образы в 5 раз меньше
Привет, контейнерный гуру!
Твои Docker-образы слишком большие и могут нести угрозу безопасности?.
Я собрал 4 критически важных приёма для hardening-а и оптимизации, которые должен знать каждый, кто работает с Docker в продакшене.
1. ⚙️ Оптимизация слоёв: Уменьши размер в 71%
Каждая инструкция
За счет перехода на минимальные базовые образы (например, Alpine) и объединения команд ты можешь уменьшить размер образа на 71%.
2. 🛡 Безопасность: Запуск без root и
Никогда не запускай контейнер с флагом
Ограничение возможностей (Capabilities) — ключевой принцип безопасности, так как
3. 💾 Очистка: Удали висячий мусор
Если ты не удаляешь остановленные контейнеры или висячие образы (dangling images), они будут накапливаться и занимать дисковое пространство.
Используй
4. 🧠 Ограничение ресурсов: Защита от DoS-атак
Ограничивай использование ресурсов с помощью cgroups, чтобы взломанный контейнер не смог вызвать отказ в обслуживании (DoS), исчерпав память или CPU хоста.
Вывод: Применение этих практик (минимальные образы, непривилегированные пользователи и ограничения ресурсов) — это не просто оптимизация, это создание надёжной архитектуры, которую ты можешь смело развертывать в production.
#Docker #DevOps #Security #Hardening #Optimization #CLI #Сборник
Привет, контейнерный гуру!
Твои Docker-образы слишком большие и могут нести угрозу безопасности?.
Я собрал 4 критически важных приёма для hardening-а и оптимизации, которые должен знать каждый, кто работает с Docker в продакшене.
1. ⚙️ Оптимизация слоёв: Уменьши размер в 71%
Каждая инструкция
RUN в Dockerfile создает новый уровень (слой), что раздувает конечный размер образа. Чтобы избежать этого, используй оператор && для объединения команд в одну инструкцию RUN.# ПЛОХО: Создаст 3 слоя
RUN apt-get update
RUN apt-get install -y nodejs
RUN rm -rf /var/lib/apt/lists/*
# ХОРОШО: Создаст 1 слой и уменьшит размер образа
FROM alpine:3.12.0
RUN apk update && \
apk add --no-cache nodejs npm && \
rm -rf /var/cache/apk/*
# Используй --no-cache, чтобы не хранить временные файлы
За счет перехода на минимальные базовые образы (например, Alpine) и объединения команд ты можешь уменьшить размер образа на 71%.
2. 🛡 Безопасность: Запуск без root и
CAP_DROPНикогда не запускай контейнер с флагом
--privileged, так как это равносильно получению прав root на хосте, позволяя, например, смонтировать его корневую ФС. Всегда переключайся на непривилегированного пользователя внутри контейнера.# Создаем непривилегированного пользователя 'app'
# Используй инструкцию USER, чтобы избежать root
RUN groupadd -r app_grp && useradd -r -g app_grp app
USER app
# Если нужны только специфические права (например, bind к порту < 1024):
# Сбрось ВСЕ права (--cap-drop all) и добавь только необходимые
docker run --cap-drop ALL --cap-add CAP_NET_BIND_SERVICE alpine sh
Ограничение возможностей (Capabilities) — ключевой принцип безопасности, так как
root в Linux — это коллекция возможностей, и Docker позволяет тебе их выборочно отключить.3. 💾 Очистка: Удали висячий мусор
Если ты не удаляешь остановленные контейнеры или висячие образы (dangling images), они будут накапливаться и занимать дисковое пространство.
# Удаление всех остановленных контейнеров
# docker rm $(docker ps -aq -f status=exited)
docker rm $(docker ps -aq) -f
# Удаление всех висячих (без тегов) образов
docker rmi $(docker images -q -f dangling=true)
# Очистка всего Docker-мусора (образов, сетей, контейнеров)
# Используй с осторожностью, это удалит ВСЁ, что не используется
docker system prune -a
Используй
docker system prune -a для быстрой очистки, но помни, что тома (volumes) не удаляются автоматически и требуют отдельной очистки, если они не используются.4. 🧠 Ограничение ресурсов: Защита от DoS-атак
Ограничивай использование ресурсов с помощью cgroups, чтобы взломанный контейнер не смог вызвать отказ в обслуживании (DoS), исчерпав память или CPU хоста.
# Ограничение памяти (128 МБ)
# -m 128m задает жесткий лимит, предотвращая OOM на хосте
docker run -it --rm -m 128m my_app
# Ограничение использования CPU (на 2 CPU или 50% CPU-времени)
docker run -it --rm --cpus="2" my_app
# или, используя доли CFS:
docker run -d --name load_high -c 512 amouat/stress
Вывод: Применение этих практик (минимальные образы, непривилегированные пользователи и ограничения ресурсов) — это не просто оптимизация, это создание надёжной архитектуры, которую ты можешь смело развертывать в production.
#Docker #DevOps #Security #Hardening #Optimization #CLI #Сборник
👍1
✅
Привет, инженер автоматизации!
Если ты переходишь с
Команда
1. 🔍 Полный статус сервиса
Эта команда показывает, активен ли сервис, его PID, потребление ресурсов (CGroup, Memory, CPU) и последние строки логов.
2. 🚀 Включение и активация (autostart)
3. 💾 Применение новой конфигурации без перезапуска
Если ты изменил конфигурационный файл (например,
4. 📈 Анализ скорости загрузки (Boot Performance)
Если система загружается медленно, эта команда покажет тебе, какие юниты (сервисы) потребляют больше всего времени.
5. 📜 Просмотр всех файлов юнитов
Для DevOps критически важно знать, какие сервисы вообще установлены в системе и в каком они состоянии (включен/выключен).
💡 Вывод
Команда
#DevOps #systemd #systemctl #CLI #Автоматизация
systemctl – 5 команд, которые должен знать каждый DevOps-инженерПривет, инженер автоматизации!
Если ты переходишь с
SysVinit на systemd, тебе нужен надёжный командник для быстрого траблшутинга и управления сервисами.Команда
systemctl — это твой универсальный диспетчер. Вот 5 ключевых функций, которые ты будешь использовать каждый день.1. 🔍 Полный статус сервиса
Эта команда показывает, активен ли сервис, его PID, потребление ресурсов (CGroup, Memory, CPU) и последние строки логов.
# Получить детальную информацию о веб-сервере Nginx
systemctl status nginx.service
# PID, CGroup, Memory, CPU - важные данные для траблшутинга
2. 🚀 Включение и активация (autostart)
systemctl enable создаёт символическую ссылку, чтобы сервис запускался при загрузке системы. Флаг --now сразу запускает его.# Включить автозапуск SSHD при загрузке и немедленно запустить
sudo systemctl enable --now sshd.service
# Проверить, включен ли сервис для автозапуска
systemctl is-enabled sshd.service
3. 💾 Применение новой конфигурации без перезапуска
Если ты изменил конфигурационный файл (например,
/etc/ssh/sshd_config), тебе нужно, чтобы демон перечитал его, не прерывая работу.# Перезагрузка конфигурации systemd, чтобы обнаружить изменения в юнит-файлах
sudo systemctl daemon-reload
# Перезагрузить конфигурацию самого сервиса (без полного restart)
sudo systemctl reload sshd.service
4. 📈 Анализ скорости загрузки (Boot Performance)
Если система загружается медленно, эта команда покажет тебе, какие юниты (сервисы) потребляют больше всего времени.
# Вывести список процессов, отсортированных по времени запуска
systemd-analyze blame
# Посмотреть общее время, потраченное на загрузку ядра и userspace
systemd-analyze time
5. 📜 Просмотр всех файлов юнитов
Для DevOps критически важно знать, какие сервисы вообще установлены в системе и в каком они состоянии (включен/выключен).
# Вывести список всех установленных файлов модулей типа service и их состояние (enabled/disabled/static/masked)
systemctl list-unit-files --type=service
💡 Вывод
Команда
systemctl — это центральный инструмент для твоей работы в Linux. Используя status для детальной проверки, reload для безопасных обновлений и systemd-analyze blame для диагностики, ты можешь эффективно управлять production-средой.#DevOps #systemd #systemctl #CLI #Автоматизация
👍17
🔥 Load Average: Когда «цифра» значит «Срочно чини!»
Привет, системный траблшутер!
Как понять, когда Load Average (LA) реально опасен?.
Критическая нагрузка — это число ядер твоего ЦПУ. Если LA > NCPU, то пора чинить!
Вывод: Если LA стабильно выше числа ядер, система насыщена.
#Мониторинг #CLI #LoadAverage #Кейс
Привет, системный траблшутер!
Как понять, когда Load Average (LA) реально опасен?.
Критическая нагрузка — это число ядер твоего ЦПУ. Если LA > NCPU, то пора чинить!
# 1. Узнай свой лимит: Количество логических процессоров (ядер)
# Информация берется из системного псевдофайла
NCPU=$(grep -c '^processor' /proc/cpuinfo)
echo "Твой лимит (NCPU): $NCPU"
# 2. Проверь текущую среднюю загрузку (за 1, 5, 15 минут)
uptime
# Load Average включает процессы, ожидающие ЦПУ ИЛИ Disk I/O
# 3. Пример сравнения: если LA за 1 мин выше лимита NCPU
CURRENT_LOAD=$(cat /proc/loadavg | cut -d ' ' -f1)
if (( $(echo "$CURRENT_LOAD > $NCPU" | bc -l) )); then
echo "🚨 СЕРВЕР ПЕРЕГРУЖЕН: $CURRENT_LOAD > $NCPU"
fi
Вывод: Если LA стабильно выше числа ядер, система насыщена.
#Мониторинг #CLI #LoadAverage #Кейс
👍10
🔧 Multipass: Запусти Ubuntu VM 3 командами (CLI-гайд)
Привет, мастер командной строки!
Тебе нужна быстрая песочница Ubuntu для тестов?
Multipass позволяет тебе запустить VM с предустановленным Docker за минуту.
1. Запуск виртуалки с Docker
Используй образ
2. Проверка и подключение
Убедись, что она запущена, и подключись.
Вывод: Используя всего три команды (
#Утилиты #CLI #Виртуализация #Multipass
Привет, мастер командной строки!
Тебе нужна быстрая песочница Ubuntu для тестов?
Multipass позволяет тебе запустить VM с предустановленным Docker за минуту.
1. Запуск виртуалки с Docker
Используй образ
docker и задай имя (например, node1).# Создаем и запускаем VM с Docker pre-installed
multipass launch docker --name node1
2. Проверка и подключение
Убедись, что она запущена, и подключись.
# Проверить статус, имя и IP-адрес VM
multipass ls
# Подключиться к виртуальной машине (ты войдёшь в неё)
multipass shell node1
# Выход из сеанса оболочки (без выключения машины)
exit
Вывод: Используя всего три команды (
launch, ls, shell), ты можешь получить готовую среду для работы.#Утилиты #CLI #Виртуализация #Multipass
🤯 CLI-гайд: 6 команд, которые делают "грязную" работу за тебя
Привет, гуру Linux-оболочки!
Ты тратишь время на рутину: многострочный поиск, управление ресурсами и сбор метаданных.
Эти утилиты позволяют тебе быстро решать сложные задачи, избегая написания длинных скриптов.
1. ⚙️
2. 🚀
Используй
3. 💾
Всегда создавай временные файлы с помощью
Когда
4. 🔗
Если ты не можешь размонтировать файловую систему (
5. 🔑
Эти три команды помогают тебе быстро найти исполняемый файл или узнать его назначение, что критически важно при работе в новой системе:
6. 📊 Комбинирование:
Используй эти три фильтра вместе для анализа структурированных текстовых файлов или вывода команд (например,
💡 Вывод
Эти хаки и утилиты — настоящий золотой фонд командной строки. Используя
#Шпаргалка #Хаки #CLI #Bash #Скрипт #Утилиты
Привет, гуру Linux-оболочки!
Ты тратишь время на рутину: многострочный поиск, управление ресурсами и сбор метаданных.
Эти утилиты позволяют тебе быстро решать сложные задачи, избегая написания длинных скриптов.
1. ⚙️
stat: Вся информация о файлеstat выдает подробную и многословную статистику о заданном файле, каталоге или устройстве. Сюда входит тип файла, права доступа, inode, размер и время.# Получить детальные метаданные о файле
stat /etc/passwd
# Извлечь конкретные данные (например, inode и тип файла)
# -c%i - inode number, -c%F - file type
stat -c%i,%F /etc/passwd
stat используется, чтобы быстро получить всю информацию, включая время последнего доступа (atime), модификации (mtime) или изменения статуса (ctime).2. 🚀
xargs: Параллельное выполнение командИспользуй
xargs для передачи аргументов команде из потока ввода (stdin), что особенно полезно, когда список аргументов слишком длинный для обычной подстановки.# Найти все файлы *.log и удалить их, даже если их миллион
find /var/log/ -name "*.log" -print0 | xargs -0 rm -f
# Найти все .mp3-файлы и вывести их размер (с использованием xargs)
find ~/ -name "*.mp3" -print0 | xargs -0 du -h
xargs разбивает поток данных на достаточно маленькие блоки для обработки, что позволяет тебе ускорить операции с большим количеством файлов.3. 💾
mktemp: Создание безопасного временного файлаВсегда создавай временные файлы с помощью
mktemp для обеспечения "уникального" имени файла. Это предотвращает атаки, связанные с гонкой (race condition).# Создать временный файл в /tmp с уникальным именем
TMP_FILE=$(mktemp)
echo "Рабочие данные" > $TMP_FILE
# После использования, не забудь удалить
rm $TMP_FILE
Когда
mktemp вызывается без аргументов, он создает файл нулевой длины в /tmp.4. 🔗
lsof: Найди, что держит ресурсЕсли ты не можешь размонтировать файловую систему (
umount fails), lsof показывает все открытые файлы и связанные с ними процессы.# Узнать, какие процессы используют директорию /mnt/data
lsof /mnt/data
# Показать, какие процессы открыли файл /usr/bin/vim
fuser -u /usr/bin/vim
lsof помогает тебе определить, какие файлы все еще открыты, чтобы ты мог безопасно убить соответствующие процессы.5. 🔑
which, whereis, whatis: Быстрый поиск документацииЭти три команды помогают тебе быстро найти исполняемый файл или узнать его назначение, что критически важно при работе в новой системе:
# Показать полный путь к исполняемому файлу (только bin)
which rm
# Вывод: /usr/bin/rm
# Показать путь к bin, исходникам И man-странице
whereis rm
# Вывод: rm: /bin/rm /usr/share/man/man1/rm.1.bz2
# Получить краткое описание команды из базы данных whatis
whatis whatis
# Вывод: whatis (1) - search the whatis database for complete words
6. 📊 Комбинирование:
cut, sort, uniqИспользуй эти три фильтра вместе для анализа структурированных текстовых файлов или вывода команд (например,
/etc/passwd).# Найти 5 самых популярных оболочек в системе
cut -d':' -f7 /etc/passwd | sort | uniq -c | sort -rn | head -5
# cut -d':' -f7: извлекает поле 7 (оболочку).
# sort: сортирует, чтобы uniq работал.
# uniq -c: подсчитывает последовательные дубликаты.
# sort -rn: сортирует в обратном порядке по числам (самые популярные сверху).
💡 Вывод
Эти хаки и утилиты — настоящий золотой фонд командной строки. Используя
xargs, stat и связку фильтров (cut, sort, uniq), ты сможешь превратить рутинные задачи в быстрые однострочники.#Шпаргалка #Хаки #CLI #Bash #Скрипт #Утилиты
🔥9👍3👎1
🔑 Секрет
Эй, Bash-архитектор!
Тебе нужна гибкая аутентификация (IP ИЛИ пароль)?
Директива
Вывод: Если IP совпадает, сервер не спросит пароль.
#Nginx #Хаки #Security #CLI #МиниГайд
Satisfy: IP-доступ без пароля для админовЭй, Bash-архитектор!
Тебе нужна гибкая аутентификация (IP ИЛИ пароль)?
Директива
Satisfy any позволяет тебе обходить Basic Auth для внутренних IP, не требуя пароля.# Конфигурация Nginx/Angie (Location Block)
# Внимание: Basic Auth небезопасна без HTTPS
location /admin/ {
# 1. Настройка аутентификации
auth_basic "Restricted Zone";
auth_basic_user_file /etc/nginx/.htpasswd;
# 2. Правила доступа по IP
allow 192.168.1.10; # Разрешить админу
deny all;
# 3. Ключевой хак: достаточно одного условия
satisfy any;
}
Вывод: Если IP совпадает, сервер не спросит пароль.
#Nginx #Хаки #Security #CLI #МиниГайд
👍4
🔥 3 метрики в SSH-баннере: Скрипт для Production
Привет, повелитель терминала!
Тратить время на ввод
Добавь этот динамический скрипт в свой
⚙️ Скрипт: Динамический MOTD (Message of the Day)
Скрипт использует подстановку команд
Вывод:
Вставь этот код в конец своего файла
#Bash #Скрипты #SSH #CLI #Мониторинг
Привет, повелитель терминала!
Тратить время на ввод
uptime и free при каждом SSH-входе, чтобы оценить состояние сервера.Добавь этот динамический скрипт в свой
~/.bashrc (или /etc/profile), и ты получишь мгновенную оценку Load Average, RAM и IP-адреса, используя встроенный документ (here document).⚙️ Скрипт: Динамический MOTD (Message of the Day)
Скрипт использует подстановку команд
$(...) (предпочтительная нотация вместо обратных кавычек ` ``) для сбора метрик и форматированный встроенный документ для их вывода.#!/bin/bash
# -------------------------------------------------------------
# 1. Сбор системных метрик
# -------------------------------------------------------------
# Получаем локальный IP-адрес сервера (первый в списке)
SERVER_IP=$(hostname -I | awk '{print $1}')
# Получаем Load Average за 1 минуту.
# Средняя загрузка (Load Average) — это количество процессов,
# ожидающих ЦПУ или дискового ввода/вывода.
# Мы считываем метрики из псевдофайла /proc/loadavg,
# извлекая первое поле (1-минутное значение).
LOAD_AVG=$(cut -d " " -f1 /proc/loadavg)
# Получаем использованную/общую RAM в "человекочитаемом" виде.
# Используем команду `free` для статистики виртуальной памяти.
# AWK используется для извлечения 3-го и 2-го столбцов строки "Mem:"
RAM_USED_TOTAL=$(free -h | awk '/Mem:/ {print $3 "/" $2}')
# -------------------------------------------------------------
# 2. Вывод баннера с помощью Встроенного Документа (Here Document)
# -------------------------------------------------------------
# Конструкция 'cat << EOF' создает встроенный документ.
# Встроенные документы поддерживают подстановку параметров, если
# ограничитель (EOF) не экранирован.
cat << EOF
=============================================
🛡️ SYSTEM HEALTH CHECK | USER: $(whoami)
=============================================
🚀 Локальный IP: $SERVER_IP
⏱️ Load Average 1m: $LOAD_AVG
💾 RAM (Used/Total): $RAM_USED_TOTAL
---------------------------------------------
EOF
Вывод:
Вставь этот код в конец своего файла
~/.bashrc. Таким образом, ты увидишь здоровье сервера сразу после подключения, не используя команды вроде top или vmstat. Помни, что stat также может давать подробную информацию о файле или каталоге, включая размер, права доступа, и временные метки (доступ, модификация, изменение статуса).#Bash #Скрипты #SSH #CLI #Мониторинг
🔥9👍5
💡
Хей, гуру Linux-оболочки!
Ты тратишь время на медленный Web-GUI для рутинных задач (например, перезапуск служб)?
Используй команду
Вывод:
#TUI #CLI #Bash #Утилиты
select + dialog: Создаём админ-меню прямо в консолиХей, гуру Linux-оболочки!
Ты тратишь время на медленный Web-GUI для рутинных задач (например, перезапуск служб)?
Используй команду
select для создания интерактивного TUI-меню.# 1. Задаем приглашение к вводу (PS3)
PS3='Выберите действие: '
# 2. Создаем TUI-меню с помощью select
select ACTION in 'Restart Proxy' 'Check Load' 'Exit'
do
# Выполняем команду, соответствующую выбору
case $ACTION in
'Restart Proxy')
# Перезапускаем службу proxy
systemctl restart proxy.service ;;
'Check Load')
# Проверяем загрузку системы (Load Average)
uptime ;;
'Exit')
# Выход из цикла
break ;;
esac
done
Вывод:
select позволяет тебе быстро выбрать и выполнить команду прямо в консоли.#TUI #CLI #Bash #Утилиты
🔥 Компактный IP: Смотрим сеть без боли в глазах
EHLO, коллега! 👋
Признайся, сколько раз ты вводил ip addr и тонул в потоке информации о MTU, qdisc и broadcast-адресах, пытаясь найти заветные цифры IP? 😵 Или по старой привычке ставил net-tools, чтобы вернуть любимый, но устаревший ifconfig,?
В современном пакете iproute2 есть скрытая жемчужина — флаг -br (brief), который превращает вывод в аккуратную таблицу. Больше не нужно писать длинные пайплайны с grep и awk.
📌 Команда для читаемого вывода:
Что она делает:
-br (brief) — включает режим краткого вывода.
a (addr) — показывает адреса.
Результат будет выглядеть примерно так:
💡 Почему это круто:
1. Ты сразу видишь статус (
2. Это работает «из коробки» в большинстве современных дистрибутивов (CentOS 8+, Ubuntu 18.04+ и др.).
3. Идеально для твоих скриптов и беглого просмотра состояния сети.
#Linux #Networking #CLI #SysAdmin #DevOps
EHLO, коллега! 👋
Признайся, сколько раз ты вводил ip addr и тонул в потоке информации о MTU, qdisc и broadcast-адресах, пытаясь найти заветные цифры IP? 😵 Или по старой привычке ставил net-tools, чтобы вернуть любимый, но устаревший ifconfig,?
В современном пакете iproute2 есть скрытая жемчужина — флаг -br (brief), который превращает вывод в аккуратную таблицу. Больше не нужно писать длинные пайплайны с grep и awk.
📌 Команда для читаемого вывода:
ip -br a
Что она делает:
-br (brief) — включает режим краткого вывода.
a (addr) — показывает адреса.
Результат будет выглядеть примерно так:
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.1.10/24 fe80::a00:27ff:fe0d:d90c/64
💡 Почему это круто:
1. Ты сразу видишь статус (
UP/DOWN), имя интерфейса и IP.2. Это работает «из коробки» в большинстве современных дистрибутивов (CentOS 8+, Ubuntu 18.04+ и др.).
3. Идеально для твоих скриптов и беглого просмотра состояния сети.
#Linux #Networking #CLI #SysAdmin #DevOps
👍25
🛡 Твой новый стандарт: Генерируем SSH Ed25519
С возвращением! 👋
Всё еще генерируешь ключи через rsa -b 4096? Это надежно, но ключи получаются длинными, а генерация — медленной. В современном мире стандартом де-факто становится Ed25519. Это алгоритм на эллиптических кривых: он безопаснее, быстрее и создает очень компактные ключи, которые удобно копировать.
Давай обновим твои доступы за одну минуту.
📌 Команда для генерации:
Разбор флагов:
-t ed25519 — указываем тип ключа. Он обеспечивает превосходную безопасность и высокую производительность.
-C "комментарий" — метка (обычно email), чтобы ты не запутался в authorized_keys, когда ключей станет много.
💡 Что делать дальше?
1. Закинь ключ на сервер:
Используй утилиту ssh-copy-id, она сама разложит всё по полочкам:
Если ssh-copy-id нет под рукой, можно сделать это вручную (но это дольше):
2. Проверь права (на локальной машине):
Приватный ключ должен быть доступен только тебе (права 600), иначе SSH-клиент может отказаться работать или это создаст дыру в безопасности.
Переходи на Ed25519 — это быстрее, короче и безопаснее. Сохрани шпаргалку, чтобы не гуглить флаги! 🔥
#SSH #Linux #Security #DevOps #CLI
С возвращением! 👋
Всё еще генерируешь ключи через rsa -b 4096? Это надежно, но ключи получаются длинными, а генерация — медленной. В современном мире стандартом де-факто становится Ed25519. Это алгоритм на эллиптических кривых: он безопаснее, быстрее и создает очень компактные ключи, которые удобно копировать.
Давай обновим твои доступы за одну минуту.
📌 Команда для генерации:
ssh-keygen -t ed25519 -C "admin@myserver"
Разбор флагов:
-t ed25519 — указываем тип ключа. Он обеспечивает превосходную безопасность и высокую производительность.
-C "комментарий" — метка (обычно email), чтобы ты не запутался в authorized_keys, когда ключей станет много.
💡 Что делать дальше?
1. Закинь ключ на сервер:
Используй утилиту ssh-copy-id, она сама разложит всё по полочкам:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-host
Если ssh-copy-id нет под рукой, можно сделать это вручную (но это дольше):
cat ~/.ssh/id_ed25519.pub | ssh user@remote-host "cat >> ~/.ssh/authorized_keys"
2. Проверь права (на локальной машине):
Приватный ключ должен быть доступен только тебе (права 600), иначе SSH-клиент может отказаться работать или это создаст дыру в безопасности.
chmod 600 ~/.ssh/id_ed25519
Переходи на Ed25519 — это быстрее, короче и безопаснее. Сохрани шпаргалку, чтобы не гуглить флаги! 🔥
#SSH #Linux #Security #DevOps #CLI
👍12🔥2
💾 UUID или /dev/sda? Почему твой сервер не грузится
Привет, суперпользователь! 👋
Знакомая ситуация: подключил новый диск, перезагрузил сервер, а он «встал»? Скорее всего, имена устройств сместились (например, sda стал sdb), и система не нашла корневой раздел по старому пути,.
Чтобы спать спокойно, используй в /etc/fstab не имена устройств, а UUID (универсальный уникальный идентификатор). Он остается неизменным, даже если ты переставишь диски местами,.
📌 Как узнать UUID всех разделов?
Используй команду blkid (Block ID). Она покажет атрибуты всех блочных устройств.
Что мы видим:
UUID="..." — тот самый идентификатор, который нужно копировать в fstab.
TYPE="..." — тип файловой системы (ext4, swap, vfat).
💡 Лайфхак:
Если нужно узнать данные только для конкретного диска, просто укажи его имя: blkid /dev/sda1.
#Linux #SysAdmin #Storage #CLI #Fstab
Привет, суперпользователь! 👋
Знакомая ситуация: подключил новый диск, перезагрузил сервер, а он «встал»? Скорее всего, имена устройств сместились (например, sda стал sdb), и система не нашла корневой раздел по старому пути,.
Чтобы спать спокойно, используй в /etc/fstab не имена устройств, а UUID (универсальный уникальный идентификатор). Он остается неизменным, даже если ты переставишь диски местами,.
📌 Как узнать UUID всех разделов?
Используй команду blkid (Block ID). Она покажет атрибуты всех блочных устройств.
# blkid
/dev/sdf2: UUID="b600fe63-d2e9-461c-a5cd-d3b373a5e1d2" TYPE="ext4"
/dev/sda1: UUID="17f12d53-c3d7-4ab3-943e-a0a72366c9fa" TYPE="ext4" PARTUUID="c9a5ebb0-01"
/dev/sda5: UUID="b600fe63-d2e9-461c-a5cd-d3b373a5e1d2" TYPE="swap" PARTUUID="c9a5ebb0-05"
/dev/sde1: UUID="4859-EFEA" TYPE="vfat"
Что мы видим:
UUID="..." — тот самый идентификатор, который нужно копировать в fstab.
TYPE="..." — тип файловой системы (ext4, swap, vfat).
💡 Лайфхак:
Если нужно узнать данные только для конкретного диска, просто укажи его имя: blkid /dev/sda1.
#Linux #SysAdmin #Storage #CLI #Fstab
👍17
🔥 Забудь про vim: Добавляем источники apt в одну строку
root@localhost:~#
Часто нужно добавить новый репозиторий в систему (например, при начальной настройке сервера), но открывать текстовый редактор долго и неудобно для скриптов. Обычное перенаправление вывода через sudo может вызвать ошибку «Permission denied».
Есть элегантный способ добавлять строки текста в файл, например, имя репозитория ПО в файл источников, не открывая его для редактирования. Используй синтаксис с командой tee.
📌 Команда для добавления репозитория (на примере Nginx):
Разбор полетов:
echo — передает строку текста в канал (pipe).
lsb_release -cs — автоматически подставляет кодовое имя твоего дистрибутива.
sudo tee — принимает вывод и записывает его в файл с правами суперпользователя, обходя ограничения оболочки.
💡 Совет:
Используй флаг -a с командой tee (например, sudo tee -a), если хочешь добавить строку в конец файла, а не перезаписать его полностью.
#Linux #CLI #SysAdmin #DevOps #Apt
root@localhost:~#
Часто нужно добавить новый репозиторий в систему (например, при начальной настройке сервера), но открывать текстовый редактор долго и неудобно для скриптов. Обычное перенаправление вывода через sudo может вызвать ошибку «Permission denied».
Есть элегантный способ добавлять строки текста в файл, например, имя репозитория ПО в файл источников, не открывая его для редактирования. Используй синтаксис с командой tee.
📌 Команда для добавления репозитория (на примере Nginx):
echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
Разбор полетов:
echo — передает строку текста в канал (pipe).
lsb_release -cs — автоматически подставляет кодовое имя твоего дистрибутива.
sudo tee — принимает вывод и записывает его в файл с правами суперпользователя, обходя ограничения оболочки.
💡 Совет:
Используй флаг -a с командой tee (например, sudo tee -a), если хочешь добавить строку в конец файла, а не перезаписать его полностью.
#Linux #CLI #SysAdmin #DevOps #Apt
👍8
🔥 Забудь про 500 ошибку: Тест конфига Nginx перед запуском
echo "Привет, инженер!"
Знакомая ситуация: поправил конфиг, перезапустил службу, а сервер «лежит» из-за пропущенной точки с запятой? Чтобы избежать страданий и простоя продакшна, всегда проверяй исправность конфигурационных файлов перед перезапуском.
У многих популярных программ есть встроенные средства для такой проверки.
📌 Команда для проверки конфигурации Nginx:
Что происходит:
Если в файле нет синтаксических ошибок, команда просто завершится или выведет сообщение об успехе. Если ошибки есть, она сообщит о них, указав строку с проблемой,.
💡 Совет:
Используй systemctl reload вместо restart, когда это возможно. Reload (перезагрузка конфигурации) обычно безопаснее, так как процесс перезапускается только после успешной проверки конфигурации,.
Проверяй конфиг до того, как это сделают пользователи! 😉
#Nginx #Linux #SysAdmin #DevOps #CLI
echo "Привет, инженер!"
Знакомая ситуация: поправил конфиг, перезапустил службу, а сервер «лежит» из-за пропущенной точки с запятой? Чтобы избежать страданий и простоя продакшна, всегда проверяй исправность конфигурационных файлов перед перезапуском.
У многих популярных программ есть встроенные средства для такой проверки.
📌 Команда для проверки конфигурации Nginx:
nginx -t
Что происходит:
Если в файле нет синтаксических ошибок, команда просто завершится или выведет сообщение об успехе. Если ошибки есть, она сообщит о них, указав строку с проблемой,.
💡 Совет:
Используй systemctl reload вместо restart, когда это возможно. Reload (перезагрузка конфигурации) обычно безопаснее, так как процесс перезапускается только после успешной проверки конфигурации,.
Проверяй конфиг до того, как это сделают пользователи! 😉
#Nginx #Linux #SysAdmin #DevOps #CLI
👍14👀3👎1
🔒 Вот что hackers проверяют в первую очередь на твоём сервере
Каждый день на серверы идут тысячи автоматических сканирований на поиск слабых мест.
Проблема: ты даже не знаешь, какие уязвимости уже есть в твоей системе. SSH настроена правильно? Firewall включён? Сервисы обновлены?
Решение: два инструмента, которые за минуты покажут тебе всё, что видит хакер.
🔹 vps-audit
https://github.com/vernu/vps-audit
Легковесный bash-скрипт для быстрого аудита VPS:
• Проверяет SSH-конфигурацию (root login, слабые пароли)
• Статус firewall, fail2ban и открытых портов
• Запущенные сервисы и SUID файлы
• Генерирует цветной отчёт (🟢 PASS / 🟡 WARN / 🔴 FAIL)
• Нет зависимостей, работает везде
🔹 Lynis
https://github.com/CISOfy/lynis
Профессиональный инструмент аудита (15+ лет на рынке):
• Сканирует 200+ параметров безопасности
• Проверяет compliance (PCI DSS, HIPAA, ISO27001)
• Поиск уязвимостей в ПО и конфигурации
• Детальный hardening index — оценка безопасности
• Работает на Linux, macOS, BSD (14.5k звёзд на GitHub)
Запусти прямо сейчас — узнаешь, что hackers видят на твоём сервере первым делом.
#Linux #Monitoring #Disk #DevOps #Bash #CLI
Каждый день на серверы идут тысячи автоматических сканирований на поиск слабых мест.
Проблема: ты даже не знаешь, какие уязвимости уже есть в твоей системе. SSH настроена правильно? Firewall включён? Сервисы обновлены?
Решение: два инструмента, которые за минуты покажут тебе всё, что видит хакер.
🔹 vps-audit
https://github.com/vernu/vps-audit
Легковесный bash-скрипт для быстрого аудита VPS:
• Проверяет SSH-конфигурацию (root login, слабые пароли)
• Статус firewall, fail2ban и открытых портов
• Запущенные сервисы и SUID файлы
• Генерирует цветной отчёт (🟢 PASS / 🟡 WARN / 🔴 FAIL)
• Нет зависимостей, работает везде
🔹 Lynis
https://github.com/CISOfy/lynis
Профессиональный инструмент аудита (15+ лет на рынке):
• Сканирует 200+ параметров безопасности
• Проверяет compliance (PCI DSS, HIPAA, ISO27001)
• Поиск уязвимостей в ПО и конфигурации
• Детальный hardening index — оценка безопасности
• Работает на Linux, macOS, BSD (14.5k звёзд на GitHub)
Запусти прямо сейчас — узнаешь, что hackers видят на твоём сервере первым делом.
#Linux #Monitoring #Disk #DevOps #Bash #CLI
👍11🔥4
🐳 20 пунктов по Docker, покроет 90% ежедневных задач.
Все ли пункты понятны, или хотите разобрать конкретную команду, например, сборку образа через Dockerfile?
❗️ ❗️ ❗️ Нравится формат? Ставь 👍
👉 Рубрика: #шпаргалка@LinuxSkill
#Docker #DevOps #Контейнеры #Linux #CLI #Cheatsheet
1.docker run: Запуск нового контейнера из образа (например, docker run -it ubuntu /bin/bash).
2.docker ps: Список всех запущенных в данный момент контейнеров.
3.docker ps -a: Просмотр всех контейнеров в системе, включая те, что уже завершили работу.
4.docker stop [ID/Name]: Корректная остановка работающего контейнера.
5.docker start [ID/Name]: Запуск ранее остановленного контейнера.
6.docker rm [ID/Name]: Удаление контейнера (перед этим его нужно остановить).
7.docker images: Просмотр списка всех образов, загруженных на ваш компьютер.
8.docker pull [Image]: Скачивание образа из удаленного реестра (Docker Hub).
9.docker build -t [Name] .: Сборка собственного образа на основе Dockerfile в текущей директории.
10.docker rmi [Image]: Удаление локального образа из системы.
11.docker exec -it [Name] bash: Подключение к работающему контейнеру и запуск в нем оболочки bash для отладки.
12.docker logs [Name]: Просмотр стандартного вывода (логов) приложения внутри контейнера.
13.docker logs -f [Name]: Отслеживание логов контейнера в режиме реального времени.
14.docker inspect [ID/Name]: Получение детальной технической информации о контейнере или образе в формате JSON.
15.docker network ls: Просмотр списка всех сетей, созданных в Docker.
16.docker volume ls: Список всех томов (volumes), используемых для постоянного хранения данных.
17.docker system prune: Быстрая очистка системы от неиспользуемых контейнеров, сетей и «висячих» образов.
18.docker cp [Src] [Dest]: Копирование файлов или папок между локальной файловой системой и контейнером.
19.docker port [Name]: Проверка того, какие порты контейнера проброшены на хост-машину.
20.docker login: Авторизация в реестре образов для выгрузки своих работ.
Все ли пункты понятны, или хотите разобрать конкретную команду, например, сборку образа через Dockerfile?
👉 Рубрика: #шпаргалка@LinuxSkill
#Docker #DevOps #Контейнеры #Linux #CLI #Cheatsheet
Please open Telegram to view this post
VIEW IN TELEGRAM
👍46