Rose debug info
---------------

Принципы SOLID

Самая доходчивая по моему мнению статья по сабжу:

https://medium.com/webbdev/solid-4ffc018077da

У Роберта Мартина в «Чистой Архитектуре» SOLID посвящено 30 страниц, но примеры не такие живые. А всё дело в магии примеров.

 Нет комментариев    68   6 мес   SOLID

Как заглянуть внутрь запущенных виртуалок?

Однажды мне потребовалось заглянуть внутрь запущенных виртуалок и сделать это массово. Не разобравшись до конца, я просто смонтировал файловые системы внутри LVM-томов с ключиком ‐‐read-only.

В общем, мораль сегодняшней заметки будет в том, что никогда не стоит полагаться на очевидность чего-либо. Ключ ‐‐read-only команды mount действует не так как можно подумать, а с особенностями:

r, --read-only Mount the filesystem read-only. A synonym is -o ro. Note that, depending on the filesystem type, state and kernel behavior, the system may still write to the device. For example, ext3 and ext4 will replay the journal if the filesystem is dirty. To prevent this kind of write access, you may want to mount an ext3 or ext4 filesystem with the ro,noload mount options or set the block device itself to read-only mode, see the blockdev(8) command.

В общем, кончилась история печально — таким же массовым fsck на всех виртуалках. Естественно, с даунтаймом.

Как же сделать правильно?

В моём случае с дисками на LVM — нужно было сделать LVM-снэпшот. Это зафиксировало бы состояние диска и позволило безопасно монтировать его.

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

# strace -f -s 256 virt-cat -a ubuntu-20.04-amd64.qcow2 /etc/issue ... 40555 execve("/usr/bin/qemu-img", ["qemu-img", "create", "-f", "qcow2", "-o", "backing_file=/virt/ostemplates/ubuntu-20.04-amd64.qcow2", "/tmp/libguestfsFr51zn/overlay1.qcow2"], 0x564b53ad1970 /* 18 vars */) = 0 ...

Доверяй, но проверяй!

 Нет комментариев    53   6 мес   libguestfs   lvm   qcow2

Как обновлять уязвимые пакеты?

Давайте на примере текущей пачки уязвимостей в Exim разберёмся что со всем этим делать.

Как проверить версию установленного пакета

Первое с чего следует начать — посмотреть что именно у нас установлено в системе. Самый простой способ — посмотреть по списку установленных пакетов в целом.

Для Ubuntu/Debian:

dpkg -l | grep exim

Для CentOS:

rpm -qa | grep exim

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

Для Ubuntu/Debian:

dpkg-query --showformat='${Version}' --show exim4-base

Для CentOS:

rpm -q --queryformat "%{VERSION}" exim

Я узнал версию пакета? Можно ли только по ней понять уязвим ли пакет?

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

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

Например, в Ubuntu 18.04 используется exim версии 4.90.1. Значит ли, что все плохо, ведь разработчики exim закрыли уязвимости о которых мы говорим в более поздней версии 4.94.2?

Вовсе нет!

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

В нашем конкретном случае, в Ubuntu 18.04 exim версии 4.90.1-1ubuntu1.7 уязвим, а версии 4.90.1-1ubuntu1.8 — нет.

Как же тогда быть?

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

Пример бюллетеней для нашего кейса:

Из них следует, что исправленные версии:

  • Ubuntu 20.04: 4.93-13ubuntu1.5
  • Ubuntu 18.04: 4.90.1-1ubuntu1.8
  • Debian 9: 4.89-2+deb9u8
  • Debian 10: 4.92-8+deb10u6

А как же бюллетени для CentOS ?

Конечно, они есть в природе. Для RedHat они называются RHSA
Есть и для СentOS — они называются CESA

Проблема в нашем конкретном кейсе в том, что exim не входит в пакетную базу самого дистрибутива и ставится из стороннего, хоть и авторитетного репозитория EPEL. Поэтому обновления отслеживаем самостоятельно

Как обновить все пакеты в системе?

Одна из стратегий обновления — обновить в системе сразу все пакеты. К ней можно прибегать в следующих случаях:

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

Из плюсов полного обновления:

  • вы не пропускаете другие уязвимости, ведь за всем не уследишь
  • полное обновление системы как правило приводит к более консистентному результату

Для Ubuntu/Debian:

apt update && apt upgrade -y

Для CentOS:

yum update -y

Как обновлять пакеты неинтерактивно

Однако, если вы обновляете много машин, то, скорее всего вы хотите сделать это так, чтобы вам гарантированно не задавали вопросов. Ключ -y — это не спасение

В Ubuntu/Debian можно прибегнуть, например, к такому варианту:

export DEBIAN_FRONTEND=noninteractive
apt update -y \
&& apt-get -y -f install \
&& apt-get -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
upgrade

Как обновить только конкретный пакет(-ы)?

Если стратегия полного обновления вам не подходит, то можно воспользоваться следующими командами:

Для Ubuntu/Debian:

apt update && apt install -y --only-upgrade 'exim4-*'

Для CentOS:

yum update exim -y

Обратите внимание на то, что с помощью * можно использовать глобы, но не забывайте тогда заключать в кавычки имена пакетов.

Рестарт сервисов

И последнее по порядку, но не по важности.

Обновления пакетов через apt / yum чаще всего тригеррят рестарты соответствующих сервисов, но лучше всего полностью контроллировать ситуацию и сделать рестарт руками, например:

Для Ubuntu/Debian:

systemctl restart exim4.service

Для CentOS:

systemctl restart exim.service

Wireguard для доступа к LinkedIn

У моего провайдера заблокирован доступ к LinkedIn. В качестве решения я решил поднять свой VPN. Почему обязательно свой?

Используя бесплатные VPN-сервисы, вы подвергаете свои данные угрозе.

Пожалуйста, никогда не пользуйтесь бесплатными VPN-сервисами.

Открыл для себя wireguard и это, наверное, мой #1 сейчас благодаря простоте. С клиентами все замечательно, даже для макоси я без проблем нашёл магазине.

Инструкцию по установке писать не буду, так как одна прекрасная уже есть:

https://www.ckn.io/blog/2017/11/14/wireguard-vpn-typical-setup/

Есть только пара моментов на которые хочется обратить внимание:

  1. в Ubuntu 20.04 wireguard ставится из штатных репозиториев, поэтому нет нужды ставить из PPA
  2. установка unbound — излишня. Просто пропишите в конфиге клиента в качестве DNS-сервера 8.8.8.8

По требованиям — я рекомендую минимальный тариф START-0 на облачных серверах REG.RU, то есть 512 МБ RAM хватит за глаза.

local в bash подавляет ошибки

Писать скрипты на баше — это весёлое занятие. Никогда не знаешь, когда выползет рояль в кустах.

Сейчас, например, наткнулся на рояль, о котором, слава богу, был заранее предупреждён в «Bite Size Bash»

Давайте возьмём такую тестовую функцию, которая задаёт недопустимый режим вращения кулеров на платформе Supermicro. Режима 0x05 нет, поэтому ждём ошибку.

test_fan() {
    local _result
    if _result=$(ipmitool raw 0x30 0x45 0x01 0x05)
    then
        return 1
    fi
    echo "YES"
}

A=$(test_fan)
echo $?
echo "$A"

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

Здравый смысл подсказывает, что:

  • ipmitool свалится с ошибкой, плюнет ее в STDERR, и поднимет ненулевое значение в $?
  • дальше мы провалимся внутрь условия и вывалимся из функции с ошибкой
  • после вызова функции в $? мы поймаем 1, а значение $A вовсе будет пусто.

Как бы не так:

# ./test_fan_control
Unable to send RAW command (channel=0x0 netfn=0x30 lun=0x0 cmd=0x45 rsp=0xcc): Invalid data field in request
0
YES

А всё потому что в баше почему-то local подавляет все ошибки.

Уберём его и получим ожидаемое поведение:

# ./test_fan_control
Unable to send RAW command (channel=0x0 netfn=0x30 lun=0x0 cmd=0x45 rsp=0xcc): Invalid data field in request
1
Ранее Ctrl + ↓