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='')

 


15 октября 2023 Bash curl awk sort uniq egrep white read


Если необходимо проверить большое количество ссылок на сайте то можно воспользоваться вот таким bash скрипт

site=http://127.0.0.1:8080

curl $site 2> /dev/null | egrep -o 'href="[^"]+"' | awk -F\" '{print $2}' | grep /catalog/ | sort | uniq | while read u; do 
curl  $site$u -o /dev/null -w "%{http_code} $u\n" -s 
done >> check-menu.txt 

Данный скрипт

  • скачивает главную страницу сайта: curl $site
  • затем  выбирает все ссылки href: egrep -o 'href="[^"]+"'
  • выбирает содержимое аттрибута href: egrep -o 'href="[^"]+"'
  • отбирает ссылки содержащие /catalog/: grep /catalog/
  • сортирует и отбирает только уникальные ссылки: sort| uniq
  • в цикле запрашивает кажду ссылку и сохраняет статус ссылки в файл check-menu.txt ;

13 октября 2023 Bash awk while read


Имеет большое количество файлов которые могут повторяться по содержимому и стоит задача оставить только уникальные файлы по содержимому. Для определения уникальности будем использовать контрольную сумму md5, а для автоматизации bash скрипт

#!/bin/bash

echo Чистка от дублей

x="" 

ls /tmp/base_1s-202* |sort  | while read f; do  
    _x=$(md5sum $f|awk '{print $1}')
    if [ $_x == "$x" ]; then 
        echo удаление $f  $_x
        rm $f 
    else 
        x=$_x
        echo сохранение $_x $f
    fi
done

 


11 октября 2023 13 октября 2023 Bash for read while git ls-files


Обычно я использую для обработки больлих списков следующую конструкцию
 

for x in $(git ls-files); do
du -sm "$x"
done

здесть создаётся локальная переменная в которой размещается результат операции find

Более оптимальная конструкция без использования локальной переменной через цикл while и read

git ls-files | while read x; 
do du -sm "$x"; 
done

 


11 октября 2023 13 октября 2023 Python url parse dict reduce


Однострочник для преобразования строки URL запроса в словь с данными ключ=значение

reduce(lambda a, x: {**a, **dict([x.split('=')])}, b.split('&'), dict())

Здесь три составные части, начнём с конца

python reduce parse url

dict() -  тут объявляется пустой словарь которые в будет пополняться результатами вычислений

request_body.split('&') - здесь тело строки запроса делится на лексемы состоящие из пары ключе/значение разделённых сиволом '='

lambda a, x: {**dict([x.split('=')]), **a} - здесь каждая лексема дробится по заделительному символу '=' добавляется в словарь соззданный в начале и возвращается результатом

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


09 октября 2023 Linux ubuntu 22.04 haproxy rsyslog logging


Недавно обнаружил, что современные на 2023 года Ubuntu не логируют работу Haproxy. Оказывается в них отсутствует и не настроен rsyslog

проверить можно вот так

apt-cache policy rsyslog

установить вот так

sudo apt-get install rsyslog

Затем необходимо настроить его для работы на 514 пору, для этого необходимо раскоментировать следующие настройки

egrep 'im(tcp|udp)' /etc/rsyslog.conf
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")

и перезапустить

service rsyslog restart

Затем проверить в /etc/haproxy/haproxy.cfg глобальную настройку
 

global
        log 127.0.0.1:514 local0

defaults
        log     global

и перезапустить haproxy

haproxy -c -V -f /etc/haproxy/haproxy.cfg && service haproxy reload

А так же подумать на счёт переноса haproxy  в отдельный контейнер


05 октября 2023 13 октября 2023 Bash array shuf random


На самом деле всё просто и выглядит вот так

echo {0..20} 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

shuf -e {0..20} | xargs 

14 6 12 19 5 8 20 10 3 15 1 16 13 7 9 4 2 0 11 17 18