ServerAdmin.ru
31.6K subscribers
841 photos
57 videos
23 files
2.99K links
Авторская информация о системном администрировании.

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

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

Ресурс включён в перечень Роскомнадзора
Download Telegram
Технический пост, который уже давно нужно было сделать, но всё руки не доходили. На канале много содержательных заметок по различным темам. Иногда сам через поиск ищу то, о чём писал. Ниже набор наиболее популярных тэгов по которым можно найти что-то полезное (и не очень).

#remote - все, что касается удалённого управления компьютерами
#helpdesk - обзор helpdesk систем
#backup - софт для бэкапа и некоторые мои заметки по теме
#zabbix - всё, что касается системы мониторинга Zabbix
#мониторинг - в этот тэг иногда попадает Zabbix, но помимо него перечислено много различных систем мониторинга
#управление #ITSM - инструменты для управления инфраструктурой
#devops - в основном софт, который так или иначе связан с методологией devops
#kuber - небольшой цикл постов про работу с kubernetes
#chat - мои обзоры на популярные чат платформы, которые можно развернуть у себя
#бесплатно - в основном подборка всяких бесплатностей, немного бесплатных курсов
#сервис - сервисы, которые мне показались интересными и полезными
#security - заметки, так или иначе связанные с безопасностью
#webserver - всё, что касается веб серверов
#gateway - заметки на тему шлюзов
#mailserver - всё, что касается почтовых серверов
#elk - заметки по ELK Stack
#mikrotik - очень много заметок про Mikrotik
#proxmox - заметки о популярном гипервизоре Proxmox
#terminal - всё, что связано с работой в терминале
#bash - заметки с примерами полезных и не очень bash скриптов или каких-то команд. По просмотрам, комментариям, сохранениям самая популярная тематика канала.
#windows - всё, что касается системы Windows
#хостинг - немного информации и хостерах, в том числе о тех, кого использую сам
#vpn - заметки на тему VPN
#perfomance - анализ производительности сервера и профилирование нагрузки
#курсы - под этим тэгом заметки на тему курсов, которые я сам проходил, которые могу порекомендовать, а также некоторые бесплатные курсы
#игра - игры исключительно IT тематики, за редким исключением
#совет - мои советы на различные темы, в основном IT
#подборка - посты с компиляцией нескольких продуктов, объединённых одной тематикой
#отечественное - обзор софта из реестра отечественного ПО
#юмор - большое количество каких-то смешных вещей на тему IT, которые я скрупулезно выбирал, чтобы показать вам самое интересное. В самом начале есть шутки, которые придумывал сам, проводил конкурсы.
#мысли - мои рассуждения на различные темы, не только IT
#разное - этим тэгом маркирую то, что не подошло ни под какие другие, но при этом не хочется, чтобы материал терялся, так как я посчитал его полезным
#дети - информация на тему обучения и вовлечения в IT детей
#развитие_канала - серия постов на тему развития данного telegram канала

Остальные тэги публикую общим списком без комментариев, так как они про конкретный софт, понятный из названия тэга:
#docker #nginx #mysql #postgresql #gitlab #asterisk #openvpn #lxc #postfix #bitrix #икс #debian #hyperv #rsync #wordpress #zfs #grafana #iptables #prometheus #1с #waf #logs #netflow
👍282👎5
​​Ниже на картинке наглядное подтверждение того, что выбор дистрибутива Debian после прекращения поддержки Centos, был абсолютно верен. Всё вышло так, как я и предполагал. Появилось несколько форков, которые конкурируют друг с другом и создают разделение в сообществе.

Я выборочно взял трех провайдеров, где у меня есть учетные записи и виртуальные машины. И посмотрел, какие ОС они предлагают в своих шаблонах. Все три предложили разные замены Centos:
- Oracle Linux
- Rocky Linux
- AlmaLinux

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

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

Иногда использую Ubuntu, так как некоторый софт на ней быстрее и проще развернуть, но сам лично её не люблю за постоянные изменения от релиза к релизу, которые лично мне никаких удобств не добавляют, а только создают проблемы. Ну зачем постоянно менять установщик? На Debian он хуже что ли? Хотя не менялся уже лет 10.

Если нет трудно, напишите с пояснением на какой системе остановились в итоге и почему.

#debian #centos
👍76👎5
Иногда возникают ситуации, когда у сервера по той или иной причине нет доступа в интернет. У меня лично теперь есть такие сервера. А вам нужно как-то обновлять и устанавливать пакеты и желательно не вручную. Для этого можно поднять свой репозиторий и вручную управлять им, обновляя все остальные машины через него. Это сложный путь и не всегда оправданный, если вам нужно обновлять одну машину, да и то не регулярно.

Для решения подобной проблему есть удобный инструмент - apt-offline (https://github.com/rickysarraf/apt-offline). Как видно из названия он актуален для DEB дистрибутивов. Я его использовал для Debian. Качаете архив с последним релизом из репозитория, копируете и распаковываете на сервере без интернета. В нём будет бинарник apt-offline, с ним и будем работать.

Для начала обновим репозитории на сервере:
# ./apt-offline set --update apt-offline.sig
Тут же в директории будет создан файл apt-offline.sig. Теперь можно всю папку с apt-offline и этим файлом перенести на сервер с интернетом и там запустить:
# ./apt-offline get --bundle bundle.zip apt-offline.sig
Информация с содержимым репозиториев будет сохранена в файл bundle.zip. Возвращаемся на сервер без инета и там запускаем обновление реп:
# ./apt-offline install bundle.zip

Теперь обновим все пакеты целевого сервера:
# ./apt-offline set --update --upgrade apt-offline.sig
Идём на компьютер с интернетом и там качаем пакеты:
# ./apt-offline get --bundle bundle.zip apt-offline.sig
Будут скачаны все обновления пакетов и зависимости. Опять берём всю директорию и копируем на сервер без инета. Там запускаем:
# ./apt-offline install bundle.zip
# apt upgrade

Для установки только одного пакета делаем следующее:
# ./apt-offline set --install-packages PACKAGENAME --update apt-offline.sig
Копируем папку на комп с инетом и там выполняем:
# ./apt-offline get --bundle bundle.zip apt-offline.sig
Возращаем на комп без инета и запускаем установку пакета:
# ./apt-offline install bundle.zip
# apt install PACKAGENAME

У вас есть в хозяйстве сервера без интернета? У меня это некоторые сервера с бэкапами, правда там я сам вручную включаю инет когда надо, а потом отключаю. А вот полностью без инета приходилось работать у некоторых заказчиков. Таскал туда руками пакеты, пока не узнал про apt-offline. На днях про него вспомнил и написал заметку.

#debian #ubuntu
👍77👎2
Есть одна вещь, которая мне не нравится в Debian. Я всегда выполняю одну и ту же настройку сразу после установки системы. Не понимаю, кто придумал по умолчанию логи cron писать в общий системный лог /var/log/syslog. Это при том, что настройка для отдельного ведения журнала cron уже есть в конфиге rsyslog, но почему-то закомментирована. И настройка для логирования файла /var/log/cron.log уже есть в logrotate.

Если вы так же, как и я, любите, когда логи cron хранятся в отдельном файле, то сделайте следующее. Открываете на редактирование /etc/rsyslog.conf и раскомментируете строку:
cron.*                 /var/log/cron.log
Далее отключаем запись логов в общий файл. Добавляем cron.none в следующую строку:
*.*;auth,authpriv.none,cron.none    -/var/log/syslog
Перезапускаем rsyslog и cron:
# systemctl restart rsyslog cron

Проверяем, появился ли файл с логом.
# ls -l /var/log/cron.log

На всякий случай проверьте файл /etc/logrotate.d/rsyslog. Есть ли там строка с упоминанием файла /var/log/cron.log. Вроде должна быть. Не помню, чтобы я руками добавлял.

Мне кажется реально удобно, когда логи крона живут отдельно. Их довольно часто используешь, так как cron популярный инструмент. Хотя его сейчас активно вытесняют таймеры systemd. Надо про них отдельно написать.

Я подзабыл, а в Ubuntu тоже логи cron в наследство от Debian пишутся в общий syslog? Кто-то делает подобную настройку или это мой бзик? Я после Centos никак не могу привыкнуть, что по дефолту нет этого лога.

#debian
👍74👎3
​​Никогда не понимал, почему вывод информации об устанавливаемых пакетах в apt-get, а потом и в apt такой неудобный. Вам просто вываливают лапшу перед глазами, где трудно что-то разобрать, например найти отдельный пакет. И ладно бы трудно было придумать что-то получше, но оно уже есть. Берём yum/dnf, там всё красиво и удобно. Почему нельзя сделать так же? Достаточно добавить форматирование.

Кажется, что это мелочь, но когда я пользовался Centos, меня прям отвращало от Debian и Ubuntu именно это поведение apt. Я не понимал, почему не сделать удобно, как в других дистрибутивах. Не понимаю я этого и сейчас. Когда впервые услышал про apt, как замену apt-get, думал, там это будет решено. Но нет.

Если хотите в Debian или Ubuntu получить нормальный вывод информации о пакетах при работе с пакетным менеджером, можете поставить Nala. Она не делает ничего особенного - просто приводит вывод apt в человекочитаемый вид. Ну и бонусом может параллельно скачивать пакеты в несколько потоков.

Поставить Nala можно либо из собранного пакета, либо из репозитория Testing/Sid самого Debian. Его нужно будет отдельно добавить в систему. Лучше этого не делать, чтобы случайно не обновиться с тестовых реп. Это необратимый процесс. Либо сразу после установки отключить его.

Я так понимаю, раз Nala уже в Testing/Sid, то есть шанс, что её перенесут в основной стабильный репозиторий. Было бы неплохо.

Исходники - https://gitlab.com/volian/nala

#debian #ubuntu
👍78👎3
В последнее время навводили кучу запретов на загрузку софта с IP адресов РФ. Я покажу на наглядном примере, как поднять свой deb репозиторий, наполнить его санкционным софтом и использовать в своей инфраструктуре.

Пример будет не гипотетический, а самый что ни на есть актуальный. Допустим, нам надо на парке серверов обновить filebeat от компании elastic, которая закрыла доступ к своим публичным репозиториям с территории РФ. Я включил прокси, скачал через браузер пакет filebeat-8.4.3-amd64.deb.

Далее идём на сервер с Debian, где будем настраивать локальный репозиторий с помощью aptly.
# apt install aptly

Создаём конфиг /etc/aptly.conf. Содержимое берём из документации, где меняем только rootDir и имя FileSystemPublishEndpoints.

{
 "rootDir": "/mnt/repo",
 "downloadConcurrency": 4,
 "downloadSpeedLimit": 0,
 "architectures": [],
 "dependencyFollowSuggests": false,
 "dependencyFollowRecommends": false,
 "dependencyFollowAllVariants": false,
 "dependencyFollowSource": false,
 "dependencyVerboseResolve": false,
 "gpgDisableSign": false,
 "gpgDisableVerify": false,
 "gpgProvider": "gpg",
 "downloadSourcePackages": false,
 "skipLegacyPool": true,
 "ppaDistributorID": "elk",
 "ppaCodename": "",
 "FileSystemPublishEndpoints": {
  "elkrepo": {
   "rootDir": "/var/www/aptly",
   "linkMethod": "symlink",
   "verifyMethod": "md5"
  }
 },
 "enableMetricsEndpoint": false
}

Создаём необходимые директории:
# mkdir -p /mnt/repo /var/www/aptly

Создаю репозиторий для Debian 11:
# aptly repo create -distribution="bullseye" elk
Копирую на сервер пакет и добавляю его в репозиторий:
# aptly repo add elk ~/filebeat-8.4.3-amd64.deb

Создаю gpg ключ для репозитория:
# gpg --default-new-key-algo rsa4096 --gen-key --keyring pubring
Real name: elkrepo

Публикуем репозиторий с этим ключом:
# aptly publish repo elk

Далее вам нужно поднять любой веб сервер и настроить через него доступ к директории /var/www/aptly. Если не хочется это делать, можно запустить сам aptly как веб сервер (дефолтный порт 8080):
# aptly serve

Он автоматом создаст и опубликует директорию /mnt/repo/public. Для удобства можно туда выгрузить публичный ключ:
# gpg --export --armor > /mnt/repo/public/elkrepo.asc

Можно зайти браузером на 8080 порт сервера и посмотреть содержимое репозитория вместе с gpg ключом.

Теперь идём на клиенты и подключаем репозиторий. Для этого создаём файл /etc/apt/sources.list.d/elk_repo.list:

deb http://10.20.1.56:8080 bullseye main

Обновляем пакеты и устанавливаем или обновляем filebeat:
# apt update && apt install filebeat

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

#debian #elk
👍123👎4
​​В выступлении с DevOpsConf, про которое выйдет заметка вечером, увидел упоминание очень любопытной программы nfpm, с помощью которой можно собирать свои deb или rpm пакеты. Я посмотрел и нашёл её современной, простой и полезной. Сразу же попробовал на реальном примере. Результатом делюсь с вами.

Я не стал ничего придумывать, а взял бинарники от Tegu и упаковал их в deb пакет, чтобы максимально упросить установку. Видел, что кто-то docker контейнер собирает для этого. Но как по мне докер тут вообще не нужен. Задача полностью решается обычным пакетным менеджером.

Итак, ставим nfpm:
# echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' |
tee /etc/apt/sources.list.d/goreleaser.list
# apt update
# apt install nfpm

Готовим для него конфиг nfpm.yaml:

name: "tegu"
arch: "amd64"
platform: "linux"
version: "v1.27.0"
section: "default"
priority: "optional"
conflicts:
 - exim4
 - postfix
maintainer: "Kalmetov Igor <ik@mbk-lab.ru>"
description: |
 Tegu is the free mailserver.
vendor: "mbk-lab.ru"
homepage: "https://project.mbk-lab.ru"
contents:
- src: ~/tegu/bin/teguctl
 dst: /opt/tegu/bin/
- src: ~/tegu/sbin/tegu
 dst: /opt/tegu/sbin/
- src: ~/tegu/tegu.conf
 dst: /etc/tegu.conf
 type: config
- src: ~/tegu/tegu.service
 dst: /etc/systemd/system/tegu.service
 type: config
overrides:
 deb:
  scripts:
   preinstall: /root/tegu/preinstall.sh
   postinstall: /root/tegu/postinstall.sh

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

Файлы tegu.service и tegu.conf взял из документации. Добавил свои скрипты для выполнения некоторых действий.

preinstall.sh:

#!/bin/bash
mkdir /opt/tegu
mkdir /opt/tegu/{bin,sbin,data,certs}
chown -R mail. /opt/tegu/{data,certs}
chgrp -R mail /opt/tegu/{bin,sbin}
chmod 750 /opt/tegu/{data,certs}
chmod -R 750 /opt/tegu/sbin
chmod -R 750 /opt/tegu/bin

postinstall.sh:

chown root.mail /etc/tegu.conf
chmod 640 /etc/tegu.conf
setcap CAP_NET_BIND_SERVICE=+eip /opt/tegu/sbin/tegu
systemctl enable tegu.service
systemctl start tegu.service

Собираем пакет:
# nfpm pkg --packager deb --target ~/
using deb packager...
created package: ~/tegu_1.27.0_amd64.deb

Пакет собран. Можно установить:
# dpkg -i ~/tegu_1.27.0_amd64.deb

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

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

#linux #debian #apt #tegu
👍80👎3
На днях вышел релиз Debian 12 Bookworm. Для меня это не стало сюрпризом, так как недавно я уже смотрел эту версию и проверял, как проходит обновление с прошлого релиза. У меня уже довольно много серверов под управлением Debian, так что вопрос меня касается напрямую.

Решил не откладывать задачу на потом и сразу рассмотреть изменения новой версии. Я написал подробную статью с обновлением с 11-й версии на 12-ю. Постарался рассмотреть наиболее значимые моменты обновления в соответствии с рекомендациями самих разработчиков из заметки Upgrades from Debian 11 (bullseye).

https://serveradmin.ru/kak-obnovit-debian-11-do-debian-12-bookworm/

Из основных нововведений, помимо обновления пакетов, я отметил следующие:

В установочные образы включили некоторые прошивки из репозитория non-free. Это сделано для лучшей поддержки железа во время установки. Debian всегда очень внимательно относился к проприетарному софту, выделяя его в отдельный репозиторий non-free. В этом релизе решили сделать некоторые исключения. Поэтому добавлен ещё один репозиторий для проприетарных прошивок non-free-firmware.

В Debian 12 добавлен пакет ksmbd-tools, который реализует функциональность файлового сервера на базе протокола SMB3. Сервер работает на базе модуля ядра Linux. Подобная реализация более эффективна с точки зрения производительности, потребления памяти и интеграции с расширенными возможностями ядра. При этом ksmbd не претендует на полноценную замену Samba. Скорее как расширение для неё.

По умолчанию не используется rsyslog для записи системных логов. Вместо этого предлагают использовать journalctl для просмотра логов systemd. Если хотите (а мы хотим) по старинке системные логи в текстовом виде в /var/log, установите пакет system-log-daemon.

Из дистрибутива выпилили утилиту which, которая объявлена устаревшей. Вместо неё предлагают использовать type. Это приведёт к поломке многих скриптов, где часто используют which для определения полного пути к бинарнику. Не забудьте установить вручную whitch, если она у вас используется.

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

С полным списком можете ознакомиться в официальной новости или переводе на opennet. За что лично мне нравится Debian, так это за его стабильность. В нём мало каких-то революционных изменений ради изменений. К примеру, сколько я знаю Debian, ещё со времён 6-й версии, у него не менялся интерфейс установщика. В этом просто нет смысла. Всё, что нужно в плане функциональности, там есть. Нет смысла менять то, что хорошо работает.

Я один свой сервер уже обновил, всё прошло штатно. Остальной прод торопиться обновлять не буду. Подожду месячишко, другой.

Скоро наверное Proxmox свою новую версию выкатит. Он обычно подгоняет свои релизы под релизы Debian. Я уже видел инфу про появление 8-й беты.

#debian
👍133👎3
​​На практике регулярно приходится собирать Nginx с дополнительными модулями. Чаще всего это модули brotli, vts или lua. У меня когда-то была статья для Centos по этой теме, но она уже неактуальна. Решил сделать мини-инструкцию по сборке своего пакета Nginx для Debian на примере добавления туда модуля статистки vts. А завтра отдельной публикацией покажу, как с его помощью очень быстро организовать мониторинг Nginx.

Выполнять сборку следует на отдельной машине, а не на рабочем сервере, чтобы не засорять его лишними пакетами. Я буду использовать небольшой читинг, а не полноценную сбоку пакета, которая не очень проста. Возьму готовые файлы настроек для упаковки в Debian 11 из официального репозитория Nginx. Распакую их, немного изменю настройки и запакую с ними свой пакет.

Устанавливаем необходимые зависимости, которые понадобятся для сборки Nginx и упаковки в deb пакет:
# apt install dpkg-dev devscripts quilte quivs wget dh-make build-essential \
git libpcre++-dev libssl-dev libgeoip-dev libxslt1-dev zlib1g-dev libpcre2-dev

Скачиваем файлы, которые нам понадобятся: исходники и настройки:
# mkdir build && cd build
# wget http://nginx.org/packages/debian/pool/nginx/n/nginx/nginx_1.24.0-1~bullseye.debian.tar.xz
# wget http://nginx.org/download/nginx-1.24.0.tar.gz

Распаковываем всё и удаляем архивы, чтобы не мешали:
# tar xvf nginx_1.24.0-1~bullseye.debian.tar.xz
# tar xzvf nginx-1.24.0.tar.gz
# rm -rf nginx_1.24.0-1~bullseye.debian.tar.xz nginx-1.24.0.tar.gz

Создаём директорию для модулей:
# mkdir debian/modules

Копируем туда исходники nginx-module-vts:
# cd debian/modules
# git clone https://github.com/vozlt/nginx-module-vts

Возвращаемся обратно в build и переносим директорию debian/ в папку с исходниками:
# cd ../../
# mv debian ./nginx-1.24.0
# cd nginx-1.24.0

Редактируем некоторые файлы. Начинаем с debian/changelog. Добавьте в начало по аналогии новую запись с описанием нового пакета. Примерно так:
nginx (1.24.0-1~bullseye) bullseye; urgency=low

 * 1.24.0-1
 * Add nginx-module-vts

 -- Serveradmin <root@serveradmin.ru> Fri, 18 Aug 2023 10:03:46 +0300

Важно следить за всеми отступами и пробелами. Если просто скопируете отсюда, то будут ошибки. Копируйте строки из исходного файла и меняйте их.

Далее вам может понадобиться файл debian/control, где можно добавить зависимости. В моём случае новых зависимостей не появится. А если вы, к примеру, захотите добавить модуль с lua, то там нужно будет пару пакетов в систему установить. Просто добавьте их в Build-Depends.

Открываем файл debian/rules и добавляем туда:
MODULESDIR = $(CURDIR)/debian/modules
Можете эту строку добавить сразу же после строки с BASEDIR. Далее ищем строки с ./configure и добавляем к ним в конец дополнительный параметр:
--add-module=$(MODULESDIR)/nginx-module-vts
Здесь же можете удалить лишние модули, которые вам точно не понадобятся.

Удаляем файл debian/source/format. Он не даст собрать пакет.
# rm -rf debian/source/format

Сохраняем файл и собираем архив с настройками пакета:
# dh_make --copyright gpl -s -e root@serveradmin.ru --createorig -y -p nginx_1.24.0
В директории build должен появиться файл nginx_1.24.0.orig.tar.xz.

Собираем пакет:
# dpkg-buildpackage -rfakeroot

В директории build должен появиться в том числе файл с пакетом nginx_1.24.0-1~bullseye_amd64.deb. Его можно установить и проверить:
# dpkg -i nginx_1.24.0-1~bullseye_amd64.deb

Проверяем, есть ли там наш модуль:
# nginx -V
В самом конце должно быть
--add-module=/root/build/nginx-1.24.0/debian/modules/nginx-module-vts

На этом всё. Таким образом можно собирать любые сборки Nginx под свои потребности и размещать их в своих репозиториях. Например, с помощью Nexus, aptly, apt-offline и т.д.

Заметка получилась полноценной инструкцией с информацией, которую я в интернете не нашёл в готовом виде. Пришлось написать самому.

#debian #nginx
👍90👎1
Забавная история случилась с моим репозиторием для ELK Stack. Специально расположил его на VPS, арендованном в USA, чтобы было удобнее скачивать новые пакеты и обновлять репозитории. И вот на днях решил в очередной раз его обновить и очень удивился, когда не смог ничего скачать по свежим ссылкам. Получал ERROR 403: Forbidden. Проверил на другом иностранном сервере, скачал без проблем. То есть мой VPS забанили. Не понятно, в рамках чего это было сделано. Кто-то стуканул или какая-то другая причина. Обновлял я в ручном режиме и запросами не спамил. IP (188.227.57.126) по всем базам сшашный.

Пришлось через другой сервер качать и обновлять репозиторий. Теперь его можно и в Россию вернуть. Один фиг качать через прокладки придётся. Я там всю структуру переделал, добавив сразу Debian 11 и 12, чтобы удобнее было. Настроил всё с помощью aptly, так что сразу кратко все команды приведу, а то постоянно забываю и приходится каждый раз в документацию лезть, когда с ним работаешь.

Ставим:
# apt install aptly

Конфиг /etc/aptly.conf:
{
 "rootDir": "/mnt/aptly",
 "downloadConcurrency": 4,
 "downloadSpeedLimit": 0,
 "architectures": [],
 "dependencyFollowSuggests": false,
 "dependencyFollowRecommends": false,
 "dependencyFollowAllVariants": false,
 "dependencyFollowSource": false,
 "dependencyVerboseResolve": false,
 "gpgDisableSign": false,
 "gpgDisableVerify": false,
 "gpgProvider": "gpg",
 "downloadSourcePackages": false,
 "skipLegacyPool": true,
 "ppaDistributorID": "elastic",
 "ppaCodename": "",
 "FileSystemPublishEndpoints": {
 "elastic": {
  "rootDir": "/mnt/aptly",
  "linkMethod": "symlink",
  "verifyMethod": "md5"
 }
 },
 "enableMetricsEndpoint": false
}

Под репы выделил каталог /mnt/aptly. Создаём 2 репозитория:
# aptly repo create -comment="Elastic repo" -component="main" \
-distribution="bullseye" -architectures="amd64" elastic-bullseye
# aptly repo create -comment="Elastic repo" -component="main" \
-distribution="bookworm" -architectures="amd64" elastic-bookworm

Добавляем туда пакеты:
# aptly repo add elastic-bullseye elasticsearch-8.9.2-amd64.deb
.......

# aptly repo add elastic-bookworm elasticsearch-8.9.2-amd64.deb
.......

Создаю gpg ключ для репозиториев:
# gpg --default-new-key-algo rsa4096 --gen-key --keyring pubring

Публикую репозитории:
# aptly publish repo elastic-bullseye
# aptly publish repo elastic-bookworm

В директории /mnt/aptly появляются две директории: db, public. Ту, что public, надо опубликовать через web сервер. Вот мой конфиг nginx:

server {
  listen 80 default_server;
  server_name elasticrepo.serveradmin.ru;
  root /mnt/aptly/public/;
  access_log /var/log/nginx/aptly-access.log main;
  error_log /var/log/nginx/aptly-error.log;

  location / {
   autoindex on;
  }
}

Осталось положить ключ в публичную директорию:
# gpg --export --armor > /mnt/repo/public/elastic.asc

На этом всё. Запускаем веб сервер и подключаем репозитории к системам:
# echo "deb http://elasticrepo.serveradmin.ru bullseye main" \
| tee /etc/apt/sources.list.d/elasticrepo.list

# echo "deb http://elasticrepo.serveradmin.ru bookworm main" \
| tee /etc/apt/sources.list.d/elasticrepo.list

Устанавливаем ключ:
# wget -qO - http://elasticrepo.serveradmin.ru/elastic.asc | apt-key add -

На Debian 12 увидите предупреждение, что apt-key is deprecated, но это не критично. Теперь можно обновлять репозитории и устанавливать из них пакеты.

Если нужно добавить пакеты, то делаем так:
# aptly repo add elastic-bullseye elasticsearch-9.0.0-amd64.deb
# aptly publish update bullseye

Если надо удалить пакет:
# aptly repo remove elastic-bullseye elasticsearch_8.5.2_amd64
# aptly publish update bullseye
# aptly db cleanup

Ещё полезные команды aptly:
# aptly repo list
# aptly package search logstash
# aptly repo show -with-packages elastic-bullseye

#debian #elk #aptly
👍70👎1
​​Как вы думаете, почему за столько лет пакетный менеджер для Debian и Ubuntu, тот, который сначала был apt-get, а сейчас просто apt, не стал удобным? Чтобы понять о чём идёт речь, посмотрите внизу картинку сравнения работы apt и dnf.

Когда появился apt, я подумал, что теперь и в Debian будет так же удобно и красиво, как в Centos. Ведь что сложного в том, чтобы отформатировать информацию о выводимых пакетах? Но увы, apt как был неудобен, так и остался.

Если нужно обновить старую систему или установить что-то объёмное, apt вываливает длиннющую трудночитаемую лапшу названий пакетов, в которой трудно разглядеть полезную информацию. И в противовес этому yum/dnf, которые выводят список в алфавитном порядке, каждый пакет в отдельной строке, видно версию, размер пакета, репозиторий, откуда он будет установлен. Всё четко и понятно.

В apt можно добавить ключ -V и будет немного лучше:
# apt -V upgrade
Но об этом мало кто знает и использует. Я и сам узнал только тогда, когда написал похожий пост тут на канале. На днях просто работал с dnf и опять вспомнил про эту тему. Уже когда сел писать заметку понял, что я её уже писал когда-то. Этот ключ стоило бы по умолчанию добавлять в стандартный вывод. С ним ведь всяко удобнее.

Ну а если хочется так же красиво и удобно, как в dnf, можно поставить Nala. К сожалению, она живёт только в Testing/Sid, в основные репы почему-то не переводят. Можно поставить из репы разработчика:
# echo "deb https://deb.volian.org/volian/ scar main" \
| sudo tee -a /etc/apt/sources.list.d/volian-archive-scar-unstable.list
# wget -qO - https://deb.volian.org/volian/scar.key | apt-key add -
# apt update && apt install nala

И будет красота, как в dnf, даже чуть лучше.

#debian
👍124👎7
Некоторое время назад у меня к статье про обновление Debian с 11 на 12 появился комментарий, на тему того, что зачем такие статьи. Debian и так автоматически обновляется с выходом нового релиза. Я как-то особо не обратил внимание, потому что знаю, что система сама собой на новый релиз не обновится, если не предпринять явных действий для этого.

А на днях другой человек предположил, что скорее всего в репозиториях у автора коммента был указан релиз в виде stable, а не конкретной версии bullseye или bookworm. И тогда стало понятно, почему у кого-то система может обновиться автоматически. Я поясню этот момент, потому что он важный и неочевидный. Поначалу, когда начинал работать с Debian, тоже не понимал этот момент.

В Debian для именования выпусков используются как псевдонимы в виде имён персонажей мультфильма «История игрушек»: Wheezy, Jessie, Stretch, Buster, Bullseye, Bookworm, так и классы релизов: Stable, Oldstable, Testing, Unstable, Experimental, Backports.

🔹Stable - стабильная ветка официального текущего релиза Debian. То есть это самая свежая и актуальная версия, которую рекомендуется использовать.

🔹Oldstable - кодовое имя предыдущего stable выпуска.

🔹Testing - содержит в себе текущее состояние разработки нового стабильного релиза. После его выхода, testing становится stable. Пакеты в testing попадают из репы unstable.

🔹Unstable (sid) - репозиторий с самым свежим программных обеспечением. Оно еще не протестировано достаточным образом для использования. Если вы точно уверены, что вам нужен новый софт, и он не сломает вам систему, можете поставить его из unstable репозитория. Но в общем случае, делать это не рекомендуется. Даже если софт из unstable не повредит работе системы, он может нарушить зависимости пакетов, так что потом может быть затруднительно вернуться на stable ветку.

Исходя из этой информации, если у вас по какой-то причине описание репозитория в sources.list будет в таком виде:

deb http://ftp.debian.org/debian stable main contrib

То система будет автоматически обновляться до нового стабильного релиза в соответствии с правилами формирования ветки Stable. Выполнив после обновления релиза:
# apt update && apt dist-upgrade
Вы получите новый стабильный выпуск. Или не получите, если что-то пойдёт не так.

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

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

Подробно о репозиториях в Debian можно почитать в моей обзорной статье.

#debian
👍145👎2
Протестировал новый для себя инструмент, с которым раньше не был знаком. Он очень понравился и показался удобнее аналогичных, про которые знал и использовал раньше. Речь пойдёт про систему планирования и управления задачами серверов Cronicle. Условно его можно назвать продвинутым Cron с веб интерфейсом. Очень похож на Rundeck, про который когда-то писал.

С помощью Cronicle вы можете создавать различные задачи, тип которых зависит от подключенных плагинов. Например, это может быть SHELL скрипт или HTTP запрос. Управление всё через веб интерфейс, там же и отслеживание результатов в виде логов и другой статистики. Помимо перечисленного Cronicle умеет:
◽️работать с распределённой сетью машин, объединённых в единый веб интерфейс;
◽️работать в отказоустойчивом режиме по схеме master ⇨ backup сервер;
◽️автоматически находить соседние сервера;
◽️запускать задачи в веб интерфейсе с отслеживанием работы в режиме онлайн;
◽️подсчитывать затраты CPU и Memory и управлять лимитами на каждую задачу;
◽️отправлять уведомления и выполнять вебхуки по результатам выполнения задач;
◽️поддерживает API для управления задачами извне.

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

Cronicle написана на JavaScript, поэтому для работы надо установить на сервер NodeJS версии 16+. Я тестировал на Debian, версию взял 20 LTS. Вот краткая инструкция:
# apt update
# apt install ca-certificates curl gnupg
# mkdir -p /etc/apt/keyrings
# curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
| gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
# NODE_MAJOR=20
# echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \
| tee /etc/apt/sources.list.d/nodesource.list
# apt update
# apt install nodejs

Теперь ставим сам Cronicle. Для этого есть готовый скрипт:
# curl -s https://raw.githubusercontent.com/jhuckaby/Cronicle/master/bin/install.js \
| node
Установка будет выполнена в директорию /opt/cronicle. Если ставите master сервер, то после установки выполните setup:
# /opt/cronicle/bin/control.sh setup
А потом запустите:
# /opt/cronicle/bin/control.sh start

Теперь можно идти в веб интерфейс на порт сервера 3012. Учётка по умолчанию - admin / admin. В веб интерфейсе всё понятно, разобраться не составит труда. Для подключения второго сервера, на него надо так же установить Cronicle, но не выполнять setup, а сразу запустить, скопировав на него конфиг /opt/cronicle/conf/config.json с master сервера. Там прописаны ключи, которые должны везде быть одинаковые.

В веб интерфейсе можно добавить новое задание, настроить расписание, выбрать в качестве типа shell script и прям тут же в веб интерфейсе написать его. Дальше выбрать сервер, где он будет исполняться и вручную запустить для проверки. Я потестировал, работает нормально.

На выходе получилось довольно удобная и практичная система управления задачами. Насколько она безопасна архитектурно, не берусь судить. По идее не очень. В любом случае на серверах доступ к службе cronicle нужно ограничить на уровне firewall запросами только с master сервера. Ну а его тоже надо скрыть от посторонних глаз и лишнего доступа.

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

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

#script #devops
👍81👎4
​​Заметка для тех кому приходится разбираться на чужих серверах или перенимать полностью управление в свои руки. Для deb дистрибутивов есть инструмент debsums, живёт в базовых репах:

# apt install debsums

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

А вот проверить конкретно изменения в стандартных конфигурационных файлах бывает очень полезно. Например, если кто-то изменял стандартный конфиг /etc/ssh/ssh_config или /etc/default/ssh, то вы это увидите:

# debsums --config --changed
/etc/ssh/ssh_config
/etc/default/ssh

И так для всех стандартных конфигов, которые идут в составе пакетов, в том числе которые устанавливаются с базовой системой. Юниты systemd, конфиги в /etc/pam.d, /etc/grub.d, /etc/defaults и т.д. Всё будет проверяться.

Простой и удобный инструмент для того, чтобы быстро оценить, что на сервере менялось и настраивалось. Увидите в том числе изменённые конфиги установленного софта, типа nginx или mariadb. То есть сразу будет видно, что сюда ставили и настраивали.

#debian
👍176👎1
За что больше всего люблю дистрибутив Debian, так это за его консерватизм. Много лет назад я написал статью на сайте:

Как настроить сетевые параметры в Debian

Последние 5 лет вообще её не трогал. А она не потеряла актуальность и популярность. Последние 2 года это самая посещаемая статья сайта. Каждый день по 200-300 посетителей приходят её прочитать. А за всё время её посмотрели сотни тысяч раз. Если прикинуть, то это большой масштаб. И таких статей много. То, что я написал, прочитали уже миллионы людей. Вроде сидишь себе, что-то пишешь. А тебя читает столько народа. В уникальное время живём. Надо это ценить.

Собрался с силами и переработал статью, актуализировал. Перенёс все настройки на ip, замерив ifconfig и route. Давно серьёзно не занимался сайтом и контентом нём. Это забирает очень много времени. Нет возможности его выделять. Одна переработка заняла целый день. А если писать с нуля, то нужно ещё больше времени. Для того, чтобы подобная статья вышла в топ поисковиков, приходится работать с SEO, надо это знать. Из-за этого текст выглядит немного косоязычно. Но если этого не сделать, то текст заберут другие сайты, добавят SEO и статья от них уйдёт в ТОП. Так что лучше самому сразу сделать так, как надо.

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

Статью можно использовать новичкам как шпаргалку. Там есть вся база:

◽️статические и динамические настройки ip адресов
◽️dns и hostname
◽️статические маршруты
◽️vlan
◽️отключение ipv6
◽️несколько адресов на одном интерфейсе

Узнал для себя некоторые новые вещи, на которые раньше не обращал внимание. Например, 2 типа активации сетевого интерфейса в /etc/network/interfaces:

▪️auto - интерфейс активируется при загрузке системы. Это подходящая настройка для статичного сетевого адаптера.
▪️allow-hotplug - интерфейс поднимается, когда подсистема udev обнаружит его. Это произойдёт и при загрузке системы, как в случае с auto, если сетевая карта будет подключена, и в случае подключения, отключения устройства. Например, если это usb сетевая карта или VPN туннель. Настройка больше подходит для динамических сетевых интерфейсов.

Ещё интересный момент. Если сбросить dhcp lease через консоль соответствующей командой:

# dhclient -r

То вы не только потеряете все полученные по dhcp настройки, но и статические адреса. Соответственно, вас отключает по ssh. Для меня это было сюрпризом. Такие вещи надо делать осторожно, имея доступ к консоли сервера напрямую.

#debian #network
👍184👎3
Я привык для установки python приложений использовать либо пакетный менеджер системы apt, либо пакетный менеджер самого python – pip. Это устаревший подход, который имеет много недостатков. Через пакетный менеджер обычно доступны только наиболее популярные приложения. Их список ограничен. А через pip напрямую ставить неудобно, так как это ломает совместимость с приложениями, установленными через apt. Если уж хочется использовать pip, то надо запускать его в изолированном окружении, что тоже создаёт некоторые неудобства в дальнейшем использовании приложений.

Решил разобраться с этой темой. В настоящий момент в deb системах, в частности, Debian и Ubuntu, для установки python приложений лучше использовать pipx. Он позволяет автоматически устанавливать приложения в изолированном окружении, которые вызываются нативно из командной строки, но при этом не конфликтуют с системными пакетами. Сам pipx живёт в базовом репозитории:

# apt install pipx
# pipx ensurepath
# source ~/.profile

Далее его можно использовать для установки приложений. Покажу на недавнем примере с ansible-cmdb. Он получится показательным для раскрытия темы. Его можно поставить через pipx:

# pipx install ansible-cmdb

Но работать установленный таким образом ansible-cmdb не будет. Это связано с тем, что собранный пакет очень старый и не умеет работать в виртуальном окружении, которое создаёт pipx. Последний создаёт символьные ссылки с именем приложения, а сами приложения размещает отдельно в виртуальном окружении. А ansible-cmdb ищет свои ресурсы по жёстко привязанным путям к тому месту, откуда его запустили. С современным приложениями такой проблемы не будет.

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

Сам uv ставим через pipx:

# pipx install uv

Пример установки зависимостей через uv:

# uv pip install -r requirements.txt

А теперь возвращаемся к ansible-cmdb и запускаем его в виртуальном окружении через uv:

# uv venv .venv
# source .venv/bin/activate
# uv pip install ansible-cmdb

Проверяем:

# ansible-cmdb --help

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

# pip install ansible-cmdb --break-system-packages

Если это всё используется в отдельной виртуалке или контейнере. Но в целом правильно запускать именно так, как я описал в текущей заметке. Это не будет ломать совместимость с системными пакетами и другими python приложениями.

📌 Резюмирую:
◽️pipx используем для установки современных python приложений;
◽️uv для установки зависимостей, библиотек и создания виртуальных окружений в том числе для запуска старых приложений.

❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.

#debian #python
2👍180👎9
Проработал вчера вопрос обновления Debian 12 до свежего релиза 13 Trixie. Предстоит много раз проделать эту процедуру, поэтому решил сам внимательно прочитать документацию к новому релизу и вручную выполнить обновление.

Как обновить Debian 12 до Debian 13 Trixie

Из особенностей отмечу следующее:

🔹У меня возникли проблемы совместимости с некоторыми пакетами Docker, так что рекомендую всё, что установлено не из стандартных репозиториев удалить, а после обновления вернуть, иначе в процессе могут возникнуть ошибки совместимости и зависимости пакетов.

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

🔹Наконец-то обновился менеджер пакетов apt и стал хоть немного, но удобнее за счёт форматирования списка пакетов и подсветки. Не понимаю, почему так долго не могли это сделать. Но даже в таком виде он выглядит хуже, чем yum или dnf даже 15 лет назад. У apt появился новый формат конфигурации. Я использовал уже его.

🔹В Debian 13 убраны утилиты last, lastb и lastlog. Вместо них можно использовать wtmpdb (пакет libpam-wtmpdb), lastlog2 (пакет libpam-lastlog2) и команду lslogins --failed.

🔹Раздел /tmp переехал в оперативную память tmpfs. Может занимать до 50% свободной памяти. Настроить поведение можно в systemd в отдельном конфигурационном файле для этого tmp.mount.

🔹Немного поменялся установщик. Я лично посмотрел на его. По описанию показалось, что он сильно поменялся. На деле не увидел изменений. Основные изменения под капотом. Внешний вид точно такой же остался. Упоминалось, что изменился алгоритм автоматической настройки разделов и точек монтирования. Заметил только, что размер раздела под swap немного по-другому выбирается. Больше никакой разницы не увидел со старым установщиков, который я знаю ещё со времён 6-й версии.

🔹Если у вас на сервере установлена MariaDB, имейте ввиду, что режим recovery запустится только с теми же бинарниками, с которыми база упала. То есть если аварийно завершите работу СУБД версии 10.11 и обновитесь до 11.8, восстановление не сработает. Поэтому перед обновлением корректно завершите работу СУБД, чтобы она остановилась без каких-либо ошибок.

🔹Если в системе используется служба systemd-sysctl, то файл /etc/sysctl.conf больше ею не поддерживается. Вместо него используется /usr/lib/sysctl.d/50-default.conf. Важное изменение. Имейте ввиду. Настройки лучше хранить в /etc/sysctl.d/*.conf.

Всё это вычитал по официальным ссылкам:

◽️What’s new in Debian 13
◽️Upgrades from Debian 12 (bookworm)

#linux #debian
1👍161👎2
В новом релизе Debian 13 обновился пакетный менеджер apt до версии 3.0, которая вышла в апреле 2025 года. В прошлом релизе apt был версии 2.6. От пакетного менеджера нужно обычно немного - установить пакет и зависимости. Основное, на что обращаешь внимание - интерфейс. И вот тут у apt всегда было всё как-то не очень.

Это не очень и попытались исправить. Стало лучше, но всё равно не так информативно, как в том же dnf. Сравнение можно посмотреть на картинке внизу. Не знаю, в чём сложность повторить примерно так же. У dnf и репозиторий сразу видно, и версию пакета, и отформатировано аккуратнее. У apt стало лучше, чем было, когда все пакеты простынёй вываливали. Частично это можно было исправить дополнительными ключами, но всё равно не так наглядно было, как у dnf.

Ну да ладно, что есть то есть. Посмотрел повнимательнее на новый apt, так как теперь постоянно с ним работать придётся. Вот основные изменения по сравнению с прошлой версией.

1️⃣ Как я уже сказал - внешний вид. Более наглядно выделены пакеты и зависимости. Плюс, по умолчанию появилась подсветка. Ею, если что, можно управлять через параметры. Не знаю, кому это может понадобиться. Я точно заниматься подобной настройкой не буду.

2️⃣ Теперь вывод apt, который не умещается в один экран терминала, например, при apt search, не вываливается весь в него, а выводится построчно, как при использовании less. Соответственно, работают все горячие клавиши от less. Я чаще всего использую Shif-g - переместиться в конец списка, / - включить поиск. Подробнее про less писал отдельно.

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

# apt -o APT::Pager= list | grep zabbix

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

3️⃣ Появилась поддержка формата DEB822 для описания репозиториев. Вместо файла sources.list можно описывать репозитории в sources.list.d/*.sources. Текущий sources.list преобразовать в новый формат можно так:

# apt modernize-sources

Эта команда забэкапит файл sources.list и создаст вместо него sources.list.d/debian.sources. Так же новый apt поддерживает использование Debian APT CDN. Можно указать в качестве источника пакетов deb.debian.org, а реальный сервер для загрузки будет выбран автоматически на основании не знаю чего. Не нашёл информации на этот счёт.

Мне новый формат понравился больше. Лучше воспринимается на глаз за счёт того, что запись репозитория разбита на строки с заголовками. Плюс, через Enabled: no можно отключать репозиторий. Это более аккуратно выглядит, чем комментирование строк с репозиториями.

4️⃣ Появился новый движок поиска зависимостей. Не знаю, для чего он был сделан и какие проблемы решил. Я не сталкивался с какими-то проблемами в зависимостях из-за apt.

Ещё ряд не таких заметных в эксплуатации изменений:
- появились несжатые индексы, традиционно их сжимают gzip или xz, теперь будут и несжатые
- переработали механизм autoremove, но я не увидел сам и не нашёл нигде примеров, что конкретно изменилось
- прекращено использование утилиты apt-key и общего хранилища ключей, но это не сказать, что что-то новое, от неё уже давно отказываются в пользу отдельного ключа для каждого репозитория
- вместо gnutls и gcrypt для шифрования теперь используется openssl

В завершении несколько полезных ключей для apt.

Посмотреть версии устанавливаемых пакетов:

# apt -V install mc

Пакеты, установленные не из системных репозиториев:

# apt list '?narrow(?installed, ?not(?origin(Debian)))'

Список установленных пакетов с версиями и репозиториями, откуда они были установлены:

# apt -o APT::Pager= list --installed -a | grep -v stable

То же самое, только чтобы можно было грепнуть неродные репы:

# apt -o APT::Pager= list -a --installed | grep -v stable | grep -v '^$'

———
ServerAdmin: 📱 Telegram | 🌐 Сайт | 📲 MAX

#linux #debian
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍105👎2