07 октября 2024 Linux


Для того чтобы UDP приходящие из внешней сети на 53 порт перенаправить на другой порт, например 1025, необходимо добавить вот такое правило

sudo iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 1025

# а удалить во тако

sudo iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-port 1025

Для того чтобы UDP идушие по локальной сети на 53 порт перенаправить на другой порт, например 1025, необходимо добавить вот такое правило

sudo iptables -t nat -A OUTPUT -p udp --dport 53 -j REDIRECT --to-port 1025

# удалить вот так
sudo iptables -t nat -D OUTPUT -p udp --dport 53 -j REDIRECT --to-port 1025

 


01 октября 2024 02 октября 2024 СуБД


Настройка определяются практически в одном месте, на главном сервер, а дочерний сервер отличается от главного только наличием сигнального файла postgres-slave1/standby.signal в директории с данными на подчинённом сервере. То-есть, сначала конфигурируется главный сервер так, чтобы в случае обнаружения файла  standby.signal он стал вторичным, но перед этим, на том сервере который должен стать вторичным необходимо удалить базу и восстановить с первичного, а затем создать файл  standby.signal

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

Для начала создам файл docker-compose.yml и определю там запуск и настройки главного сервера

version: "3.9"

services:
  master:
    image: postgres:14
    container_name: master
    volumes:
      - ./postgres-master:/var/lib/postgresql/data/
      - ./wals:/var/lib/postgresql/archive/
    env_file:
      - .env

так же небходимо создать файл с настройками по умолчанию для postgres

POSTGRES_USER=test
POSTGRES_PASSWORD=test++test
POSTGRES_DB=test
POSTGRES_INITDB_ARGS=

создадим директории для хранения данных СУБД вне контейнеров

mkdir {postgres-master,postgres-slave1,postgres-slave2}

создадим директорию для хранения wal файлов

mkdir wals

Запускаем главный сервер и проверяем его работу

docker-compose up  -d

docker-compose exec master psql -U test # войти в консоль главным пользователем и посмотреть список баз

create database test111;  -- создать базу test111

\l
                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges 
-----------+-------+----------+------------+------------+-------------------
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 test      | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 test111   | test  | UTF8     | en_US.utf8 | en_US.utf8 | 

Готово, сервер работает. Теперь склонируем секцию настройки главного сервера в docker-compose.yml, назовём его slave1 и перезапустим клустер, а так же проверим какие базы имеются на подчинённом сервере

version: "3.9"

services:
  master:
    image: postgres:14 
    container_name: master
    volumes:
      - ./postgres-master:/var/lib/postgresql/data/
      - ./wals:/var/lib/postgresql/archive/
    env_file:
      - .env

  slave1:
    image: postgres:14 
    container_name: slave1 
    volumes:
      - ./postgres-slave1:/var/lib/postgresql/data/
      - ./wals:/var/lib/postgresql/archive/
    env_file:
      - .env

Перезапуск клустера

docker-compose down
docker-compose up -d

docker-compose ps 
NAME                COMMAND                  SERVICE             STATUS              PORTS
master              "docker-entrypoint.s…"   master              running             5432/tcp
slave1              "docker-entrypoint.s…"   slave1              running             5432/tcp

Проверка баз на подчинённом сервере

docker-compose exec slave1 psql -U test
psql (14.13 (Debian 14.13-1.pgdg120+1))
Type "help" for help.

test=# \l
                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges 
-----------+-------+----------+------------+------------+-------------------
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 test      | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
(4 rows)

Тут видно, что на подчинённом сервере отсутствует таблица test111, это произошло потому, что slave1 пока что не является подчинённым сервером, так как она ещё не настроен

Для того чтобы slave1 стал подчинённым необходимо разрешить главному серверу принимать внешние подключения от подчинённых серверов.

Для этого необходимо на главном сервере создать нового пользоваетля с правами репликации и разрешить этого пользоватлю внешние подключения

create user newuser replication login PASSWORD '2024';

теперь необходимо разрешить удалённый доступ этому пользователю

Для этого необходимо на главном сервере в файле postgres-master/pg_hba.conf добавить разрешение. Адрес 0.0.0.0/0 я использую для среды докер контейнером, потому там адрес контейнером могут менять, по этому будем принимать все входящие

host    replication     newuser         0.0.0.0/0               md5

Перезапускае главный сервер и проверяем возможность доступ с починённого

docker-compose restart 
docker-compose exec slave1 psql postgres://newuser:2024@master/test111 # тут я использую упрощённый способ формирования строки запрос в виде урла, такие урлы применяются во многих приложениях совместимых libpg

psql (14.13 (Debian 14.13-1.pgdg120+1))
Type "help" for help.

test111=> \l
                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges 
-----------+-------+----------+------------+------------+-------------------
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 test      | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 test111   | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
(5 rows)

test111=> 

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

Теперь попробуем на подчинённом сервере загрузить резервную копию главного сервер

docker-compose exec slave1 pg_basebackup -d postgres://newuser:2024@master -v -D /tmp/base

Тут мы из среды подчинённого сервер подключаемся к главному и выкачиваем бекап в директорию /tmp/base

Если всё хорошо сработало, то пришло время настраивать отношения master слейв для клустера.

Для этого переопределим настройки главного сервера в файле sudo vim postgres-master/postgresql.conf

wal_level = replica
max_wal_senders = 5                # я указываю 5
archive_mode = on

wal_keep_size = 1024                # Обеспечивает хранение WAL файлов до передачи
hot_standby = on

archive_command = 'test ! -f /var/lib/postgresql/data/archive/%f && cp %p /var/lib/postgresql/archive/%f'

Строчку est ! -f /var/lib/postgresql/data/archive/%f && cp %p /var/lib/postgresql/archive/%f необходимо пояснить: эта строчка описывает комаду которая создаёт архивную копию WAL файл, в моём случае я копию её в директорию которая доступна снаружи конейнера: ./wals:/var/lib/postgresql/archive/

Затем уже для подчинёного сервера привести переменную primary_conninfo к такому виду, эта переменная редактируется в файле мастер сервера, но она будет игнорироваться мастеро

primary_conninfo = 'host=master port=5432 user=newuser password=2024'

Теперь необходимо на удалить все данные на подчинённом сервере в директории /var/lib/postgresql/data/ и на освободившееся место поместить бекап главного сервера с помощь утилиты pg_basebackup, но перед этим необходимо оставить подчинённй сервер постгрес

docker-compose stop slave1

docker-compose run slave1 rm -R /var/lib/postgresql/data/

Теперь скачиваем бека с главного сервера запускаем подчинённый

docker-compose run slave1 pg_basebackup -d postgres://newuser:2024@master -v -D /var/lib/postgresql/data

А теперь самое главное, создание файла сигнала, обнаружив который, обычный узел Postgres превращается в ведомй

sudo touch postgres-slave1/standby.signal

Запускаем подчнённый сервер и видим, что появилась база которая была создана на главном  сервере

docker-compose start slave1

echo \\l | docker-compose exec -T master psql -U test
                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges 
-----------+-------+----------+------------+------------+-------------------
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 test      | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
 test111   | test  | UTF8     | en_US.utf8 | en_US.utf8 | 
(6 rows)

Теперь создадим новую скопируем живую базу на главный сервер клустера

# создание новой базы
docker-compose exec master createdb -U test global-art

# клонирование живой базы с одного из моих тестовых серверов
pg_dump  -c globalart | docker-compose exec -T master psql -U test global-art

# проверка структуры новой базы на главном сервере
echo \\dt | docker-compose exec -T master psql -U test global-art
                      List of relations
 Schema |                Name                | Type  | Owner 
--------+------------------------------------+-------+-------
 public | auth_group                         | table | test
 public | auth_group_permissions             | table | test
 public | auth_permission                    | table | test
 public | auth_user                          | table | test
 public | auth_user_groups                   | table | test
 public | auth_user_user_permissions         | table | test
 public | catalog_accessory                  | table | test
 public | catalog_accessory_subproducts      | table | test
 public | catalog_additionalfile             | table | test

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

docker-compose exec master pg_dump -U test global-art |md5sum
164858e3f201d1f6261c3fad4b5ff59a  -

Видим, что контрольная сумма  базы на главном сервере равна 164858e3f201d1f6261c3fad4b5ff59a

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

docker-compose exec slave1 pg_dump -U test global-art |md5sum
164858e3f201d1f6261c3fad4b5ff59a  -

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

Визуализация работы клустера

Добавление новых записей в главной базе

Добавление новых записей в главной базе

Проверка добавления новых записей на подчинённых серверах

Проверка добавления новых записей на подчинённых серверах

Логи работы клустера

Логи работы клустера


17 сентября 2024 Hardware


Состав

  • Intel(R) Core(TM) i5-14600K
  • Gigabyte B760 GAMING X AX
  • Kingston DDR5 5200 MT/s 32 GB AB151BAE (2шт)
  • Samsung SSD 990 PRO 1TB (4B2QJXD7)

Тест 7z

7z b -mmt=20

7-Zip 23.01 (x64) : Copyright (c) 1999-2023 Igor Pavlov : 2023-06-20
 64-bit locale=ru_RU.UTF-8 Threads:20 OPEN_MAX:1024

 mt=20
Compiler: 13.2.0 GCC 13.2.0: SSE2
Linux : 6.8.0-44-generic : #44-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 13 13:35:26 UTC 2024 : x86_64
PageSize:4KB THP:madvise hwcap:2 hwcap2:2
Intel(R) Core(TM) i5-14600K (B0671) 

1T CPU Freq (MHz):  5191  5271  5268  5251  5256  5260  5258
10T CPU Freq (MHz): 892% 4024   889% 4037  

RAM size:   64065 MB,  # CPU hardware threads:  20
RAM usage:   4449 MB,  # Benchmark threads:     20

                       Compressing  |                  Decompressing
Dict     Speed Usage    R/U Rating  |      Speed Usage    R/U Rating
         KiB/s     %   MIPS   MIPS  |      KiB/s     %   MIPS   MIPS

22:     123228  1642   7300 119877  |     885844  1600   4720  75523
23:     110449  1591   7075 112535  |     886279  1631   4699  76670
24:     102531  1563   7051 110241  |     856978  1599   4703  75198
25:     105061  1677   7151 119955  |     812367  1543   4683  72279
----------------------------------  | ------------------------------
Avr:    110317  1618   7144 115652  |     860367  1593   4701  74918
Tot:            1606   5923  95285

10 сентября 2024 30 сентября 2024 Linux DNS DNS сервер DNS протокол


Список опций

ssnn --help
Использовать так: ssnn [-hVv] [-p <port>] [--ttl=<ttl>] [-a <admin>]... [--zones=<zones>]... [TYPE=NAME=VALUE]...
Такие есть аргументы.

  -h, --help                показать подсказку и выйти
  -V, --version             показать версию и выйти
  -v, --verbose             расширенный вывод
  -p, --port=<port>         Номер порта (1024)
  --ttl=<ttl>               TTL (default: 600)
  -a, --admin=<admin>       Админ по умолчанию
  --zones=<zones>           Путь к директории зон (zones)
  TYPE=NAME=VALUE           Multiple records (e.g., A=test.ru=127.0.0.1)

Запустить на 53 порту можно только с root правами или в Docker контейнере с пробросом порта

sudo ./ssnn --port=53

Через опцию командной строки добавить две ресурсные A-записи для домена test.ru

./ssnn A=test.ru=127.0.0.1 A=test.ru=192.168.0.1

Поддерживаются следующие записи

Тип ресурсной записи Структура значения
A список IP адресов, по одной на каждую строку
MX число адрес-сервера
CNAME строка
HINFO список строк ключ;значение
SOA строка емейла администратора зоны
TXT список строк длиной до 255 символов
URI число число урл

Так же опциями запуска можно изменить значение по умолчанию для параметра TTL и емейл администратора всех зон

Настройки зоны можно сохранить в виде иерархии директорий и файлов, представленной в виде:

[D:путь к настройкам]/[D:название ресурсной записи]/[D:ТИП РЕСУРСНОЙ ЗАПИСИ/[F:значение ресурсной записи]

Директория ресурсных записей

По умолчанию настройки должны размещаться в директории zones либо можно изменить с помощью опции --zones=/etc/ssnn/zones/

После запуска программа анализирует опции запуска и формирует группу хешь-таблиц ресурсных запией,

затем загружаются данные из директории ZONES (при этом замещая ранее определённые записи)

затем сервер переходит в режим обслуживания неблокируемых UDP соединений с DNS клиентами

для внесения изменений в настройки ресурсных записей необходимо изменить данные в хранилища --zones и перезапустить сервер

либо можно отправить серверу сигнал SIGHUP, после получения сигнала сервер заново загружает все данные из хранилища --zones

pkill -q ssnn

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

echo $(awk '{print $1+1}' < zzz/example.com/SERIAL ) > zzz/example.com/SERIAL
cat zzz/example.com/SERIAL
4

killall -1 ssnn 

nslookup -querytype=SOA -port=1025 example.com 127.0.0.1
Server:		127.0.0.1
Address:	127.0.0.1#1025

example.com
	origin = example.com
	mail addr = ff.ya.ru
	serial = 4
	refresh = 600
	retry = 6000
	expire = 6000
	minimum = 600

 


28 августа 2024 10 сентября 2024 Linux bash xxd


Предположим есть некоторый дамп данных в формате hex, определяем его в переменную xxx

xxx='e9 e4 85 80 00 01
00 01 00 00 00 00 03 63 64 6e 09 63 65 6e 74 72
73 76 65 74 02 72 75 00 00 05 00 01 c0 0c 00 05
00 01 00 00 00 78 00 19 0a 32 6d 76 36 35 32 73
62 75 33 01 61 06 74 72 62 63 64 6e 03 6e 65 74
00'

Затем в цикле преобразуем каждое значение и сохраняем в файл

for x in $xxx ; do 
echo x$x |  xxd -r -p  ; 
done > xxx.bin

Преобразовать обратно в дополнительный ANSI форма

hexdump -C xxx.bin

 


19 августа 2024 Nginx


# сохранить публичный сертификат сайта
openssl s_client -connect breys.ru:443 -showcerts | openssl x509 -pubkey -noout > pubkey.pem


# зашифровать файл msg.txt 
openssl pkeyutl -in msg.txt -out msg.enc -pubin -inkey pubkey.pem -encrypt


# преобразовать бинарный формат зашифрованного файла в текстовый (пункт 3)
openssl base64 -in msg.enc -out msg.enc.asc


# преобразовать текстовый формат зашифрованного файла в бинарный (пункт 4)
openssl base64 -d -in msg.enc.asc -out msg.enc


# расшифровать зашифрованный файл msg.enc с помощью закрытого ключа домена
openssl pkeyutl -in msg.enc -out msg.txt -inkey privkey.pem -decrypt


# зашифровать файл, упаковать в текстовый формат, отправить через сеть и расшифровать одной командой
openssl pkeyutl -in msg.txt  -pubin -inkey pubkey.pem -encrypt |openssl base64 | ssh-balancer1 'cat |openssl base64 -d| openssl pkeyutl   -inkey /etc/letsencrypt/live/www.breys.ru/privkey.pem -decrypt'

Так же можно шифровать и расшировывать с помощью паролей

# зашфировать файл /etc/passwd
openssl enc -in /etc/passwd  -e -salt -aes-256-cbc -md sha256


# расшифровать 
openssl enc  -d -aes-256-cbc -md sha256  расшифровать с паролем

 


10 июля 2024 Linux losetup cfdisk dd mkfs


Для получения навыка работы в дисковыми устройствами в среде Linux лучше начать экспериментировать в виртуальными устройствами в домашней папке пользователя

Это позволит безопасно для данных и оборудования освоить процессы разметки раздело, создания файловых систем, монтирования, размонтирования, так же лучше понять принципы работы ядра Linux с данными на дисках

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

 

  1. Создать пустой файл размером 1Гб
    dd if=/dev/zero of=test-image bs=1M count=1024
    1024+0 записей получено
    1024+0 записей отправлено
    1073741824 байт (1,1 GB, 1,0 GiB) скопирован, 0,678707 s, 1,6 GB/s
    
  2. Подключить файл как блочное устройство(диск), тут с помощью утилиты losetup ядро получает имя нового виртуального устройства и имя файла, затем ядро связывает эти данные в новое виртуальное устройство
  3. sudo losetup /dev/loop33 test-image 
  4. Теперь в директории /dev/ появлось виртуальное устройство /dev/loop33 и с ним можно работать как с обычными диском используя инструменты fdisk cfdisk или gparted

    Разметить разделы на новом "диске" под свои тестовые нужны

    sudo cfdisk /dev/loop33
  5. Так как структура файла изменилась и на нём появились разделы, необходимо перемонтировать файл-виртуальное устройство
    # отмонтировать
    sudo losetup -d /dev/loop33 
    
    # примонтировать с поиском разделов
    sudo losetup -P  /dev/loop33  test-image
  6. Теперь в директории /dev/ появятся файлы устройств-разделов находящихся в тестовом файле и с ними можно работать как обычными разделами, там можно создавать файловые системы
    ffsdmad@basm:~$ sudo mkfs.ext4  /dev/loop33p1
    [sudo] пароль для ffsdmad: 
    mke2fs 1.46.5 (30-Dec-2021)
    Discarding device blocks: done                            
    Creating filesystem with 128000 4k blocks and 128000 inodes
    Filesystem UUID: d184b921-84f1-4fbe-8e98-729e67fbbfeb
    Superblock backups stored on blocks: 
    	32768, 98304
    
    Allocating group tables: done                            
    Сохранение таблицы inod'ов: done                            
    Создание журнала (4096 блоков): готово
    Writing superblocks and filesystem accounting information: готово
    
    ffsdmad@basm:~$ sudo mkfs.ext4  /dev/loop33p2
    mke2fs 1.46.5 (30-Dec-2021)
    Discarding device blocks: done                            
    Creating filesystem with 133888 4k blocks and 33520 inodes
    Filesystem UUID: fc175588-43de-4731-973c-875722ed273f
    Superblock backups stored on blocks: 
    	32768, 98304
    
    Allocating group tables: done                            
    Сохранение таблицы inod'ов: done                            
    Создание журнала (4096 блоков): готово
    Writing superblocks and filesystem accounting information: готово
    

    gparted

  7. Просмотр разделов устройства с помощью консольной версии gparted

    Просмотр разделов устройства с помощью консольной версии gparted

  8. Смонтировать новые файловые системы
    # создаёт две директории в /tmp
    mkdir -p /tmp/{1..2}
    
    # монтирование в созданные директории
    sudo mount /dev/loop33p1 /tmp/1 
    sudo mount /dev/loop33p2 /tmp/2
    
  9. Заполнить тестовыми данными
    sudo cp -r /etc /tmp/1/
    
    sudo cp -r /var/mail /tmp/2/
    
    # открыть смонтированные файловые системы в файловом менеджере mc
    mc  /tmp/1/  /tmp/2/ 

  10. Отмонтировать файловые системы, отмонтировать виртуальные устройства и удалить следы
    # отмонтировать файловые системы
    sudo umount /tmp/{1..2}
    
    # отмонтировать виртуальное устройств
    losetup -d /dev/loop33
    
    # удалить файл устройства
    rm test-image

 


17 июня 2024 20 июня 2024 Hardware


 


13 июня 2024 18 июня 2024 Hardware


Регулировочные резисторы типа СП3-9а и СП04

  • М47 3шт
  • 2М2
  • 3К3 2шт
  • 47К

Осцилограм H3013Осцилограм H3013Осцилограм H3013

Цена осцилографа 60 советских рублей, дата выпуска 1979


30 мая 2024 Linux


Для того чтобы обойти блокировку ДокерХаба необходимо

на сервере который не заблокирова DockerHub установить непрозрачный прокси

настроить авторизацию по паролю

настроить Docker на работу с Proxy

Вот пример моих настроек tinyproxy

User tinyproxy
Group tinyproxy
Port 8888
Timeout 600
DefaultErrorFile "/usr/share/tinyproxy/default.html"
StatFile "/usr/share/tinyproxy/stats.html"
LogFile "/var/log/tinyproxy/tinyproxy.log"
LogLevel Info
PidFile "/run/tinyproxy/tinyproxy.pid"
MaxClients 100
BasicAuth user superPsWd
ViaProxyName "superproxy"
ConnectPort 443
ConnectPort 563

Теперь необходимо перенастроить докер приложение,  у меня удалось только через глобальную правку конфига /lib/systemd/system/docker.service, в секции [Service] добавляем прокси переменные

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
Environment="HTTP_PROXY=http://user:superPsWd@my-proxy.xxx:8888"
Environment="HTTPS_PROXY=http://user:superPsWd@my-proxy.xxx:8888"

Затем можно перезагрузить конфиг докера и сам докер

systemctl daemon-reload &&  systemctl restart docker

 


28 мая 2024 Linux


Иногда чтото происходит с материнской платой и отваливается USB порт. Но ядро Linux продолжает пытаться общаться с этим портом и в логах появляются вот такие логи

Cannot enable. Maybe the USB cable is bad

Для исправления этой ошибки необходимо сообщить ядру о необходимости исключить заданный порт из работы, для этого необходимо отправить ID порта в файл /sys/bus/pci/drivers/xhci_hcd/unbind

Найти ID порта можно вот так

find /sys/ -name \*usb8-port2\*

/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0/usb8/8-0:1.0/usb8-port2

у меня получился вот такой ID: 0000:07:00.0, затем этот ID нужно отправить в ядро

echo -n 0000:07:00.0 | tee /sys/bus/pci/drivers/xhci_hcd/unbind

/sys/bus/pci/drivers/xhci_hcd/unbind


27 апреля 2024 Linux


Имею несколько компьютеров с прошлым LTS релизом Ubuntu 24.04, согласно рекомендация перед сменой версий необходимо обновить текущий дистрибутив

root@micro-server:~# apt update 
Сущ:1 http://ru.archive.ubuntu.com/ubuntu jammy InRelease                                                         
Сущ:2 http://ru.archive.ubuntu.com/ubuntu jammy-updates InRelease                                                 
Сущ:3 http://ru.archive.ubuntu.com/ubuntu jammy-backports InRelease                                               
Сущ:4 http://security.ubuntu.com/ubuntu jammy-security InRelease                                                  
Сущ:5 https://esm.ubuntu.com/apps/ubuntu jammy-apps-security InRelease                            
Сущ:6 https://esm.ubuntu.com/apps/ubuntu jammy-apps-updates InRelease
Сущ:7 https://esm.ubuntu.com/infra/ubuntu jammy-infra-security InRelease
Сущ:8 https://esm.ubuntu.com/infra/ubuntu jammy-infra-updates InRelease
Чтение списков пакетов… Готово            
Построение дерева зависимостей… Готово
Чтение информации о состоянии… Готово         
Все пакеты имеют последние версии.


root@micro-server:~# apt upgrade
Чтение списков пакетов… Готово
Построение дерева зависимостей… Готово
Чтение информации о состоянии… Готово         
Расчёт обновлений… Готово
Обновлено 0 пакетов, установлено 0 новых пакетов, для удаления отмечено 0 пакетов, и 0 пакетов не обновлено.


root@micro-server:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.4 LTS
Release:	22.04
Codename:	jammy


root@micro-server:~# grep Prompt /etc/update-manager/release-upgrades
Prompt=lts
#Prompt=normal

root@micro-server:~# do-release-upgrade 
Проверка наличия нового релиза Ubuntu
Нет доступной LTS версии для разработчиков.
Чтобы произвести полное обновление до последнего разрабатываемого (без долгосрочной поддержки) выпуска 
установите Prompt=normal в /etc/update-manager/release-upgrades.

Причём совсем недавно обновление работало и я для тестов обновил 22.04,4 до тестовой версии 24.04, но там обнаружился сломанный пакет docker-python и я ожидал что его починят в официальном релизе

Так вот после выхода релиза ничего не изменилось,

root@csvt:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 24.04 LTS
Release:	24.04
Codename:	noble


root@csvt:~# apt update 
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://archive.ubuntu.com/ubuntu noble-security InRelease
Hit:4 http://archive.ubuntu.com/ubuntu noble-backports InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
root@csvt:~# apt upgrade 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

То-есть сейчас, пока не получается обновиться до офицального LTS Ubuntu 24.04

PS: оказывается, что обновиться с 22.04.4 на 24.04 нельзя потому что это обновление придёт после 15 августа, об этом написано https://discourse.ubuntu.com/t/noble-numbat-release-notes/39890#upgrades-4

Users of Ubuntu 23.10 will be offered an automatic upgrade to 24.04 soon after the release.
Users of 22.04 LTS however will be offered the automatic upgrade when 24.04.1 LTS is released, which is scheduled for the 15th of August.

 


17 апреля 2024 18 апреля 2024 Linux docker stunnel4


Серверную часть тонеля stunnel4 не имеет смысла описывать, а вот создания контейнера шифрующего трафика ещё ни где особо не описано. Итак

В директори services/stunnel4 размещаем 3 файла

  • [remote-ip].pem - файл сертификат, [remote-ip]  я использую для быстрой идентификации IP сервера к которому идёт подключение
  • stunnel.conf - настройка stunnel4
  • Dockerfile - файл образа

в файле stunnel.conf пишем примерно такое

client = yes
pid = /var/run/stunnel.pid
foreground = yes

[postgres]
accept = 0.0.0.0:55432
connect = [remote-ip]:15432
cert = /etc/stunnel/[remote-ip].pem

Разумеется [remote-ip]  заменяем на свой

В файле Dockerfile пишем вот такое

from avccvut/stunnel4:0.1-5.44

COPY ./[remote-ip].pem /etc/stunnel/
COPY ./stunnel.conf /etc/stunnel/

CMD ["stunnel4", "/etc/stunnel/stunnel.conf"]

В файле docker-compose.yml добавляем новый такой контейнер:

  postgres:
    # ...

  stunnel4:
    container_name: ${APP_NAME}-stunnel4
    build:
      context: services/stunnel4
    ports:
      - 55432:55432

После того как контейнер будет запущен обращаться к продакшен базе вот так

docker-compose exec postgres psql postgresql://user:psswrd@stunnel4:55432/dbname

Или например вот так можно скорпировать таблицу из внешней базы в локальный контейнер

docker-compose exec postgres pg_dump postgresql://user:psswrd@stunnel4:55432/dbname -t auth_user | docker-compose exec postgres psql dbname

 


18 декабря 2023 СуБД fail2ban postgres


Если postgres используется в качестве мастерсервера для репликаций то у него должен быть открыт порт для подключения клиентов извне, соответственно открытый порт начнут сканировать с целью подобрать пароли и тогда в логах появится вот такое записи

postgres@postgres FATAL:  no pg_hba.conf entry for host "115.216.124.164", user "postgres", database "postgres", no encryption
postgres@postgres FATAL:  no pg_hba.conf entry for host "222.90.83.209", user "postgres", database "postgres", no encryption

Причём, подбор паролей идёт активно, десятки тысяч запросов за сутки

for f in /var/log/postgresql/postgresql-14-main.log.*.gz; do 
echo `date -r $f +"%Y-%m-%d"` `zcat $f | grep 'no pg_hba.conf entry for host' |wc -l` ; 
done

2023-10-15 79090
2023-12-10 81664
2023-12-03 33115
2023-11-26 22769
2023-11-19 100753
2023-11-12 70794
2023-11-05 130725
2023-10-29 82514
2023-10-22 119528

Для блокировки адресов источников запроса необходимо добавить фильтр и добавить новое правило в fail2ban

/etc/fail2ban/filter.d/postgres.conf

[Definition]
failregex = FATAL:  no pg_hba.conf entry for host "<HOST>"

Затем созданное имя фильтра необходимо использовать в правиле, добавив в конец файла /etc/fail2ban/jail.conf

[postgresql]
enabled   = true
filter    = postgres
action    = iptables[name=PostgreSQL, port=5432, protocol=tcp, blocktype=DROP]
           sendmail-whois[name=PostgreSQL, dest=root]
logpath   = /var/log/postgresql/postgresql-14-main.log
maxretry  = 3
findtime  = 600
bantime   = 604800

После этого необходимо перезапустить fail2ban: service fail2ban restart 

и проконтролировать перезапуск сервиса просмотрел логи: tail -f /var/log/fail2ban.log

  • fail2ban-client status # — покажет список сервисов события которых обслуживает fail2ban
  • fail2ban-client status postgresql # — показать статус обработки postgresql
  • fail2ban-client set postgresql  unbanip 115.216.124.164 222.90.83.209 34.76.158.233 # — удалить из бана заданные IP

19 октября 2023 Rust


use std::io::{self, Write};

fn main() -> io::Result<()> {

    for (idx, line) in std::io::stdin().lines().enumerate() {
        match line {
            Ok(_line) => {
                let _cnt = _line.len();
                let _line = format!("{idx:>5}:[{_cnt:>3}] -> {_line}\n");
                let _ = io::stdout().write(_line.as_bytes());
            },
            Err(e) => println!("Error: {e}")
        };
    }

    Ok(())

}

Здесь интересным может показаться разворачивание итератора line с помощью конструкции match, так как в line может быть Ok("строка") или Err("ошибка"), то для использования необходимо развернуть

А так же вместо println используется запись в stdout


19 октября 2023 Rust stdin lines enumerate


use std::io;

fn main() -> io::Result<()> {

    for (idx, line) in std::io::stdin().lines().enumerate() {
        println!("Номер строки: {idx:>5} -> {}", line.unwrap() );
    }

    Ok(())
}

тут в цикле перебираются пронумерованные строки переданные на входящий канал

{idx:5}, указывает формированить вывод строк в блоке из 5 символов

cat src/main.rs | cargo r

    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/read_stdin`
Номер строки:     0 -> use std::io;
Номер строки:     1 -> 
Номер строки:     2 -> 
Номер строки:     3 -> 
Номер строки:     4 -> fn main() -> io::Result<()> {
Номер строки:     5 -> 
Номер строки:     6 ->     for (idx, line) in std::io::stdin().lines().enumerate() {
Номер строки:     7 ->         println!("Номер строки: {idx:>5} -> {}", line.unwrap() );
Номер строки:     8 ->     }
Номер строки:     9 -> 
Номер строки:    10 ->     Ok(())
Номер строки:    11 -> }

Тоже самое но на python

#!/usr/bin/env python
import sys

for idx, line in enumerate(sys.stdin.readlines()):
    print(f"Номер строки: {idx:>5} -> {line}", end='')