Сетевые namespace’ы Linux, отдельные конфигурации для каждого namespace.

Это заметка от моего собственного склероза, потому что мелочи иногда забываю.
Для общей информации, что такое этот самый сетевой неймспейс. Это такая хитрая фиговина в ядре Linux, которая позволяет на одной машине с одной сетевой картой соединяться с сетью, будто у вас вагон и маленькая тележка этих сетевых карт (соответственно, куча локальных IP), можно, например, на одном неймспейсе поднять VPN до одного провайдера, на втором — до второго, на третьем — коннектиться к основному, и т.д.

Network namespace — это логически отделенный от других стек сетевых протоколов в Linux. Такая себе контейнерная виртуализация для сетевых интервейсов, когда chroot LXC и нужна виртуализация только сетевых интерфейсов. Эмулируется полностью сетевой стек: сетевые интерфейсы, таблица маршрутизации, файрволл и т.д. Так, как это работает на уровне ядра и для определенных процессов, то вполне можно получить рабочую конфигурации, когда на одной машине есть несколько сетевых интерфейсов с одинаковыми IP-адресами и ничто не конфликтует.
Хочу по этим штуковинам написать большой материал, как мы их у себя сконфигурировали и развели с одного сервера целый пул доступа к разным VPN-провайдерам, но руки не доходят. Поэтому да, заметка от склероза.

Каждому из нэймспейсов можно подсунуть свою конфигурацию сети, свои конфигурационные файлы (resolv.conf, hosts)

Для этого достаточно положить соответствующие файлы в директорию /etc/netns/имя_namespace, например, для гипотетического namespace с именем riseupvpnns это будет каталог /etc/netns/riseupvpnns, туда можно положить, например, resolv.conf, прописать необходимые DNS, и эта конфигурация будет влиять только на данный namespace, в независимости, что там в основной системе прописано.

Linux, curl, обнаружение и анализ ошибок HTTP. Улучшаем скрипт.

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

Клиент может не знать все коды состояния, но он обязан отреагировать в соответствии с классом кода. В настоящее время выделено пять классов кодов состояния.

Т.е. объясняя по рабоче-крестьянски, не только код 200 может свидетельствовать об успешном завершении запроса, а другие коды, кроме явных клиентских или серверных ошибок, могут требовать от нас каких-либо действий.

Вообще, коды ответа HTTP разделены на 5 классов:
1xx — информационные
2xx — успешное завершение
3xx — требуется переопределение
4xx — ошибка, допущенная со стороны клиента
5xx — ошибка, допущенная со стороны сервера

Вот и модифицируем наш скрипт в соответствии со стандартом.
В общем, надо из кода ответа HTTP извлечь первую цифру, и, соответственно прореагировать. Привожу часть скрипта, ответственного за более подробную реакцию на код ответа HTTP:

curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null
EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then
    echo "CURL error $EXITCODE"
else
    HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'` #get HTTP status code
    HTTPSTATUSMESS=`cat $HEADERDUMP|head -1|cut -d '  ' -f 3-
    HTTPSTATUSID=`echo $HTTPSTATUS|cut -c 1` #get first char status code
    
    case "$HTTPSTATUSID" in
	1 ) echo -n "Informational: ";;
	2 ) echo -n "Success: ";;
	3 ) echo -n "Redirection: ";;
	4 ) echo -n "Client Error: ";;
	5 ) echo -n "Server Error: ";;
	* ) echo -n "Unknow status: ";;
    esac
    
    echo "$HTTPSTATUS $HTTPSTATUSMESS"
fi


Жирным шрифтом выделена строка, в которой мы получаем этот самый класс кода возврата.

Курсивом — строка, где мы получаем пояснения текстовые пояснения к коду ответа.

Используемая в процессе анализа утилита cut, в первом случае, позволяет нам вывести в переменную все символы после с третьего пробела.
Перед первым у нас версия протокола http, потом код ошибки, а потом пояснение, которое может содержать несколько пробелов, поэтому awk тут не подходит.
cut так же может работать с текстовыми данными, в которых есть разделители, например пробелы, или же с отдельными символами, как в той строке кода, что выделена жирным — так мы можем извлечь первую цифру из кода ответа.

Дальнейший анализ осуществляется с помощью оператора case

Пример работы

Скрипты

Расширенный анализ кодов состояния HTTP:
На Pastebin
На Github

PHP скрипт для проверки:
На Pastebin
На Github

Дополнительные источники

Краткий справочник по командам curl и wget Копия
Утилита cut
Коды статуса HTTP
Оператор case

Начало

curl в Linux, ошибка 404, обнаружение и использование кодов ответа HTTP

Итак, возникла следующая задача — определить, когда curl получил вменяемые данные от http-сервера, а когда нет. В общем, и самом распространенном случае, задача сводится к тому, чтобы определить, отдал ли нам сервер запрашиваемый файл, или отобразил «страница не найдена».

Впрочем, это работает и для других возможных кодов ответа.

Ясно, что сервер, на наш запрос GET может ответить, как возвратив нам запрашиваемую страницу, так и отправив код, например, 404 (не найдено), и возвратив страницу-заглушку для этого случая. Так вот, на уровне скрипта bash или скрипта php необходимо проанализировать ответ сервера, чтобы не выдать пользователю вместо ожидаемых данных, всяческую лабуду. Далее я рассматриваю исключительно консольную Linux-утилиту curl. Для php, синтаксис, по-моему, отличается.

Есть страница, которую мы хотим получить: http://example.org/page.html, сохранить ее в файл page.html и есть curl, команда будет такая:

curl -o "page.html" http://example.org/page.html

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

Как же быть:

Проверяем код ошибки самого curl, если нет связи с сетью, URL неправильный, или задан неподдерживаемый curl протокол, если так, то мы получим соответствующий код возврата, наподобие:

curl: (1) Protocol htt not supported or disabled in libcurl

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

Надо получить код ответа HTTP!

Сделать это можно, если получить отдельно заголовки ответа сервера, и после их проанализировать. Благо, для этого никакого страшного колдунства не требуется, достаточно указать утилите curl опцию -D (т.е. dump) и файл, куда выгружать заголовки.

Покажу это на примере конкретного скрипта:

#!/bin/bash

HEADERDUMP="/tmp/headerdump.txt"
SAVEFILE="/tmp/httpfile"
HTTPSTATUS=""

curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null
EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then
    echo "CURL error $EXITCODE"
else
    HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`
    
    if [ "$HTTPSTATUS" == "200" ];then
	echo "OK"
    else
	echo "HTTP error $HTTPSTATUS"
    fi
fi

заводим 3 переменные

HEADERDUMP="/tmp/headerdump.txt" — файл, в который будем получать заголовки
SAVEFILE="/tmp/httpfile" — файл с сервера, который мы хотим получить
HTTPSTATUS="" — переменная для статуса (состояния) HTTP

curl -o $SAVEFILE $1 -D $HEADERDUM

пытаемся скачать нужный файл (получить страницу):
-o «имя_файла» — куда сохранять результат
$1 — внутренняя переменная, первый параметр скрипта, при вызове его с командной строки. В своем скрипте надо заменить на свой случай.
можно добавить >/dev/null 2>/dev/null — для красоты, чтоб не вылезали сообщения о процессе и ошибках.

-D <файл> — файл, куда будем копировать заголовки

Файл headerdump.txt выглядит примерно так:

HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Fri, 30 Mar 2018 00:17:23 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.33
Link: ; rel="https://api.w.org/"
Set-Cookie: quick_chat_alias=Anon_240883; path=/
Upgrade: h2,h2c
Vary: Accept-Encoding,User-Agent

В первой строке — интересующая нас информация. Версия протокола (не интересно), код ответа (вот он) и информационное сообщение (не особо надо).

Вычленяем код:

HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`

1. Берем первую строчку (head -1)
2. Сохраняем в переменную 2-е значение после пробела (разделитель пробел): awk '{print $2}'

Дальше можно анализировать:

    if [ "$HTTPSTATUS" == "200" ];then
	echo "OK"
    else
	echo "HTTP error $HTTPSTATUS"
    fi

Результат

Также, впрочем, можно поступить и для анализа запросов POST, вот тестовый скрипт php для отладки подобных возможностей и скрипт bash

Скачать

Пример с запросом GET
Пример с запросом GET на Гитхаб

Пример с запросом POST
Пример с запросом POST на Гитхаб

Тестовый php скрипт для запроса POST
На Гитхаб

Скачать одним архивом

PC-speaker в Linux, или как сделать beep из консоли встроенным динамиком ПК

Еще со времен DOS можно было свистеть, гудеть и пикать встроенным динамиком компьютера, и даже симфонии играть. Сейчас это особо не нужно, ибо везде звуковые карты, динамики и прочая мультимедия. Но иногда PC-speaker нужная и полезная вещь, способная сигнализировать о чем либо, например, о разрыве соединения с Интернетом на домашнем сервере, к которому не подключен монитор, или о том, что торрент докачался. Да и вообще, способов, как можно применить спикер — множество. Даже симфонии можно играть.

Включение динамика

Зачастую, PC-speaker в линуксе отключен, точнее, не загружен модуль ядра, который им управляет. Обычно это модуль pcspkr, хотя, в некоторых источниках написано, что может быть и другой модуль snd-pcsp. У меня оказался первый.
Проверить, загружен ли соответствующий модуль ядра можно командами
lsmod |grep pcspkr и lsmod |grep snd-pcsp соответственно.
Если команда ничего не выдала, то модуль не загружен.
Если выдала что-то похожее, значит, модуль загружен:

>lsmod |grep pcspkr
pcspkr                  1448  0

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

modprobe pcspkr
или
modprobe snd-pcsp

Если команда не выдала ошибки, модуль загружен. Можно проверить с помощью команды lsmod. Если случилась ошибка, то печально. Модуль, скорее всего, придется собирать. Ну, или не так печально, а даже наоборот — модуль встроен в ядро, и PC-speaker по умолчанию включен. Попробуйте простой beep.

Простой beep

Для простого beep достаточно отправить на консоль символ с кодом 007, ASCII-символ BEL

echo -ne '\007'

Способ может не сработать из SSH-терминала, либо из терминала X. Терминал SSH «булькнет» не на удаленном компьютере, а на локальном, а X-server может перенаправить beep на колонки, вместо PC-speaker’a

Утилита beep

Простые звуки и даже целые мелодии можно играть на спикере утилитой beep.
На рабочей машине она уже была в комплекте ОС, на Ubuntu ее можно установить командой apt-get install beep, а в Slackware она ставится через Sbopkg
Проект имеется на Github, можно собрать и из исходников

Примеры вызова:

bell

Без параметров издаст стандартный beep

bell -f 500 -l 1000

Выдаст звук частотой 500 Гц, продолжительностью 1 секунду (1000 миллисекунд)

Пример скрипта, играющего тему Die Gedanken Sind Frei из ролика в начале заметки.

Ссылки

Больше мелодий и ссылок на готовые скрипты Копия
How do I make my pc speaker beep. Еще больше про то, как можно пискнуть спикером.

Beep Music Demo или мелодии на PC-Speaker

С помощью утилиты beep под Linux


Прямая ссылка
Скачать скрипты


Прямая ссылка
Скачать скрипты


Прямая ссылка
Скачать скрипты


Прямая ссылка
Скачать скрипты

Скачать весь архив
Скрипты взяты отсюда

Бесплатный VPN от riseup.net. Часть 3.

Настройка на другом компьютере с Linux

Как следует из ранее изложенного, ничего сверхъестественного не обнаружилось, и для того, чтобы воспользоваться этим VPN, требовательный к железу Debian 9 x64 не нужен совершенно. Bitmask тоже не нужен. Проблемы могут возникнуть разве что с виндой, а вот с линуксов вполне можно раздавать VPN-интернет на другие устройства в локальной сети, в т.ч. и на виндовые компьютеры. Без bitmask это даже лучше получается, поскольку он пакостит в iptables. Пакостит, правда, для «более лучшей» защиты пользователя. Но в данном случае получается, как у Черномырдина — хотели как лучше, получилось как всегда.

Конфигурация Openvpn

Первым делом надо составить конфиг для Openvpn. Не буду каждый параметр пояснять, а ссылка на сами конфиги есть в конце заметки. Вроде составил правильно, по ранее извлеченным параметрам Openvpn. Единственное что добавил от себя, это запуск пользовательских скриптов — параметры script-security 2, разрешающий оный запуск, и параметры up '/путь/к/скрипту up' и down '/путь/к/скрипту down', указывающие Openvpn, какой скрипт надо запускать при, соответственно, установке и разрыве соединения.

Про подобные скрипты я совсем недавно упоминал.

Сертификаты

Получены в прошлой части.

Пользовательский скрипт настройки соединения.

Переделывался из ранее приведенного примера с небольшими изменениями:

#!/bin/bash

#заводим человеческие переменные

MAIN_STAT=$1 #up/down
DEV_NAME=$2
TUN_MTU=$3
LINK_MTU=$4
LOCAL_IP=$5
REMOTE_IP=$6
ADD_STAT=$7 #init/restart

#путь к ip и iptables
ACPATH="/usr/sbin/"

# [...]

#соединение поднялось
if [ "$MAIN_STAT" = "up" ]; then
	#установка маршрута по умолчанию
    "$ACPATH"ip route del default #удаление старого
	#установка нового
	#именно так, локальный ip и удаленный - один и тот же
	#особенность провайдера Oo
    "$ACPATH"ip route add default via $LOCAL_IP dev $DEV_NAME src $LOCAL_IP
    
     #разрешение транзитного трафика
	"$ACPATH"iptables -P FORWARD ACCEPT
    
    #установка адреса DNS-сервера
    echo "nameserver 10.42.0.1">/etc/resolv.conf
    exit
fi

#соединение разорвано
if [ "$MAIN_STAT" = "down" ]; then
    #запрет транзитного трафика
    "$ACPATH"iptables -P FORWARD DROP 
    #установка маршрута по умолчанию без VPN
	"$ACPATH"ip route del default
    "$ACPATH"ip route add default via 10.10.1.1 dev eth1 src 10.10.20.55
    
    #восстанавление адресов DNS по умолчанию
    echo "nameserver 8.8.8.8">/etc/resolv.conf
    echo "nameserver 8.8.4.4">>/etc/resolv.conf
fi

Основная особенность в том, что сервер, вместо REMOTE_IP, передает маску подсети, а чтобы маршрутизация осуществлялась правильно, вместо удаленного IP надо прописать выданный сервером локальный.

Долго с этим разбирался, т.к. поначалу был глюк — транзитный трафик проходил, а вот локальный нет. Помог выхлоп ifconfig:

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.42.0.2 netmask 255.255.248.0 destination 10.42.0.2
inet6 2001:db8:123::1000 prefixlen 64 scopeid 0x0
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)
RX packets 982346 bytes 1307345786 (1.2 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 541554 bytes 27027659 (25.7 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

Вторая важная особенность — надо прописать правильный DNS.
И не забыть передать его клиентам, если компьютер используется в качестве PPTP- или другого VPN-сервера.

ЗЫ. Если будете пользоваться сервисом riseup.net, по возможности донатьте, хорошее дело ребята делают. Фиг где в мире встретишь таких альтруистов.

Ссылки

Предыдущие части заметки

Часть 1. копия
Часть 2. копия
Скачать все в PDF

Конфиги

На моем сайте копия

На PasteBin:
Голландия
Канада
США

Скачать с Mega.nz

Скрипт настройки сети

На PasteBin
Скачать с Mega.nz

Riseup

http://riseup.net
Регистрация Riseup Black
О Riseup
Донат

Bitmask

http://bitmask.net
http://leap.se

Загрузка Puppy Slacko по сети

Puppy по сети грузится, но с некоторыми проблемами. А именно, для полноценной загрузки ОС требуется файл puppy_slacko_X.X.sfs, содержащий основные файлы ОС.
Этот файл сам по себе по сети не подгружается. Можно, конечно, подшаманить в initrd и сделать так, чтоб файл подтягивался по tftp или с расшаренной папки, но это довольно нетривиально.
Есть другой способ — записать в initrd главный sfs. Правда, initrd раздуется от этого (аж до 150 Мб с гаком) и на совсем слабых машинах Slacko не загрузится. Но 512 Мб оперативки вполне хватает. Тестировано на селероне 1.7 с 512 Мб ОП.

Мы нашли на murga-linux скрипт, который автоматизирует данный процесс. Ссылки на оригинал не будет, т.к. никто уже не помнит, где качали. 🙂

Скрипт на PasteBin
Скачать с Mega.nz

Бесплатный VPN от riseup.net. Часть 2.

Получение данных для нормального запуска VPN, без bitmask и на любом линуксе.

Подготовка

1. Ставим Debian x64. Я ставил 8.10 на виртуалку в VMWare 9 с netinst установщика, при установке можно выбрать LXDE, чтоб быстрее поставилось и тянуло меньше ерунды с инета.

2. Заходим в консоль и переключаемся под root
su

3. Обновляем списки пакетов после установки (из консоли)
apt update

4. Для удобства можно поставить mc
apt install mc

4. Ставим Openvpn
apt install openvpn

5. Качаем Bitmask (bundle-версию) отсюда копия на всякий случай и распаковываем его в отдельный каталог в пользовательской директории.

Регистрация

Первый вариант, на сайте https://riseup.net. Переходим по ссылке, придумываем имя пользователя и пароль.

Вариант второй — через Bitmask под катом:
Регистрация успешна, теперь надо получить данные для использования VPN

Глюки и зависания Bitmask

Bitmask оказался каким-то нестабильным и висючим, периодически при запуске делая бочку:

Отчего он так себя вел, непонятно совершенно. Лечилось либо убийством с помощью pkill и последующим перезапуском, либо запуском через консоль и двойным Ctrl+C (на одиночный он прячется в трей), или удалением каталога программы и каталога .config/leap из домашней директории. Накрайняк была копия HDD виртуалки.

Получение сертификатов VPN

Запускаем bitmask, вводим логин (в виде login@riseup.net) и пароль, логинимся и попадаем в главное окно, или если через bitmask и регистрировались, то сразу попадаем в главное окно, можно даже не пытаться соединиться, сертификаты уже получены.

При первом запуске с ранее зарегистрированным через сайт логином и без заранее добавленного в bitmask провайдера riseup.net может возникнуть следующая картина

Жмем Install Helper Files, после чего несколько раз будет запрошен пароль root, после чего можно нажать кнопку Trun ON
По началу у меня все очень долго соединялось, я так и не дождался. Но на момент написания данного текста все заработало сразу же, я так понял, товарищи из Riseup починили голландский сервер, висевший до этого пару дней.

Нужные сертификаты лежат в домашнем каталоге пользователя:
/home/username/.config/leap/providers/riseup.net/keys/ca/cacert.pem
/home/username/.config/leap/providers/riseup.net/keys/client/openvpn.pem

Получение параметров Openvpn.

Bitmask, как выяснилось, фактически навороченная обертка над Openvpn. Соединением VPN управляет именно он. А параметры можно получить независимо от того, удалось ли соединиться с помощью bitmask, или bitmask долго думает над соединением, например, из-за какого-нибудь одного зависшего сервера. Откроем консоль и посмотрим:

ps -Af|grep openvpn

Ага! Вот и все нужные нам параметры, из которых вполне можно сделать конфиг для Openvpn:

nobody 2934 2515 0 05:27 ? 00:00:00 /usr/sbin/openvpn --setenv LEAPOPENVPN 1 --nobind --client --dev tun --tls-client --remote-cert-tls server --management-signal --script-security 1 --user nobody --persist-key --persist-local-ip --persist-remote-ip --group nogroup --verb 1 --remote 5.79.86.180 443 udp --remote 199.58.81.145 443 udp --remote 198.252.153.28 443 udp --tls-cipher DHE-RSA-AES128-SHA --cipher AES-128-CBC --auth SHA1 --keepalive 10 30 --management-client-user kvakushka --management /tmp/leap-tmpzK6zDA/openvpn.socket unix --ca /home/kvakushka/.config/leap/providers/riseup.net/keys/ca/cacert.pem --cert /home/kvakushka/.config/leap/providers/riseup.net/keys/client/openvpn.pem --key /home/kvakushka/.config/leap/providers/riseup.net/keys/client/openvpn.pem
kvakush+ 9906 2676 0 05:56 pts/3 00:00:00 grep openvpn

Ссылка на готовые конфиги копия

DNS-сервер

Этот VPN использует свой локальный DNS-сервер, дабы данные клиента не уходили к его провайдеру или, например, корпорации добра. IP можно подсмотреть в скрипте bitmask-root в каталоге с bundle bitmask’а в директории apps/helpers

NAMESERVER = "10.42.0.1"

В общем, сохраняем параметры Openvpn в текстовый файл, запоминаем адрес DNS-сервера, копируем на флэшку или закидываем в облако сертификаты, и можно настраивать данный VPN на любом другом компьютере. Но Bitmask или вообще жесткий диск виртуалки, советую куда-нибудь забэкапить. Он может потребоваться в будущем для обновления сертификатов. Как их выковырнуть вручную я, пока что, недопетрил, а Riseup периодически сертификаты обновляет.

Начало

Продолжение следует…

Бесплатный VPN от riseup.net

Бесплатный, довольно быстрый, но не без геморроя. Иначе не было бы смысла о нем писать.

Немного о сервисе

Сервис надежный в плане безопасности и защиты приваси от всяких нехороших дядек в погонах и пиджаках, ибо основан политическими активистами анархического толка для таких же политических активистов. Причем основан, аж в 1999 году во время протестов против ВТО в Сиэтле и с тех пор работает на благо человечества.
Кроме VPN Riseup также предоставляет защищенную электронную почту и обслуживает новостные рассылки для активистов.
Подробнее можно почитать на официальном сайте https://riseup.net/ru/about-us

VPN-сервис

Фактически, сервисов даже два. Riseup Red, включающий в себя кроме VPN, электронную почту и XMPP. VPN Red-сервиса настраивается просто и его можно без особых проблем использовать на любом устройстве. Достаточно зарегистрироваться, скачать конфиг и поставить OpenVPN. Но вот с регистрацией проблема, нужен либо инвайт от зарегистрированного пользователя, либо написать администрации, объяснив, зачем тебе их VPN и какой конкретно деятельностью ты занимаешься. Со знакомыми анархами, у которых была регистрация на Riseup, мы давно всякие контакты потеряли. Искать инвайты, или же просить админов, это, во-первых, лишнее общение с живыми людьми, а, во-вторых, х.з., дадут или нет. Нарвешься еще на как[-ого/-ую/-ое]-нибудь SJW, радикальную феминистку, веганского прозелита, или неадекватного антифа, который фашистов видит только что не в своем шкафу, и хрен тебе, а не инвайт. Хотя, среди админов, поговаривают, неадекватных нет, но зачем людей от работы отвлекать.
Есть еще один сервис Riseup Black, предоставляющий пока только VPN, но обещают и электронную почту со сквозным шифрованием в ближайшем будущем. На Riseup Red регистрация без инвайтов и даже без указания электронной почты Безопасность же и политика непередачи данных третьим лицам в виде злобных корпораций и не менее злобной гебни. Зарегистрироваться можно либо на сайте, либо через приложение Bitmask, которое и обеспечивает VPN-соединение, что рекоменовано. Вот в Bitmask и была целая песцовая нора…

VPN с Bitmask’ом и раздолбайством

Хоть вроде нам обещали доступность, анархичность, всемирное счастье и прочий мир, труд, май и благорастворение воздухов, все оказалось совсем не так радужно.
Юзерам винды не повезло вообще — версии клиента под форточки нет в природе, только обещание, что «скоро будет». Есть версии под Mac и Android, но по их поводу ничего сказать не могу, у нас нет их. Кто отпишется, тому печенька.
Версия под Linux, слава Ктулху, была, и это по началу обнадежило. И даже есть дистрибутивы bundle. Т.е. «портабельные», распаковал на флэшку и забыл о пакетах, зависимостях и установках. Но не тут-то было! В ходе непродолжительного исследования выяснилось, что Bitmask больше напоминает разработанную инопланетянами скороварку, чем программу под линуксы. «Из коробки» и корректно эта фиговина работает только на астероиде с определенной гравитацией, атмосферным давлением, и только в первую субботу после полнолуния, когда Венера в Козероге. Да и то не уверен, потому что когда понял, какой дистрибьютив официально ™ поддерживается, уже сделал так, чтоб поддерживалось везде, кроме винды. Во всяком случае, с VPN оно соединяет.

Очевидные гадости:
— приложение только под 64-разрядные ОС
— только под Убунту и Дебиан
— нифига не под все Убунты и Дебианы

Неочевидные гадости, или о раздолбайстве:
— на сайте bitmask’а нагло врут, что есть x32 версии, ссылки на bundle ведут на страницу 404, пакетов в репозиториях тоже нет, либо есть не все, либо «не подходит к гробу крышка»
— перечислены версии убунт и дебианов, которые поддерживаются. И даже приведены команды для подключения соответствующих репозиториев. Но опять та же история, то пакетов нет, или есть не все, то в команде что-то указано неправильно.
Когда, путем научного тыка, вдумчивого чтения существующих путей к репозиториям, лазания по аж двум официальным сайтам (bitmask.net и leap.se), на которых написаны совершенно разные вещи, было выяснено, что из коробки поддерживается только Debian Stretch x64 и Ubuntu 17.04, то проверять это «за ради проверки» расхотелось. Хотите — проверяйте сами.

В общем такая вот дискриминация, ложь, пиздежь и провокация, со стороны разработчиков Bitmask по отношению к пользователям других дистрибьютивов линукса, и даже к дебианщикам/убунтоводам, уж не говоря про обладателей устройств с процессорами x32.

Конечно, сейчас набегут всякие погромисты и прочие неравнодушные с криками «ну кот жи аткрыд, перепейшы1111», но дело ведь в том, что можно хотя бы везде на своих сайтах написать — «наша софтина работает только там-то, там-то и там-то, а остального мы не гарантируем» и все. А то в результате получается ситуация, когда пользователь читает, что на сайте написано, пробует у себя, оно не работает (хотя знают, что не работает, только разработчики), и так и сяк не работает, и пользователь приходит к выводу, что опенсурс (линукс, дебиан, убунта, нужное подчеркнуть) говно. И никакого равенства, братства и благорастворения воздухов.

Впрочем, сие ворчание распространяется только на горе-разработчиков Bitmask и к команде Riseup никак не относится. Хочешь VPN без геморроя, проси инвайт, или у админов, секурного VPN на всех не напасешься, тем более не напасешься на потенциальных политических противников.

Ладно, поговорили и хватит, пора расколдовать принцессу.

Еще немного бормотологии

Для того, чтобы решить задачу, мне все таки пришлось на время одолжить более мощный ПК, правда с 32-разрядной виндой и запретом ее сносить. Оказалось, что VMWare Workstation даже на хосте с 32-разрядной XP вполне смогла запустить в качестве гостевой ОС 64-разрядный Debian 8.10

Продолжение

OPENVPN: Запуск в фоновом режиме, настройка маршрутизации, фаервола и другие мелочи

Бредистория

Год назад, может раньше, по совету товарищей, я переполз с PPTP VPN на Openvpn. За это время узнал несколько хинтов, которые, периодически нужны либо по работе, либо кому-нибудь.
Эталонный конфиг, который буду модифицировать, лежит здесь

Проблема с установкой, требует модуль PAM

Windows: не актуально
Linux: да
Решение:
Собрать из исходников, предварительно переконфигурировав командой
./configure --disable-plugin-auth-pam

Автоматический ввод пароля

Windows: да
Linux: да, за исключением старых версий, которые приходилось пересобирать со специальным ключом. Если вдруг такое попалось, то обновить.
Решение:
В конфиг соединения надо добавить строку auth-user-pass /path/to/auth/file
где
/path/to/auth/ — путь к файлу авторизации
file — имя файла
Для Windows будет что-то типа C:\path\to\file.txt

Файл авторизации — простой текстовый файл в котором содержатся две строки: первая — логин, вторая — пароль:

содержимое файла file:
username
pa$$w05D

Запуск в фоновом режиме

Windows: не актуально
Linux: да
Решение:
В конфиг соединения надо добавить строку daemon

Выполнение пользовательских скриптов

Windows: не актуально, во всяком случае, мне не встречалось
Linux: да
Для чего надо: например, для того, чтобы при установке/разрыве соединения, настроить маршрутизацию или iptables (фаерволл)

Решение:
1. Надо разрешить Openvpn выполнять пользовательские скрипты, добавив в конфиг следующую строку:

script-security 2

2. Прописать путь к скрипту в одном или нескольких нужных параметров конфига, например:

up '/home/kvakushka/scripts/ovpn-routes up'
down '/home/kvakushka/scripts/ovpn-routes down'

Вообще, таких параметров довольно много, почти на все случаи жизни:
down <command> — выполнить команду когда интерфейс TUN/TAP выключится.
up-restart <command> — выполнить команду после каждого реконнекта
route-up <command> — выполнить команду после установки сетевых маршрутов.
up-delay <seconds> — подождать установленное количество секунд перед запуском команды указанной в up. Пример: up-delay 120
down-pre <command> — выполнить команду перед тем, как интерфейс TUN/TAP выключится.
up <command>— выполнить команду после запуска устройства TUN/TAP.
ipchange <command> — выполнить команду, если ip сервера изменился.
client-connect <command> — выполнить команду, после того, как клиент подключился.
client-disconnect <command> — выполнить команду, после того, как клиент отключился.
learn-address <command> — выполнить указанную команду, если IP удаленной стороны стал другим.

Надо уточнить, что скриптам up и down Openvpn передает параметры командной строки, несущие информацию о соединении:

[1..N]: Параметры, указанные пользователем в конфигурационном файле, т.е. в вышеприведенном примере, скрипту ovpn-routes при вызове после того, как поднимется тоннель, будет передано первым параметром «up«, а при разрыве соединения — «down«.
Очень полезный горшочек, позволяющий в одном скрипте обрабатывать несколько событий.
[2]: Имя сетевого устройства (тоннеля). Например, tun0
[3]: MTU сетевого интерфейса
[4]: MTU соединения
Можно использовать для сложной маршрутизации между несколькими каналами и поиска более выгодного маршрута.
[5]: IP-адрес клиента
[6]: IP-адрес клиента на стороне сервера
[7]: init, если скрипт был вызван во время запуска/останова Openvpn или restart, если скрипт был вызван при перезапуске (обрыве соединения, например).

Пример скрипта

#!/bin/bash

#заводим переменные с понятными именами
MAIN_STAT=$1 #up/down
DEV_NAME=$2
TUN_MTU=$3
LINK_MTU=$4
LOCAL_IP=$5
REMOTE_IP=$6
ADD_STAT=$7 #init/restart

#директория с iptables и ip
ACPATH="/usr/sbin/"

# [...]

#скрипт вызван при поднятии тоннеля
if [ "$MAIN_STAT" = "up" ]; then
     #установка маршрута по умолчанию для VPN
    "$ACPATH"ip route del default
    "$ACPATH"ip route add default via $REMOTE_IP dev $DEV_NAME src $LOCAL_IP
     #настройка IPTABLES
     #разрешение транзитного трафика
    "$ACPATH"iptables -P FORWARD ACCEPT
    exit
fi

#скрипт вызван при отключении тоннеля
if [ "$MAIN_STAT" = "down" ]; then 
    #запрет транзитного трафика 
    "$ACPATH"iptables -P FORWARD DROP
   #установка маршрута по умолчанию без VPN
    "$ACPATH"ip route del default
    "$ACPATH"ip route add default via 10.10.1.1 dev eth1 src 10.10.20.55
fi

В примере настраивается маршрут по умолчанию, для случая соединения через VPN и напрямую, а также отключается транзитный трафик, если соединение идет не через VPN.

Пример модифицированного конфига соединения Openvpn
Скрипт ovpn-routes

Источники

1. Основные команды и параметры OpenVPN Копия
2. Установка и настройка клиента OpenVPN в Ubuntu Копия

Установка Windows 7 с жесткого диска

Бредистория

Или сраный интеловский чипсет. В общем, вызвали меня на заказ, поставили задачу — десятку убить, семерку вкрутить. Беру верную флешку с YUMI, на которой есть образ Acronis Disk Durector, всякого рода винды и линуксы, нужные для эникейной работы, и начинаю.

Снес я Windows 10, убил б-гмерзкое GPT, переделил диск, вставляю флешку с установщиком Win 7, но не выходит каменный цветок, посылает меня установщик Windows 7 за Cdrom drivers, иначе говоря, Windows 7 просит драйверы CD-ROM.

Непорядок, подумал я, ибо CD-ROM даже в проекте не было. Легкое гугление дало ответ, Windows 7 не поддерживает USB 3.0 искаробки. Гейц с ним, включаю в BIOS режим совместимости USB. Линуксы и флешку и hdd видят, акронис тоже, а вот инсталлятор Windows 7 — хрен.

В общем думал я, думал, и таки нашел способ поставить Win7 с жесткого диска, хотя кучу времени зря потратил на добавление драйверов USB, различную греблю с перетыканием флешек и прочей фигней, есть же способ гораздо проще…

Что надо

1. Две флешки. На одну кладем любимую «форматилку», он же менеджер дисков и Hiren’s Boot CD. Вообще весь HBCD нам тут нахрен не нужен, можно обойтись вырезкой из сабжа.
2. Чуть не забыл, нужен еще какой-нибудь легковесный Linux. Я в конкретном случае использовал Puppy Linux.
3. Флешка 2, на которой или образ установочного диска Win7, или уже подготовленный для загрузки с флешки установщик. В моем случае, был вариант 2, заранее подготовленный с помощью rufus
4. Достаточное дисковое пространство. В моем распоряжении был аж терабайтный винт, хотя описываемый ход котом можно повторить даже на 50-гигабайтном IDE-HDD, буде он в такой конфигурации железа окажется.

Что делаем

1. Делаем разделы диска, как нам угодно. Например, я сделал логический диск D: для файлов пользователя, на 700 Гб, в конце диска, и оставил область в 300 Гб в начале неразмеченной. Установщик Win 7 сам ее потом разметит, положит файлы ОС на будущий диск C: и создаст свой загрузчик на отдельном разделе 'Зарезервировано системой', размером 100 Мб

2. Делаем с помощью любимого менеджера дисков, логический раздел для установщика Windows 7, размер варьируется, от 5 до 8 Гб, но лучше сделать 8. Формат (файловая система) раздела NTFS или FAT32, последнее предпочтительнее.

3. Загружаемся в Linux, и если вы последовали совету использовать Puppy, то все будет «какввенде» — рабочий стол, ряд дисков ниже, флешка с виндой с иконкой флешки. Жаль, не могу заснять видео, машину уже унесли

4. Копируем файлы с флешки с установщиком Windows на созданный раздел. Файлы скопировать просто: открываем флешку, кликая по ней 1 раз, открываем нужный диск (аналогично), переключаемся в окно с открытой флешкой, нажимаем CTRL+A, выделяя все в окне, и мышкой перетаскиваем в соседнее окно, где открт нужный раздел

5. Осталось перезагрузиться с загрузочной флешки, и выбрать пункт меню Boot From Hard Drive (Windows Vista/7/2008 or Xp), если вы грузитесь через PXE или с установленного на YUMI HBCD, или последовательно выбрать Boot Windows (XP/2003/2008/Vista/7) From Local HDD а только потом Boot From Hard Drive (Windows Vista/7/2008 or Xp)

Если все сделано верно, то Grub4DOS найдет bootmgr, а тот запустит установщик Windows 7.

Останется установщику указать неразмеченную область диска для установки.

Потом раздел с установщиком можно снести и объединить его с диском C: или D:.

Как-то так, прошу прощения, что без скриншотов и видео, пациента уже выписали.

Утилита для PXE или загрузочной флешки, запускающая Windows с локального жесткого диска.

А нахрена он нам?

Спросит вдумчивый читатель. И будет прав.

Отвечу на это:
1. Да чтобы запустить локальную Windows, если, например, слетел к чертям собачьим MBR, оригинального диска с виндой под руками нет, а зайти смерть, как надо, и именно в локальную винду.
2. Чтобы запустить установку Windows 7 (а может быть и 8, а может быть и 10, а может быть ворона, я не проверял) с локального жесткого диска. А вот зачем это — расскажу позднее.

Как сделано

1. Использован образ DOS, взятый отсюда
2. Подправлен AUTOEXEC.BAT
3. Добавлен Grub4DOS, причем особо не заморачиваясь, утащен с мультизагрузочной флешки, созданной YUMI
4. Подправлен menu.lst также нагло спертый из Hiren’s boot CD
5. Создана ISO-версия этого безобразия, по вот этому рецепту

Скачать

Готовый образ
Готовый образ, сжатый gzip
ISO-образ

Примечание

Вообще я использовал для работы оригинальный HBCD, а эта штуковина, хоть и сделана «по мотивам», но в реальных условиях не тестировалась. Только на тестовой виртуальной машине, так что юзайте на свой страх, риск и хвост, и оставляйте комментарии, ежели любо, или же не любо и в чем конкретно

Анализ древней дискеты AVP Z.E.S Linux. Скрипты на закуску.

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

Разборка оригинального bootdisk.img и подключение ramdisk’а

#!/bin/bash

RDMP="/mnt/ramzes"
LDRKRNLPATH="./ldrkrnl/"
LDRKRNLNAME="ldrkrnl.img"

echo "Making dirs"
mkdir $RDPATH
mkdir $RDMP
mkdir $LDRKRNLPATH

echo "Extracting RAMDISK..."
dd bs=1 if=$IMGPATH of=$RDPATH$RDGZNAME skip=464896

echo "Extracting loader and kernel"
dd bs=1 if=$IMGPATH of=$LDRKRNLPATH$LDRKRNLNAME count=464896

echo "Unpacking RAMDISK..."
cd $RDPATH
gzip -d $RDGZNAME
cd ..

echo "Mount RAMDISK"
mount -o loop $RDPATH$RDNAME $RDMP

Удаление AVP

#!/bin/bash

RDMP="/mnt/ramzes"

echo "Remove AVP"

cd $RDMP

cd root/.AVP
rm *
cd ..
rmdir .AVP
rm $RDMP"/usr/bin/AVPLinux"

cd $RDMP
cd opt
cd AVP
rm *
cd ..
rmdir AVP

cd $RDMP

Сборка модифицированного bootdisk.img

#!/bin/bash

IMGPATH="./mbootdisk.img"
RDPATH="./ramdisk/"
LDRKRNL="./ldrkrnl/ldrkrnl.img"
RDNAME="ramdisk"
RDMP="/mnt/ramzes"

echo "Umount RAMDISK"
umount $RDMP

echo "Packing RAMDISK"
cd $RDPATH
gzip -9 $RDNAME
cd ..

echo "Make bootdisk"
cat $LDRKRNL $RDPATH$RDNAME".gz" >$IMGPATH
echo "Complete!"

Ссылки и файлы

Разборка оригинального диска на PasteBin
Удаление AVP из образа на PasteBin
Сборка модифицированного образа на PasteBin
Архив со скриптами
Часть I
Часть II
Все статьи (PDF, ZIP)

Препарирование AVP Z.E.S Linux Глава 2

Надо ж выдумать такое, во дурак!

Я, почему-то, не принял во внимание ясные надписи серым по черному, и попытался распаковать полученный ramdisk, думая, будто бы это стандартный initrd. А почему? Да потому что внимательнее мануалы читать надо, и гуглить лучше, если сам чего-то не знаешь.

Ramdisk, Ramdisk, only Ramdisk.

Оказывается, при создании дискеты была применена более старая технология создания диска в оперативной памяти
Полученный на прошлом этапе ramdisk.gz оказался действительно виртуальным диском в оперативной памяти, сжатым gzip’ом
Правда, при распаковке в Линуксе, gzip выдал предупреждение:
Пытаемся распаковать ранее вырезанный ramdisk.gz:

gzip -d ramdisk.gz
gzip: ramdisk.gz: decompression OK, trailing garbage ignored

Так, какой-то «мусор» после конца архива был игнорирован при распаковке. Как позже выяснится, фактически он ни на что не влияет, и на предупреждение gzip’а можно забить.

В конце образа дописано некоторое количество байт F6 (Ў) и нечто похожее на контрольную сумму и цифровую подпись.

Хотя, для чистоты эксперимента, ничто не мешает получить «чистый» архив, размером 876114 байт:
dd bs=1 count=876114 if=ramdisk.gz of=ramdiskcln.gz
И «мусорный» хвост (остаток размером 133614 байт).
dd bs=1 skip=876114 if=ramdisk.gz of=endimg

Пробую распаковать ramdiskcln.gz — никаких предупреждений, распаковка успешна:

Доступ к ramdisk’у и его модификация

Сначала создается точка монтирования:
mkdir /mnt/ramzes

Теперь монтирование распакованного образа:
mount -o loop ramdiskcln /mnt/ramzes


Доступ у ФС ramdisk’а получен

Все успешно примонтировалось, видно структуру каталогов оригинального ramdisk’а AVP Z.E.S Linux. Места, правда, маловато. Всего 3 с хвостиком Мб, а осталось свободными вообще 806 К. Но все равно, кое-что можно сделать, например, для первого раза:
— выкинуть сам AVP (директория AVP в opt, скрипт avp.run из sbin, ссылку usr/bin/AVPLinux и директорию .AVP из root)
— подправить скрипт etc/rc.d/rc.sysinit, чтоб выкинуть команды вызова AVP

Сборка модифицированного образа AVP Z.E.S Linux

1. Отмонтируем ramdisk:
umount /mnt/ramzes

2. Запакуем образ ramdisk’а:
gzip -9 ramdiskcln

3. Соберем образ диска обратно. От предыдущих экспериментов должен остаться файл ldrkrnl.img, содержащий начальный загрузчик и ядро Z.E.S. Его нужно скопировать в директорию с измененным и запакованным ramdisk’ом, и просто слить в новый образ с помощью cat:
ldrkrnl.img ramdiskcln.gz >mbootdisk.img

Но мы прошли туман!

И все-таки попытку модификации исходного образа удалось завершить, хотя бы для демонстрации того, что «а так можно было?»
Например, в образ добавлен минималистичный текстовый редактор qed, написанный на Free Pascal:

Или даже мощный консольный редактор, переделанный из примера, поставляющегося с Free Pascal:

Фейлы

Размер ramdisk’а сильно ограничен, поэтому некоторый софт, даже статически скомпилированный, туда не влез. Либо нарушалась идея «чтоб влезло на одну дискету».
-Постоянные проблемы с shared-библиотеками даже у того, что влезло. Так понимаю, что какие-то библиотеки устарели настолько, что новое не запускается, а старое, если заменить библиотеки — не работает. Или я что-то неправильно делал.

Итог

Поигрались и хватит, все равно для практического применения этот дистрибьютив не совсем подходит. Но есть и плюсы — классно поковырялся, в процессе узнал новое, в общем, удовольствие получено. Осталось даже несколько идей на будущее, например, очень понравился Free Pascal и некоторые возможности Linux, реализуемые им без геморроя, которым страдает программер на C/C++.

Источники и файлы

Начало
Использование ramdisk в Linux (ramdisk, ramfs, tmpfs)
или препарирование рамдисков

How to Create/Modify an RAM disk Image (на английском), PDF, скачать
Оригинальный образ bootdisk.img

AVP Z.E.S Linux, или исследование образа одной древней дискеты.

Чисто от нефиг делать…

Истерический экскурс

В состав древних версий Касперского антивируса входила утилита, для создания спасательной дискеты, включающая образ диска bootdisk.img и собственно утилиту, копировавшую этот образ на дискету №1, а на все остальные 2-3 штуки — антивирусные базы.
Дискеты с базами были самые обычные, они нас не интересуют, а вот на первой дискете был малюсенький Linux со встроенным антивирем. Linux автоматически монтировал локальные диски, причем поддерживал FAT, FAT32, NTFS, HPFS, EXT2, т.е. все самые популярные на 1999-2001 г. файловые системы.
После загрузки Касперского надо было вставить дискеты с базами, дождаться загрузки баз и далее шла проверка. Если же дискеты с базами не вставить, то выбрасывало в линуксовую консоль, в последней версии без всяких вопросов, а в более ранней надо было ввести имя пользователя root и аналогичный пароль. Далее, зная команды, можно было бродить по дискам, читать файлы с помощью cat, копировать их, и т.д.
Касперский линукс был неприхотлив, для работы ему хватало то ли 4, то ли 8 Мб оперативки, и нам с товарищем удавалось запустить его даже на 486 машине, а вот на 386 не получилось, памяти не хватило.
Сама же дискета не открывалась ни в 98 винде, ни в NT и 2000, ни в Линуксе. Линукс мы знали совсем мало-мало, винды ругались на то, что диск не форматирован, мануалов особо не было, интернета и подавно. В общем решили мы, что хитрый Касперский дискету зашифровал, чтоб чуть что ее вирусы не заразили ненароком, и решили, что тягаться с самим Валентинычем нам не под силу, да и забили на это дело.

Иногда они возвращаются.

Недавно товарищ вновь объявился на горизонте и принес тот самый bootdisk.img из дистрибутива AVP 5, правда, огорчил, что доступные ему виртуалки образом подавились. Microsoft Virtual PC свалилась вместе с виндовозом в синий экран, а Virtualbox и вовсе отказался принимать это за образ дискеты.
Я высказал предположение, что дискета в формате RAW и на ней просто последовательно без всякой файловой системы записаны загрузчик, ядро Линукса и что-нибудь типа initrd, откуда и запускается все остальное, скинул образ на флэшку, и опять забыл.

Дело было вечером, делать было нечего…

Точнее мне не хотелось слушать разговоры слесарей о машинах и футболе, мне они так же непонятны, как слесарям разговоры о Линуксе, и мне же о бабах, потому что про глючные девайсы я и в интернете могу почитать. Бухать тоже не перло, но на автобазе было тепло, а снаружи дул холодный ветер и сыпал мерзкий снег. К тому же обнаружился ЁЁЁ-писюк с модемом, а в кармане валялась та самая флешка с образом и Хрювером, он же HIEW. А пуркуа бы не па…

Обратный отсчет. Поехали!

Скачиваю QEMU, ставлю и скармливаю ей образ дискетки:

qemu-system-i386.exe -fda bootdisk.img -boot a

Надо же, загрузились, какие мы молодцы!

Тааак… Если загрузились, должен быть и загрузчик. Вот, кстати он работает:

Вспоминаем устройство загрузочных дисков. Сначала BIOS загружает первые 512 байт, которым передает управление. Можно попробовать эти 512 байт отрезать и посмотреть, что получится.
Устанавливаю dd
И делаю вот так:
dd bs=1 count=512 if=bootdisk.img of=512.img
bs=1
— размер блока 1 байт
count=512 — количество блоков
if=bootdisk.img — откуда читать
of=512.img — куда писать

Пробую скормить выходной файл QEMU:

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

Пространственное сжатие

Ладно, с налета, с шашкой наголо закономерно ничего не вышло, будем наблюдать дальше. Загрузимся опять с оригинального образа.
Момент раз:

Момент два, чуть погодя:

Ага! Uncompressing Linux! Compressed image found at block 454!

Похоже, моя гипотеза подтверждается: загрузчик, за ним сжатое ядро, в которое встроены необходимые модули, а за ним сжатый образ со всем остальным.
За следующую гипотезу приму то, что Касперский не изобретал крутых велосипедов, а ограничился стандартным gzip-сжатием.
Недолгое гугление дало, что gzip-архив начинается с сигнатуры 1F 8B 08 00, хорошо, что на флешке завалялся HIEW.
Загружаем в него оригинальный образ, переключаемся в HEX-режим (F4) и пробуем поискать сигнатуру архива.

Вот первое совпадение по смещению 4344h т.е. на 17221 байте от начала файла (HIEW ведет счет с 0).

А вот и второе по смещению 71800h, т.е. на 464897 байте от начала файла.
Больше сигнатур обнаружено не было. Пока с моими гипотезами все в порядке.

Мы режем, режем, режем…

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

Сначала оставлю один загрузчик, чтобы посмотреть, как он поведет себя без всего остального.
Копирую bootdisk.img под именем loader.img, открываю loader.img в HIEW. Далее надо переключиться в HEX-режим и провести поиск первого вхождения сигнатуры 1F 8B 08 00.
Теперь переключаемся в режим редактирования (F3) и обрезаем файл с этой позиции включительно (Trunc, F10)
Выходим из HIEW, получился файл размером ровно 17220 байт. Скармливаю его QEMU.

Точно загрузчик. Не обнаружил сигнатуры запакованного gzip’ом ядра, отругался и оставил нас.

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

Ага! Ядро! Вроде бы загрузка поначалу шла нормально, но потом RAMDISK не нашел образа диска на своем месте и драйвер VFS потребовал с нас дискету с корневой файловой системой. Естественно, т.к. у дискеты нестандартный формат, то смонтировать ее не удалось и получилась kernel panic. Хотя, забегая вперед, это дает возможность отвязаться от ограничений RAMDISK и модифицировать систему как угодно. Фактически это, конечно, не нужно, проще уж что-то свое собрать, чем идти таким странным способом.
Но ради развлечения я все-таки систему модифицирую, не зря же ковырялся.

Встаньте под образа!

Раз уж речь зашла о модификации, то нАчать надо с того, чтобы извлечь образ ramdisk’а.
Это последнее, что я сделал в теплом гараже и на винде. Для остального уже Линукс надобен.
Итак, имеем ldrkrnl.img размером 464 896 байт, и оригинальный bootdisk.img. Чтобы вырезать рамдиск, можно воспользоваться dd:
dd bs=1 if=bootdisk.img of=ramdisk.gz skip=464896
skip=464896
— количество блоков размером в 1 байт (bs=1), которые нужно пропустить с начала файла bootdisk.img

На выходе получился файл ramdisk.gz размером мегабайт с хвостиком, имеющий в начале вышеупомянутую сигнатуру gzip-архива. Файл успешно открылся в WinRar, и тест показал, что ошибок не обнаружено.

Начинался новый день…

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

Продолжение следует…

О gzip-архиве и сигнатуре ея
QEMU для Windows XP
dd для Windows

Линуксовая утилита dd для Windows

Не буду описывать для чего она нужна %) Заметка от дырявой памяти на всякий случай.

Скачать с официального сайта
Прямая ссылка на последнюю стабильную не бета-версию 0.5
Копия на всякий противопожарный

QEMU для Windows XP

К сожалению, автор QEMU перестал поддерживать XP, а старые версии, на мой взгляд, несколько глючноватые, но для каких-то небольших задач вполне подходят.

1. Качаем последнюю версию, поддерживающую XP 2016-09-03 (2.7.0) или отсюда
2. Ставим стандартным для Windows образом
3. Поскольку QEMU, как и в линуксе, управляется с командной строки, а расположена установленная программа в Program Files, да и имена у виртуалок длинные и неудобные, типа qemu-system-i386.exe, то пишем батник, передающий программе параметры, примерно такой, как здесь

содержимое qemu386.bat:
@Echo Off
Setlocal EnableDelayedExpansion
Set P="C:\Program Files\qemu\qemu-system-i386.exe"
For %%A In (%*) Do SET P=!P! %%~A

start "QEMU"/B %P%

Команда start — чтоб после запуска из консоли, например из-под FAR’а, консоль не висела, ожидая завершения работы QEMU
Параметр "QEMU" — заголовок окна, создаваемого командой start. Без него start подумает, что заголовок окна это путь к исполняемому файлу и попытается безуспешно выполнить первый передаваемый QEMU параметр.
/B — указывает команде start не создавать это самое новое окно, если его не указать, то за окном QEMU будет висеть черное пустое окно новой консоли.
В переменной %P% будет путь к QEMU и передаваемые параметры, например:
qemu-system-i386.exe -fda bootdisk.img -boot a загрузка с образа дискеты bootdisk.img

4. Кладем батник в какой-нибудь каталог, имеющийся в PATH, например, в C:\Windows

Пример как раз таки загрузки с такого образа

Про эту дискету расскажу как-нибудь позже, она с хитринкой, а мне было нечем заняться в компании дальнобоев, автослесарей и ноута с XP и мамедным интернетом, кроме как ее (недо)-реверсингом %).

Батник на PasteBin или скачать

Более сложный способ мониторинга состояния сервера на Linux в реальном времени.

Продолжаю тему, начатую в предыдущей заметке [КОПИЯ]. В ней описывал получение данных от определенных скриптов и процессов запущенных на сервере под управлением Linux с помощью SSH, псевдотерминала и отдельного пользователя, создаваемого специально для целей мониторинга.

Будем посмотреть другой способ, с одной стороны, более сложный и требующий владения каким-нибудь языком программирования, кроме Bash-скриптов. Хотя, можно обойтись и исключительно одним Bash’ем, если клиент и сервер под Linux, или Bash прикрутили к Windows (cygwin(?), не пробовал, не знаю). А с другой стороны, наоборот, способ простой безопасный, требующий минимум вмешательства в настройки сервера.

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

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

Задача

Такая же, как и в предыдущей заметке. Имеется удаленный компьютер под управлением Linux, рулящий системой контроля температуры и давления.
На самом деле, рулить он может чем угодно: от домашнего FTP с котиками или соединения с Интернетом, до управления СКД, открытием ворот, дверей, врат в Ад, личным концлагерем и т.д.
Суть в том, что нужно, чтобы удаленная система сигнализировала оператору об изменении своего состояния (изменении температуры, разрыва соединения с Интернетом, пришествии Сатаны). Оператор, как обычно, сидит под Windows (как в большинстве организаций в СНГ).

Некоторые соглашения

Для простоты условимся, что локальный и удаленный компьютер находятся в одной локальной сети (и одной подсети) 10.10.0.0/24, IP-адрес локального компьютера 10.10.0.30, прием данных производится через сетевой порт 11000 локального компьютера. Локальный и удаленный компьютеры обмениваются данными по протоколу TCP, данные представляют собой Unicode-строки.

Как это организовано на локальном и удаленном компьютере

Код

Сервера приема сообщений:
Смотреть на PasteBin
Скачать с Mega.nz

Скрипта отправки сообщений:
Смотреть на PasteBin
Скачать с Mega.nz

Источники

1. Клиент-серверное приложение на потоковом сокете TCP [Копия]
2. Как открыть TCP-/UDP-сокет средствами командной оболочки bash [Копия]

Видеоиллюстрация

Прямая ссылка