Анализ древней дискеты 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 [Копия]

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

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

Простой способ мониторинга состояния сервера.

Введение

Понадобилось мониторить состояние сервера, точнее не всего сервера, а определенного демона, на сервере запускаемого. Понятно, что самым простым способом мониторинга чего-то работающего в фоне, является просмотр соответствующих логов. Но такой способ на самом деле дает весьма мало интерактивности, надо постоянно заходить по SSH, ковыряться в этих самых логах. Хочется, чтоб при изменении состояния, или же по определенной команде от определенного пользователя, сервер нам все рассказывал сам.
Хорошо, если демон умеет при изменении состояния запускать некие пользовательские скрипты. Так умеет, например, демон OpenVPN или, например, демон небольшой промышленной системы метеоконтроля, который я использовал в данном примере.
Вкратце, имеется плата на Arduino, обрабатывающая показания с нескольких датчиков и передающая их в удобоваримом формате через COM-порт демону, запущенному на сервере. Демон умеет исполнять пользовательские скрипты, но вот беда (та же беда и с OpenVPN), если в скрипте написать что-то типа echo "У нас изменились параметры, шеф, все пропало" это сообщение в лучшем случае уйдет неведомо куда. В худшем — вылезет пользователю, из под которого стартует демон, посреди рабочего сеанса в консоль.

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

Не так давно я делал похожего пользователя для отключения/перезагрузки сервера [КОПИЯ] . Фактически, пользователю была установлена псевдооболочка (на самом деле просто скрипт), выполняющий единственную команду перезагрузки/отключения системы. И идея создания псевдооболочек меня зацепила. Таким образом можно дать пользователю выполнять только ограниченный набор команд, да еще и обрабатывать параметры в скрипте по-своему, так что никакой злоумышленник, даже получив доступ по ssh ничего сделать не сможет, т.к. команды псевдооболочки ему неизвестны.

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

Создание пользователя

Первым делом создаем отдельную группу:
groupadd monusers
где monusers — любое название группы на ваш вкус, ранее в системе не существующее

Создаем пользователя:
useradd -g monusers -d /home/meteomon -s /home/meteomon/monitor.sh meteomon

где:
-g monusers группа пользователя (ранее созданная monusers)
-d /home/meteomon домашний каталог пользователя
-s /home/meteomon/monitor.sh — псевдооболочка для пользователя, скрипт, обрабатывающий команды.
meteomon — имя пользователя

Задаем пользователю пароль (иначе не сможем залогиниться по ssh):
passwd meteomon

Создаем домашний каталог:
mkdir /home/meteomon

Меняем владельца каталога на пользователя meteomon:
chown meteomon:monusers /home/meteomon

Меняем права доступа на каталог:
chmod 500 /home/meteomon

Создаем в домашнем каталоге скрипт monitor.sh о содержимом скрипта ниже.

Меняем владельца и права доступа для скрипта monitor.sh
chown meteomon:monusers /home/meteomon/monitor.sh
chmod 500 /home/meteomon/monitor.sh

Скрипт-псевдооболочка

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

#!/bin/bash

echo "Hi, monitor operator"
echo "To exit enter byebye"

while [ "$KEYINPUT" != "byebye" ]; do
    read KEYINPUT
done

Все просто — ввод с клавиатуры попадает в переменную KEYINPUT и пока она не равна byebye скрипт выполняется. Как только пользователь введет byebye, так прервется цикл, скрипт завершит работу, и пользователь автоматически выйдет из системы.

Отправка сообщений пользователю

Для отправки сообщений пользователю используем связку команд echo и write
Можно создать отдельный скрипт со следующим содержимым:

#!/bin/bash

USERNAME="meteomon"

echo -e $1|write $USERNAME 2>/dev/null

положить его в каталог с доступными пользователям скриптами (например в /usr/sbin) и установить права доступа, например в 755, чтобы пользователь для мониторинга мог получать сообщения от всех пользователей системы.

Примечание: параметр -e команды echo позволяет использовать специальные символы, такие, как перенос строки \n, а конструкция 2>/dev/null отправляет в нуль-устройство сообщение об ошибке, которое может возникнуть, если пользователь meteomon не вошел в систему.

Использование

Осталось прописать соответствующую команду в пользовательском скрипте, вызываемом демоном, или исполняемом по cron’у:

...
DATA=`meteosrv checksystem`
/usr/sbin/techo $DATA
...

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

Настройка рабочего места оператора

Для Windows понадобится утилита plink, обычно она идет вместе с ssh-клиентом PuTTY. В каталоге с ней создаем bat-файл следующего содержания.

testmon.bat:
plink -ssh -P 22 -l meteomon -pw meteomonpass 192.168.0.40

где вместо meteomon надо подставить имя пользователя для мониторинга, вместо meteomonpass — заданный пароль, а вместо 192.168.0.40 настоящий адрес удаленного компьютера.

Вот что получилось

Источники

1. Bash, команда write

Изменение логотипа в окне логина GDM

Спрашивают, как у нас сделан украинский флаг при входе на сервер. Да проще пареной репы, товарищи!

1. В любимом графическом редакторе готовим картинку. Должна быть PNG, разрешением 210×210 px и глубиной цвета 32 бита.
2. Идем в файл /usr/share/gdm/defaults.conf и ищем там параметр Logo= (секция [greeter]) и меняем путь на путь к своему файлу или заменяем сам файл.
Можно настроить приветствие:
Параметры
DefaultWelcome=false
DefaultRemoteWelcome=false

устанавливаем в false (иначе, ЕМНИС, будет использовано имя компьютера) и меняем параметры (вместо нашего названия подставьте свое):
Welcome=Welcome to UAITC
RemoteWelcome=Welcome to UAITC

Флаг (по клику можно скачать с mega.nz):

Права доступа и владельцы файлов в Linux.

Шпаргалка на стену студенту.




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

Скачать архив с копиями источников, файлами большого разрешения и svg.

По материалам:
1. http://downloads.naulinux.ru/pub/NauLinux/school_server/Docs/Docs/Nau/nau-server-sbs-ru/s1-navigating-ownership.html
2. http://www.k-max.name/linux/prava-dostupa-v-linux-eshhe-odna-malenkaya-shpargalka/

Настройка XDMCP, удаленного подключения к рабочему столу Linux

Не так давно я затрагивал вопрос настройки X11 Forwarding [Копия], что позволяет через ssh запускать отдельные графические приложения на удаленной Linux-машине (сервере). Теперь буду настраивать удаленный доступ к рабочему столу через XDMCP.
XDMCP внешне похож на RDP в Windows, т.е. при подключении пользователю будет предложено ввести логин и пароль в окне входа в систему и на экране отобразится удаленный рабочий стол. Фактически, на удаленной машине в памяти висит Display Manager (GDM, XDM и т.д.) и слушает 177 порт UDP, если от X-сервера с другой машины поступает запрос, Display Manager начинает с ним общаться, принимать оттуда изображение, а туда передавать координаты мыши и нажатия с клавиатуры, рисует окошко входа в систему. Если пользователь предоставил корректные данные для входа в систему, то он сможет работать с удаленным рабочим столом.

Внимание! Не все Display Manager’ы поддерживают работу по протоколу XDMCP. Точно поддерживают XDM, GDM, KDM и LightDM [3], так что проверьте в первую очередь, какой у вас Display Manager, и может ли он работать по XDMCP. Например, на одной из машин, к которой требовался доступ по XDMCP пришлось вместо LXDM ставить GDM.
Внимание! Протокол XDMCP довольно слабо защищен, так что его не рекомендуется использовать через Интернет без дополнительного шифрования. У нас, например, сделан доступ через VPN.

Настройка файервола

Первым делом необходимо открыть на файерволе нужные порты. Обязательно для входящих соединений открывается порт UDP 177. Если соединение планируется из Windows, то необходимо также открыть порты TCP 6000-6005 в обоих направлениях (входящие и исходящие соединения). Для соединения из Gnome вроде как надо открыть также в обоих направлениях порты TCP 16001 и 35091 [2]. На практике я проверял только подключение из Windows.
Команды для настройки файервола:

# XDMCP
echo "Open 177 port UDP (XDMCP) for Avallon AG clients..."
iptables -A INPUT -s x.x.x.x/yy -p udp --dport 177 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p udp --sport 177 -j ACCEPT

echo "Open 6000:6005 ports (Windows XDMCP) in both directions for AAG clients..."
iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT

iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT

Вместо x.x.x.x/yy надо подставить адрес компьютера с которого будем связываться с компьютером под Linux, или маску подсети.

Настройка Display Manager’а

У меня был GDM, поэтому приведу его как основной, остальные дам для справки.
Необходимо найти файл custom.conf, в источниках написано, что лежать он должен по адресу /etc/gdm/custom.conf, но на самом деле это зависит от дистрибьютива. В моем случае файл находился здесь: /etc/X11/gdm/custom.conf

В файле, который выглядит, как обычный INI-файл необходимо найти секцию [xdmcp] и вписать туда следующие параметры:

Enable=true
Port=177

Как видите, можно задать альтернативный порт для XDMCP.

Настройка других DM:
Под катом

Внимание! Стоит заметить, что в некоторых случаях конфигурационные файлы могут располагаться в других местах. Если их нет по указанным путям, можно воспользоваться поиском файлов в том же mc

Настройка подключения в Windows

Понадобится уже упомянутый в заметке про X11-Forwarding Xming.
Запускаем XLaunch и устанавливаем конфигурацию.

В первом окне выбираем один из режимов «одного окна», например One window, иначе не даст создать XDMCP сессию, и указываем номер дисплея 0 (обычно 0, если вы специально ничего не переопределяли на сервере, подробнее см. документацию по используемому Display Manager’у):

Описание настройки с иллюстрациями под катом

Если все сделано правильно

То при запуске Xming (через мастер XLaunch или с нужными параметрами) мы увидим окно авторизации в системе:


По клику доступно полноразмерное изображение

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


По клику доступно полноразмерное изображение

Сохранение и использование настроек соединения

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

1. Как ранее говорилось, сохранить конфигурацию в файл *.xlaunch (например xdmcp.xlaunch) и запускать мастер XLaunch, указывая ему с помощью ключа -load файл конфигурации. Мастер XLaunch запустится, но все поля в окнах будут уже предварительно заполнены. Это удобно, если нужно соединяться по XDMCP с несколькими серверами, различающимися только, например, IP-адресом. Можно создать ярлык, в свойствах которого указать параметры к запуску XLaunch:

"C:\Program Files\Xming\XLaunch.exe" -load xdmcp.xlaunch

2. Создать ярлык Xming с нужными параметрами:

"C:\Program Files\Xming\Xming.exe" :0 -clipboard -query 10.10.3.24 -dpi 96

Естественно, вместо 10.10.3.24 нужно подставить свой адрес удаленной машины с XDMCP, а число после -dpi выбрать под свои глаза и монитор.

Источники

1. Удаленный доступ по XDMCP (удаленное подключение к рабочему столу)
2.What Ports Need to be Opened for XDMCP
3.Xdmcp

Копия заметки в PDF

Удаленная перезагрузка сервера под управлением Linux. Перезагрузка Linux без ввода пароля.

На самом деле делалось не для совсем сервера, но тем не менее. Стоит, в общем, на одном заводике в одной из стран СНГ аппарат по переработке пластиковых отходов в пластиковые полезности, управляет им комп с Linux на борту, а компом из будочки рядом управляет оператор с рабочего места с обыкновенной виндой. Комп с Линуксом надо иногда перезагружать, отключать, а в штатном ПО аппарата эту возможность почему-то не встроили. Раньше оператором был довольно умный парень, которому и root-пароль можно было доверить, и ssh, но он уволился, напоследок создав два батника примерно такого содержания:
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 reboot
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 poweroff

Бардак сущий, под root ходить для перезагрузки никуда не годится, да еще и хранить рутовый пароль в открытом виде. Можно, конечно, было бы подправить батник, сделав вход под юзерской учеткой, но sudo было криво настроено и все равно оператору бы пришлось для перезагрузки вводить пароль.

Решение

Завести на сервере отдельных пользователей «для отключения» и «для перезагрузки» и настроить все так, чтобы при входе этих пользователей по ssh автоматически выполнялось выключение или перезагрузка, при этом не требовался ввод пароля, создать соответствующие bat-файлы на операторском рабочем месте.

Создание группы

Первым делом понадобится группа для этих пользователей. Самая простая операция. Назовем группу, например powermanager и создадим ее (естественно, здесь и далее все команды, требующие root-доступа делаются из-под учетки root или через sudo).

groupadd powermanager

Настройка sudo, редактирование файла sudoers

В файле /etc/sudoers как раз и описывается, какие пользователи и группы имеют возможность пользоваться утилитой sudo, временно повышая свои права до root, и какие команды им разрешено выполнять без пароля.
Этот файл руками лучше не редактировать, а всегда делать это с помощью команды visudo:

Файл настроек /etc/sudoers всегда следует редактировать с помощью команды visudo. visudo блокирует файл sudoers, сохраняет изменения во временный файл и проверяет, что файл грамматически корректен, перед тем как скопировать его в /etc/sudoers.
Важно:
Крайне важно, чтобы файл sudoers был без синтаксических ошибок! Любая ошибка делает sudo неработоспособным. Всегда редактируйте его только с помощью visudo для предотвращения ошибок.
[1]

I. Улучшаем работу с sudoers

Но есть небольшая проблема, visudo, в качестве вызываемого ей редактора, использует неудобный vi, который без стакана и длительной практики может только «пищать и портить». Слава Ктулху, на компьютере стоял mc, и, соответственно, mcedit, поэтому:

1. Переопределение редактора для visudo при однократном запуске:

EDITOR=mcedit visudo

Уфф, /etc/sudoers открылся в человеческом mcedit.

2. Постоянная замена редактора для visudo
Для этого добавляем в sudoers следующие строки:

Defaults env_reset
Defaults editor=/usr/bin/mcedit, !env_editor

где editor=/usr/bin/mcedit указание, какой редактор использовать
!env_editor — запрет использования редактора, установленного переменными окружения (подробности смотрите по ссылке на детальное описание файла sudoers в конце заметки).

II. Прописываем разрешения для группы powermanager в sudoers

Для разрешения пользоваться командой shutdown без ввода пароля для пользователей группы powermanager, в sudoers следует добавить следующую конструкцию:

%powermanager ALL=NOPASSWD: /sbin/shutdown

Внимание! Для более полного понимания sudoers настоятельно рекомендую ознакомиться со статьей по ссылке в конце заметки!
Внимание! Все пути в файле sudoers должны быть полными

Пример файла sudoers можно посмотреть здесь.

Создание пользователей для перезагрузки и отключения питания

Создание пользователя для удаленной перезагрузки.

1. Создаем пользователя:

useradd -g powermanager -d /home/rebootusr -s /home/rebootusr/reboot.sh rebootusr

где:
-g powermanager группа пользователя (ранее созданная powermanager)
-d /home/rebootusr домашний каталог пользователя
-s /home/rebootusr/reboot.sh — оболочка для пользователя. Обычно здесь прописывается /bin/sh, /bin/bash для интерактивных пользователей, или /bin/false для неинтерактивных, например пользователя FTP, но можно задать и собственный скрипт, команды которого будут выполнены при входе пользователя в систему.

2. Задаем пользователю пароль (иначе не сможем залогиниться по ssh):
passwd rebootusr
3. Создаем домашний каталог:
mkdir /home/rebootusr
4. Меняем владельца каталога на пользователя rebootusr
chown rebootusr:powermanager /home/rebootusr
5. Меняем права доступа на каталог:
chmod 500 /home/rebootusr
6. Создаем в домашнем каталоге скрипт reboot.sh со следующим содержимым:

#!/bin/sh

echo "Rebooting..."
sudo /sbin/shutdown -r now

где
-r — указание программе shutdown выполнить перезагрузку
now — указание временного интервала — немедленно (можно еще выставить число в минутах, тогда перезагрузка произойдет через указанное время)

7. Меняем владельца и права доступа для скрипта reboot.sh

chown rebootusr:powermanager /home/rebootusr/reboot.sh
chmod 500 /home/rebootusr/reboot.sh

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

Содержимое скрипта для отключения питания poweroff.sh:

#!/bin/sh

echo "Power off"
sudo /sbin/shutdown -hP now

Настройка рабочего места оператора

Для Windows понадобится утилита plink, обычно она идет вместе с ssh-клиентом PuTTY. В каталоге с ней создаем два bat-файла следующего содержания.
rebootsrv.bat:
plink -ssh -P 22 -l rebootusr -pw rebootpass 192.168.0.40
pwroffsrv.bat:
plink -ssh -P 22 -l pwroffusr -pw pwroffpass 192.168.0.40

где вместо rebootusr и pwroffusr надо подставить имена пользователей для удаленной перезагрузки и отключения питания соответственно, вместо rebootpass и pwroffpass — заданные пароли, а вместо 192.168.0.40 настоящий адрес удаленного компьютера.

Источники

1. sudo [Копия]
2. Как перезагрузить компьютер без прав root [Копия]

Заметка в PDF

Скрипт, разбирающий deb-пакеты

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

Кратко и по рабоче-крестьянски, что такое deb-пакет. Фактически, это архив формата ar, содержащий бинарные файлы программы, скрипты, необходимые пакетному менеджеру Debian для установки/удаления пакета и всякую служебную информацию, вроде контрольных сумм и прочего.
Нас интересуют бинарные файлы и неплохо бы посмотреть на предустановочные скрипты, ну мало ли чего там интересного и важного обнаружится. Установочные скрипты внутри архива ar сжаты в архив control.tar.gz, а вот бинарники находятся в архиве data.tar.??, где вместо ?? может быть .gz, .xz и т.д., в зависимости от того, что для сжатия бинарников было использовано. В архиве data сохранена структура каталогов, идентичная каталогам в системе, куда будет установлен пакет, примерно как в пакетах Slackware (только структура каталогов, естественно, специфична для Debian-подобных Linux). В архиве control.tar.gz могут содержаться скрипты конфигурирования, из которых наиболее интересны preinst, выполняемый на Debian перед распаковкой пакета, и postinst, выполняемый, когда пакетный менеджер распаковал бинарники в целевую систему. Естественно, просто так их выполнять не советую, но если делать из deb-пакета пакет Slackware, то не лишним будет с этими скриптами ознакомиться и буде там что нужное, передрать в doinst.sh

Скрипт

Определим основные переменные:
#!/bin/bash

DATADIR="./data" #директория, куда класть архивы с бинарниками
CONTROLDIR="./control" #... с управляющими скриптами
CURDIR="" #Текущая директория

Вывод краткой справки по использованию скрипта:

if [ "$1" == "-h" ]; then #print help
    echo "Unpacking all *.deb packages in current directory"
    echo "use" `basename "$0"` "[-c]"
    echo "-c - delete files in out-dirs"
    exit
fi

Выводим информационное сообщение и создаем каталоги для хранения архивов с бинарниками и управляющими скриптами:

echo "Unpacking all *.deb packages in current directory"

echo "Making out-dirs... $DATADIR $CONTROLDIR"
mkdir $DATADIR
mkdir $CONTROLDIR

Если при запуске скрипта был указан ключ -c, то очищаем содержимое директорий для хранения распакованных файлов:

if [ "$1" == "-c" ]; then 
    echo "Clear out-dirs..."
    CURDIR=`pwd`
    cd $DATADIR
    rm *
    cd $CURDIR
    cd $CONTROLDIR
    rm *
    cd $CURDIR
fi

С помощью команды find получим список всех deb-пакетов (*.deb) в текущей директории:

echo "Processing:"
F=`find . -name "*.deb" -type f`

где:
. (точка) — указание команде find искать в текущем каталоге.
-name — после этого ключа задается нужная нам маска файла ("*.deb")
-type f — искать только файлы (не каталоги, подпадающие под шаблон).

Результат отправляется (``) в переменную $F, которую обрабатываем в следующем цикле for:

for FILE in $F
do
...
done

Что делаем в цикле:
Вызываем архиватор ar с параметром t, это выведет список файлов в архиве, потом при помощи grep получаем имя архива data с бинарниками (напомню, оно разное может быть, в зависимости от того, чем бинарники сжаты):

DATAPKG=`ar t ${FILE}|grep "data"`

Аналогично поступаем и с архивом control, содержащим управляющие скрипты:

CONTROLPKG=`ar t ${FILE}|grep "control"`

Получаем имя deb-пакета без расширения (ключ -s ".deb" команды basename):

BASENAME=`basename -s ".deb" ${FILE}`

И расширения для содержащихся в deb-пакете архивов с бинарниками и скриптами:

EXTDATA=`echo $DATAPKG|sed 's/data//g'`
EXTCONTROL=`echo $CONTROLPKG|sed 's/control//g'`
echo "${FILE} : $DATAPKG, $CONTROLPKG"

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

Вытаскиваем архивы из пакета:
ar -p "$BASENAME.deb" $DATAPKG > "$DATADIR/$BASENAME$EXTDATA"
ar -p "$BASENAME.deb" $CONTROLPKG > "$CONTROLDIR/$BASENAME$EXTCONTROL"

После запуска скрипта в каталоге, содержащем deb-пакеты, будкт созданы два подкаталога, содержащие архивы с бинарниками и архивы с инсталляционными скриптами.
Их уже можно распаковать стандартными tar’ом и gzip’ом или посмотреть их содержимое с помощью mc

Скрипт целиком

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

Источники

1. Архиватор ar
2. Структура deb-пакета
3. Цикл for
4. Распаковка пакета deb
5. basename --help

Заметка в PDF

Универсальный конвертер символов перевода строки (Windows\Mac\Linux)

Ух и задолбался же я с этими самыми переводами строк! Возникла тут задачка конвертировать кучу огромную текстовых файлов из DOS/Windows (перенос строки CR+LF, h0D, h0A), старого Mac-формата (CR, h0D), который, вопреки утверждениям Википедии и других авторитетных источников использует не только вышедшие из употребления Маки, в формат Linux (LF, h0A). Желательно иметь возможность еще и обратной/произвольной конвертации между всем этим зоопарком. Сначала я, конечно, попробовал написать универсальный скрипт с помощью sed, но никакой универсальности не получилось. На C++, ой, после C# это все равно, что пересесть с мерседеса на велосипед. На C# задача в строчки 4 кода решается, но тащить ради маленькой утилиты Mono, это уж слишком

В общем нашел готовую крохотную утилиту flip.
Плюсы:
+ Есть готовые версии почти под все платформы, кроме DOS, даже статически откомпилированный бинарник для Linux, так что можно задуть в роутер/initrd, если оно кому-то там надо.
+ Бесплатно
+ Есть исходники
+ Работает моментально
+ Поддерживает файлы с перепутанными концами строк (где есть и Windows, и UNIX и Mac варианты)

Минусов пока не нашел.
Использование простое: первый параметр, что конкретно делаем, остальные — имена файлов через пробел.
Делать можно следующее:
-t — отобразить используемый тип переноса строки
-d — конвертировать в DOS/Windows формат (CR+LF)
-m — конвертировать в Mac-формат (CR)
-u — конвертировать в UNIX/Linux формат (LF)

Скачать можно со странички автора или отсюда:
1. Исходник
2. Slackware-пакет
3. Версия для Windows (консольная)
4. Все остальное

Няшная панель Qtpanel для Openbox и других WM для Linux

Недавно нашел няшную чОрную панель с меню Пуск для всяких там WM, у меня стояла на Openbox, но скрины будут с IceWM. Давно искал такую легковесную, простенькую и при этом няшную (чОрную, как мой кот) панель. Да, изначально была идея найти панель под цвет кота.
Правда, проект довольно старый и походу издох естественной смертью, но мне нравится.


Скрин из оригинальной статьи

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

По клику доступно вениаминное полноразмерное изображение

Может находиться и снизу:


По клику доступно вениаминное полноразмерное изображение

Статья и описание на Хабре
Скачать бинарный пакет для Slackware с Mega.nz

ЗЫ. Сборка: сообщество PuppyLinux Rus. Пакет для Slackware мой.

polkit-gnome-0.105 для Slackware x86 (i386)

Пост, скорее из серии, «чтоб не пролюбить, и самому потом долго не искать», чем конкретная детальная инструкция. Понадобился мне PolicyKit для GDM под x86 Slackware (14.1), из коробки его нифига не было, во всяком случае в нужном дистрибьютиве, пришлось собирать. Не буду детально описывать геморрой со сборкой, ибо зачем вам описание четырех кривых рук из двух стран, хехе. Наибольший геморрой случился с правильной сборкой требуемой ему библиотеки mozjs-17.0, то ли я дурак, то ли оно изначально криво, но оригинал не собирался, ставился не туда, загаживал систему какими-то лишними файлами под 200 Мб, в общем тьфу и ужоснах. Совместными усилиями были найдены нужные слакбилды, так что тут краткая заметка для себя.

1. Собираем упомянутый mozjs-17.0 (aka js-185)
Sources
SlackBuild
Binary package (готовый собранный пакет) для x86 (i386) Slackware
2. Собираем polkit-0.133 (polkit-1)
Sources
SlackBuild
Binary package (готовый собранный пакет) для x86 (i386) Slackware
3. Наконец, собираем polkit-gnome (polkit-gnome-authentication-agent-1)
Sources
Binary package (готовый собранный пакет) для x86 (i386) Slackware

1 и 2 собираются стандартно
1. Распаковываем SlackBuild из архива в отдельный каталог.
2. Копируем туда архив с исходником.
3. Запускаем в этом каталоге ./Название_программы.SlackBuild Архив_с_исходниками.tar.gz

Финальный пакет замечательно соберется с помощью src2pkg, если первые установлены.

Да, чуть не забыл, само дерево жужжать не будет, т.е. polkit-gnome-authentication-agent-1 автоматически не запустится, его надо прописать в какую-нибудь иксовую автозагрузку и после того, как стартуют иксы, GDM и будет сформировано окружение пользователя, т.е. или в скрипт Xsession добавить строку /usr/libexec/polkit-gnome-authentication-agent-1 & или добавить его в автозагрузку приложений, как описано, например, здесь

Позже я вернусь к описанию автозагрузки иксовых программ отдельно, во всяком случае опишу автозапуск в GDM и IceWM

Отключение автомонтирования USB-устройств при запуске X (gdm, icewm, spacefm)

Попросили разобраться тут с одной небольшой проблемой, при старте X-server’а и вообще графического окружения выполнялось ненужное, и даже вредное автоматическое монтирование USB-устройств. На подключенных к терминальному серверу флешках хранились ключи для бухгалтерии.
Проблема была в том, что подключающимся через XDMCP к графической оболочке пользователям, автоматически становились доступны подключенные к серверу носители USB.
Было известно, что графический интерфейс представляет собой связку GDM, IceWM в качестве desktop-manager’а и SpaceFM в качестве файлового менеджера. Исследование было недолгим, ибо такая конфигурация по умолчанию применяется в Absolute Linux, легковесном дистрибьютиве Slackware, который я же и посоветовал этой фирме года 3 назад 🙂
В автомонтировании был виновен SpaceFM, файловый менеджер. Поскольку, в самом менеджере все настраивается через графический интерфейс, и изменить настройки (локальные) может любой пользователь, то надо было искать другой выход.
Монтирование SpaceFM, естественно, осуществляет не сам, а использует udevil. Соответственно, наиболее простое, быстрое и секурное решение — подправить конфиг udevil. Выкладываю финальный параноидальный вариант, где udevil запрещено монтировать все, что не было примонтировано до старта графической оболочки, и от любых пользователей (сменные носители, сетевые шары, оптические носители). Хотите монтировать — добро пожаловать в sudo.

Конфиг: /etc/udevil/udevil.conf

Конфиг прекрасно документирован, правда на буржуйском, так что его можно переделать под свои нужды.

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

Скрипт для автоматического обновления паролей бесплатного VPN vpnbook.com

Как-то выкладывал конфигурационные файлы для PPTP-VPN от бесплатного VPN-сервиса http://vpnbook.com.
Правда у сервиса есть небольшой недостаток, как и у многих других бесплатных VPN, периодически меняется пароль. Благо, что пароль появляется у них на странице в текстовом виде, без всяких каптч, картинок и яваскрипта, и вполне просто автоматизировать его обновление, чтобы вручную не менять его в конфигурационных файлах после изменения на сайте.

Определение основных переменных

VPNBOOKPAGE="http://www.vpnbook.com/#pptpvpn"
WORKDIR="/tmp/"
HTMLFILE="vpnhtml.txt"
PASSANCOR="Password:"
VPNBOOKPASS=""
FILEPASS=""
PEERSDIR="/etc/ppp/peers/"
PEERSFILES[0]="vpnbook-e214"
PEERSFILES[1]="vpnbook-e217"
PEERSFILES[2]="vpnbook-de233"
PEERSFILES[3]="vpnbook-us1"
PEERSFILES[4]="vpnbook-us2"
PEERSFILES[5]="vpnbook-ca1"

VPNBOOKPAGE — адрес, по которому доступен текущий пароль.
WORKDIR — рабочий каталог, куда будем сохранять полученную с сайта HTML-страницу с паролем
HTMLFILE — имя сохраняемого файла
PASSANCOR — Ключевое слово, по которому будем определять, где именно на странице пароль:

VPNBOOKPASS — тут будем хранить пароль, полученный с сайта
FILEPASS — тут будет пароль, сохраненный в данный момент в конфигурационном файле
PEERSDIR — директория, в которой хранятся конфигурационные файлы для соединения с VPN-серверами vpnbook
PEERSFILES[0]...PEERSFILES[5] — массив с именами конфигурационных файлов

Получение пароля с сайта

I. Сначала, с помощью wget, получим HTML-страницу, содержащую пароль.

echo "GET VPNBOOK PASSWORD v 0.2" #приветствие

rm $WORKDIR$HTMLFILE #удаляем текущий файл
echo "Get vpnbook page..."
wget -P $WORKDIR --default-page=$HTMLFILE --header="Content-type: text/plain" $VPNBOOKPAGE #сохраняем HTML-страницу

ВНИМАНИЕ! Существующий файл с сохраненной HTML-страницей надо обязательно удалить, иначе wget при сохранении страницы добавит к имени дополнительно .1 (.2 .3 и т.д.).

Параметры утилиты wget:
-P $WORKDIR — установка рабочего каталога, указанного в переменной $WORKDIR
--default-page=$HTMLFILE — установка имени файла, под которым в рабочем каталоге будет сохранена полученная с сайта HTML-страница. Имя указывается в переменной $HTMLFILE
--header="Content-type: text/plain" — передаем серверу заголовок, в котором указываем, в каком виде хотим получить страницу (text/plain). Лучше не упускать этот момент, одно время сервер почему-то отдавал без этого заголовка сжатую HTML-страницу, и анализировать ее потом было некузяво.

II. Проверяем, сохранилась ли страница:

if [ ! -f $WORKDIR$HTMLFILE ]; then
    echo "ERROR: Page not saved"
    exit 1
fi

III. Вытаскиваем пароль из сохраненного HTML-файла:

VPNBOOKPASS=`cat $WORKDIR$HTMLFILE|grep "$PASSANCOR"|head -n1|sed -e :a -e 's/<[^>]*>//g;/</N;//ba'|sed 's/.$//'|awk ' {print $2} '`

1. Выводим содержимое файла на stdout командой cat $WORKDIR$HTMLFILE
2. Передаем вывод команде grep, она фильтрует строчку с содержимым, указанным в переменной $PASSANCOR, т.е. строчку, содержащую слово "Password:" и сам пароль. На самом деле команда grep отфильтрует две строки, еще и с виндовыми концами строк:

3. Обрабатываем строчку дальше с помощью команды head -n1 Она получит из вывода команды grep только первую строчку (-n1)

4. Команда sed -e :a -e 's/<[^>]*>//g;/</N;//ba' с вот этим диким регулярным выражением, удалит HTML-теги. Регулярка не моя, я нашел на просторах интернетов.

5. Следующая команда sed 's/.$//' избавит строку от лишнего виндового символа конца строки.

6. Наконец, утилитой awk, которая обрабатывает строки, воспринимая содержимое, как набор полей разделенных разделителем (по умолчанию пробел), вытаскиваем из строки непосредственно сам пароль. awk ' {print $2} '

wra2ezEz

Записываем результат в переменную VPNBOOKPASS, обернув всю команду в обратные кавычки (``)
Далее устанавливается размер массива, хранящего имена файлов настройки (специально так сделал, чтобы если добавится еще один файл конфигурации, количество обрабатываемых файлов обновлялось автоматически): CTR="${#PEERSFILES[*]}"
Далее инициализируется счетчик цикла I="0"

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

until [ "$CTR" -eq "$I" ]; do
    passwork $PEERSDIR${PEERSFILES[I]}
    let "I+=1"
done

Замена пароля в файле конфигурации соединения VPN

Этим в скрипте занимается отдельная функция passwork(), которой в качестве параметра передается полный путь к файлу конфигурации соединения. Вот ее код:

passwork()
{
    echo -n "Checking $1..."
    if [ -e $1 ]; then #file exist
    	COUNT=`cat $1|grep "password" -c`
	if [ $COUNT -eq 1 ]; then # strochek s parolem 1
	    #vitaskivaem password i udalyaem kavichki
	    FILEPASS=`cat $1|grep "password"|awk ' {print $2} '|sed 's/\"//g'`
	    echo -n "password "$FILEPASS
	    
	    if [ "$FILEPASS" = "$VPNBOOKPASS" ]; then #proverka parolya
		echo " not replaced."
	    else
		#backup file
		cp $1 $1".bak"
		echo "...file backuped..."
		sed -i 's/'$FILEPASS'/'$VPNBOOKPASS'/g' $1 #replace password
		echo "...replaced!"
	    fi
	    
	else #>1 ili 0
	    echo  " Peer file format error"
	fi
    else
    
	echo  " $1 not found"
    fi
}

В зарезервированной переменной $1 находится параметр, переданный функции из основной программы, в данном случае путь к файлу конфигурации соединения.
Сначала проверяется, существует ли файл:

...
if [ -e $1 ]; then #file exist
...

Если он существует, продолжаем работу, если нет — выводим сообщение об ошибке и выходим из функции:

...
else
echo " $1 not found"
fi
...

Сам конфигурационный файл выглядит так:

debug
#nodetach
unit 1
remotename ca1.vpnbook.com
ipparam vpnbook-ca1
pty "pptp ca1.vpnbook.com --nolaunchpppd"
name vpnbook
user vpnbook
password "wra2ezEz"
require-mppe-128
refuse-eap
noauth
file /etc/ppp/options.pptp

Далее получаем количество строк, содержащих конфигурационный параметр password. Подсчет нужных строк можно выполнить командой grep с ключом -c

COUNT=`cat $1|grep "password" -c`

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

...
if [ $COUNT -eq 1 ]; then # strochek s parolem 1
...

Если строка найдена, и она одна, то продолжаем работу, иначе выдаем сообщение об ошибке и выходим из функции:

...
else #>1 ili 0
echo " Peer file format error"
fi
...

Извлекаем содержащийся в конфигурационном файле пароль в переменную FILEPASS:

FILEPASS=`cat $1|grep "password"|awk ' {print $2} '|sed 's/\"//g'`

1. Читаем файл с помощью команды cat: cat $1
2. Отфильтровываем строку с паролем: grep "password"
3. Извлекаем пароль (в кавычках) с помощью awk: awk ' {print $2} '
4. С помощью sed удаляем кавычки: sed 's/\"//g'`

Далее сравниваем содержимое переменной FILEPASS, т.е. пароль из обрабатываемого файла конфигурации, с паролем, полученным с сайта vpnbook. Он в переменной VPNBOOKPASS.

...
if [ "$FILEPASS" = "$VPNBOOKPASS" ]; then #proverka parolya

Если пароли идентичны, то выдаем сообщение, что пароль не изменен. Иначе, делаем копию файла конфигурации (cp $1 $1".bak") и заменяем пароль с помощью sed непосредственно в обрабатываемом файле (ключ -i и указание пути к файлу в качестве последнего параметра команды):

sed -i 's/'$FILEPASS'/'$VPNBOOKPASS'/g' $1 #replace password

Попутно выводим сообщения о ходе процесса.

Готовый скрипт

1. На PasteBin
2. Скачать с Mega.NZ

Используемые источники

1. Команда head
2. Однострочные скрипты sed
3. Удаление кавычек с помощью sed
4. Краткое описание awk

[Скачать копии источников в формате PDF]
Заметка в формате PDF

Создание загрузочного образа диска DOS в Slackware Linux

Продолжая тему загрузочных образов.
Расскажу, как сделать загрузочный образ диска DOS в который можно добавить свои программы, загружаемый по сети или с CD-диска. На примере тестового образа, который использовал в одной из предыдущих заметок.
Загрузчик, соответственно, оставлю такой же, какой использовал ранее — SYSLINUX. Вообще SYSLINUX, а точнее memdisk поддерживает кроме ISO загрузку образов дискет и жестких дисков, в т.ч. и сжатых gzip’ом.
С дискетами возникает небольшая проблема — файл образа должен быть строго определенного размера (хотя SYSLINUX поддерживает и нестандартные размеры дискет, но все равно они должны быть строго определенными), в образе дискеты, естественно, не может быть два логических раздела и т.д. Чтобы не заморачиваться с этими ограничениями, буду делать образ жесткого диска, его размер можно определить произвольно, главное, чтоб влез в память машины, на которой его потом будем загружать.

Подготовка системы

1. Устанавливаем простенькую виртуальную машину QEMU, для DOS ее вполне хватит.
2. Устанавливаем multipath tools, для того, чтобы получить доступ к файлам, расположенным в образе диска из Linux (ну если мы хотим добавить в образ какие-нибудь программы). У меня multipath tools были уже установлены, ибо нужны для работы с шифрованными контейнерами truecrypt/tcplay
Я установил необходимые программы с помощью менеджера sbopkg без всяких дополнительных опций при сборке.
3. Если будем работать на удаленной машине через SSH, то настраиваем X11-forwarding
4. Создаем отдельный каталог в котором разместим необходимые образы дисков
5. Скачиваем выдранный из Hiren’s boot CD образ с досовыми утилитами. Или делаем его сами, как я описывал ранее
6. Проверяем, все ли работает, запускаем с досом, выдранным из HBCD:

qemu-system-i386 -cdrom dos.iso -boot d
где:
qemu-system-i386 — программа QEMU для 32-разрядных систем. В 64-разрядной версии Linux необходимо использовать команду qemu-system-x86_64
-cdrom — указываем программе местонахождение ISO-образа диска (тут dos.iso, расположенный в текущем каталоге).
-boot d — указываем программе, что необходимо грузиться с виртуального CDROM’а (из указанного образа диска).

Должно получиться как-то так:


Во втором меню нужно выбрать пункт Next, далее File Managers и Volkov commander
Если Volkov Commander успешно загрузился, то закрываем QEMU и приступаем к созданию образа диска DOS

Создание образа

Первым делом создаем пустой файл (заполненный нолями) нужного размера, например 10 мегабайт. Делается это с помощью стандартной утилиты dd
dd if=/dev/zero of=diskc.img bs=10M count=1
Грузимся опять в QEMU с ISO-образа, но подключив созданный образ диска:
qemu-system-i386 -cdrom dos.iso -hda diskc.img -boot d
Выбираем в загрузочном меню HBCD Volkov Commander
Продолжение со множеством иллюстраций под катом

Готовый образ можно сжать gzip’ом, включить в состав загрузочного ISO-образа или загружать по сети. Пример конфига для ISOLINUX описан здесь

Примеры

Как и что можно таким образом запускать:


Acronis Disk Director for DOS


Acronis True Image for DOS

Скачать

Готовый образ диска
Заметку в формате PDF

Домашний FTP-сервер на Slackware и PureFTPd.

Введение

Когда-то давно поднимал вопрос создания простенького FTP-сервера для домашнего и мелкоофисного использования на Puppy Linux Slacko. Как-то незаметно настало время улучшить и углУбить мануал, и сделать такой же сервер, но на Slackware. Собственно программное обеспечение сервера решено оставить то же — PureFTPd. Ибо уже и какой-никакой опыт в настройке есть, и мануалов в сети много. Тут такая мини-инструкция, больше для себя, где я попытался воедино свести информацию из различных источников. К сожалению, не во всех все подробно описано, посему сперва столкнулся с некоторыми неочевидными глюками, и чтоб не гуглить потом все в разных местах, сам решил свести воедино все свои пометки в рабочем блокноте в данной заметке.
Сразу говорю, вопрос шифрования трафика, FTP через SSL в данной заметке благополучно упущен по причине ненадобности. Для общего доступа из Интернета данный сервер и не планировался, а для того, чтобы не бегать с флешками между десятком-другим компов, хранить бэкапы, дистрибьютивы софта, его как раз должно хватить.
Почему FTP, а не Samba? Не знаю, но FTP мне показался более простым в настройке, плюс универсальней — клиент FTP есть из коробки во всех «больших» ОС, начиная от Windows XP и кончая почти всеми Линуксами и MacOS, плюс FTP-клиент достаточно быстро прикручивается и к мобильным системам. Во всяком случае, подружить Android и iOS с FTP оказалось менее муторно, чем заставить нормально работать мобильные девайсы с расшаренными директориями в Samba на Linux, или с расшаренными папками в Windows.

Важные примечания

ВАЖНО! Перед установкой и настройкой сервера, открываем файл /etc/shells и проверяем в нем наличие строки /bin/false Если ее нет — смело дописываем.
Если данной строки нет, то при настройке могут проявиться всякие странные глюки. Например, на одном из дистрибьютивов пользователя для FTP-сервера удалось создать только с помощью скрипта-обертки adduser, а пользователи, созданные командой useradd, почему-то получали отлуп при входе на FTP, несмотря на верное имя пользователя и пароль (и прочих верных параметрах). Хотя и adduser (хоть и переспрашивая) и useradd (ничего не спрашивая) позволяли отключить пользователю FTP оболочку, задав вместо нее /bin/false. Так и не понял, какую магию добавлял скрипт-обертка, хотя параметры утилиты useradd были идентичными

Примечание. Забегая вперед, скажу, что у PureFTPd есть замечательный механизм виртуальных пользователей. Он позволяет не плодить в системе кучу Linux-пользователей, которым нужно обеспечить доступ к FTP, а вместо этого создать всего одного, из-под которого будет работать сколь угодно виртуальных. Необходимые параметры виртуальным пользователям (имя, пароль, рабочий каталог FTP, объем выделенного дискового пространства, скорость закачки файлов) задаются с помощью утилиты pure-pw, входящей в пакет PureFTPd, ею виртуальные пользователи также добавляются и удаляются.

ВАЖНО! Далее приводится инструкция по минимальной настройке FTP-сервера для дома или малого офиса. Настоятельно рекомендуется ознакомиться с полной версией инструкции к PureFTPd, если вы хотите открыть доступ к нему в Интернет и других общедоступных сетях, а также с инструкцией, как обеспечить работу FTP с шифрованием трафика (FTP через SSL).

Подготовка системы к настройке FTP-сервера

Итак, приступим. Естественно, все делается через консоль под root

1. Проверяем наличие строки /bin/false в файле /etc/shells
2. Устанавливаем PureFTPd. Лично я установил его с помощью sbopkg, без дополнительных параметров при сборке пакета. Все заработало.
3. Создаем группу для пользователей FTP:

groupadd ftpgroup

где:
ftpgroup — название группы для пользователей FTP, можете вместо ftpgroup вписать любое уникальное название группы. Уникальное — значит, такой группы в системе не должно быть.

4. Создаем Linux- (системного, реального) пользователя для FTP. Этому пользователю для пущей безопасности (и корректной работы с виртуальными пользователями FTP) следует отключить командную оболочку и задать несуществующий домашний каталог. Добавляем нового пользователя в систему командой useradd:

useradd -g ftpgroup -d /dev/null -s /bin/false ftpuser

где:
-g ftpgroup — указывается группа пользователя, необходимо вместо ftpgroup подставить ту, которую вы задали для пользователей FTP-сервера.
-d — указание домашнего каталога, данному пользователю он не нужен, посему указываем /dev/null
-s
— указание командной оболочки, используемой данным пользователем. Пользователь сам входить в систему не должен (и не будет для пущей безопасности), посему отключим ему доступ к командной оболочке, указав в данном параметре /bin/false
ftpuser — имя пользователя, можете выбрать любое по зову сердца, почек и печени.

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

Настройка PureFTPd

Сам демон FTP-сервера, будучи довольно универсальным для любых Linux- и даже Windows-based операционных систем сделан по принципу максимальной переносимости, посему он не признает as is конфигурационных файлов или конфигурационных каталогов. Для удобства пользователей разработчики (или сборщики) пакетов предусмотрели, что демон будет запускаться не напрямую, а через инициализационный скрипт, различный для конкретной ОС или ее дистрибьютива. Поэтому, если вы пользуетесь инициализационным скриптом, то способ конфигурирования будет различен для, например, Debian/Ubuntu или Slackware. Вы всегда можете обойти эти ограничения, запустив демон напрямую, и передав ему конфигурацию в соответствующих параметрах командной строки. НО в данной заметке такой способ не рассматривается, для управления (запуска, проверки статуса, остановки) демона, используется поставляемый в пакете для Slackware инициализационный скрипт, анализирующий соответствующий конфигурационный файл, разбирающий его и передающий конфигурацию демону.

Скрипт запуска: /etc/rc.d/rc.pure-ftpd
Его параметры: /etc/rc.d/rc.pure-ftpd start запуск FTP-сервера
/etc/rc.d/rc.pure-ftpd stop остановка FTP-сервера
/etc/rc.d/rc.pure-ftpd restart перезапуск FTP-сервера

Файл конфигурации: /etc/pure-ftpd/pure-ftpd.conf

Можно много чего отконфигурировать, подключить базы MySQL или Постгресс, устроить аутентификацию через LDAP, установить квоты, но всего этого я делать не буду, если кому надо — конфигурационные файлы замечательно откомментированы, а подробных мануалов в сети есть. Комментарии в оригинале на буржуйской мове, но там даже ребенок через гугль-транслейт переведет. Я буду делать, повторяюсь, домашний сервер с виртуальными FTP-пользователями.

В файле конфигурации, раскомментируя соответствующие строчки, или заменяя yes на no (или наоборот), настраиваем следующие параметры:

#Не позволять пользователю выходить за пределы домашнего каталога
ChrootEveryone yes

#Отключить режим совместимости с "неправильными клиентами". Мне такие не попадались.
BrokenClientsCompatibility no

#запускать в режиме демона
Daemonize yes

#подробный LOG, можно поставить в no, если все работает, а FTP сильно загаживает логи
VerboseLog yes

#Анонимы дома не нужны (установка в yes включает полностью анонимный доступ к FTP)
AnonymousOnly no

#Отключаем возможность соединяться анонимно
NoAnonymous yes

#ОБЯЗАТЕЛЬНО раскомментируем эту строчку, задаем путь к базе данных виртуальных пользователей (можно путь не задавать, оставив, как есть)
PureDB /etc/pure-ftpd/pureftpd.pdb

#Обязательно комментируем эту строчку (или ставим соответствующее значение в no)
# PAMAuthentication yes

# и эту тоже комментируем, нефиг FTP соваться в системный файл аутентификации - пусть сам рулит виртуальными пользователями, которые специально для FTP
# UnixAuthentication yes

#автоматическое создание домашней директории для пользователя (при первом заходе на сервер)
CreateHomeDir yes

#использовать только IPv4, вряд ли в домашней или сети мелкого офиса нужен IPv6
IPV4Only yes

Готовый конфиг можно скачать здесь . Или посмотреть на PasteBin

Добавление виртуального пользователя

Делается это следующей командой:
pure-pw useradd miguel -u ftpuser -g ftpgroup -d /home/ftp/files
где:
useradd — команда добавления виртуального пользователя
miguel — имя виртуального пользователя, будет использоваться FTP-клиентом для подключения к FTP-серверу. Естественно, можно придумать свое.
-u ftpuserреальный linux-пользователь, под которым будет работать данный виртуальный (см. выше).
-g ftpgroup — группа пользователей FTP-сервера (см. выше)
-d /home/ftp/files — директория для создаваемого виртуального пользователя. Если параметр CreateHomeDir в конфигурационном файле сервера не закомментирован и установлен в yes, то директория будет создана автоматически при первом входе данного пользователя через FTP-клиент.

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

Можно создать неограниченное количество виртуальных пользователей, работающих из под одного реального с разными каталогами. Если установлен в yes параметр ChrootEveryone, то виртуальные пользователи не смогут перейти в каталоги других виртуальных пользователей, соответственно, мы можем наделать персональных директорий в FTP хоть для каждого устройства/конкретного пользователя, меняя только имена, пароли и домашние каталоги.

Примечание: Когда нужно дать доступ к одному и тому же каталогу нескольким пользователям, то просто в команде создания пользователя, после параметра -d указывается одинаковый путь.

ВАЖНО! После любых изменений (добавления, удаления, смены пароля, и т.д.) виртуальных пользователей, необходимо выполнить команду обновления/создания базы виртуальных пользователей:

pure-pw mkdb

Создание пользователя только для чтения

Иногда полезно иметь пользователя, способного только читать что-либо с FTP-сервера, но не имеющего возможности на него что-нибудь писать. Представим себе такую гипотетическую ситуацию, есть Миша, который завел себе домашний FTP-сервер, на нем виртуального пользователя под именем miguel, но к нему домой приходит множество друзей с ноутбуками, планшетами и прочими устройствами. На FTP-сервере хранятся фотографии Миши, но он не хочет, чтобы друзья пририсовали ему усы на этих фото. Как же быть?

1. Предположим, что пользователь для чтения-записи (в нашем случае miguel) уже создан, и он уже совершил вход и загрузку хотя бы одного файла через FTP-клиент, соответственно каталог создан, и права на него уже установлены в 755, иначе потом вручную придется переставлять права.
2. Создаем второго реального пользователя в группе ftpgroup:

useradd -g ftpgroup -d /dev/null -s /etc ftpuserread

3. Создаем виртуального пользователя, имеющего права только на чтение общего каталога с пользователем ftpuser (и соответственно, с виртуальным пользователем miguel, работающим в реальной системе из под соответствующего реального пользователя):

pure-pw useradd friends -u ftpuserread -g ftpgroup -d /home/ftp/files

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

pure-pw mkdb

В процессе создания пользователя friends можно задать для него пустой пароль, тогда получится псевдо-анонимный доступ. Друзьям можно дать имя пользователя, и они на FTP-сервер смогут войти без пароля (введя в своих FTP-клиентах пустую строку), а враги, гады, ведьма-соседка и рептилоиды из SCP будут долго подбирать имя пользователя, или же гоняться за всей вашей компанией с паяльниками. 🙂

Смена пароля для виртуального пользователя FTP

Для смены пароля используем следующую последовательность команд:

pure-pw passwd miquel
pure-pw mkdb

где:
pure-pw passwd miquel — команда смены пароля, вместо miquel необходимо подставить имя нужного виртуального пользователя FTP, пароль будет предложено вести, символы не отображаются.
pure-pw mkdb — обновляем базу данных.

Другие часто используемые команды

pure-pw list — список виртуальных пользователей
pure-pw show username — подробная информация о пользователе, вместо username подставить существующее имя виртуального пользователя
pure-pw userdel username — удаление виртуального пользователя, вместо username подставить существующее имя виртуального пользователя

Краткую инструкцию по командам можно получить, запустив утилиту управления пользователями (pure-pw) с ключом --help

После каждой операции с виртуальными пользователями не забываем выполнить команду обновления базы:
pure-pw mkdb

Источники

1. Установка и настройка Pure-FTPD (Pure FTP) [Копия в PDF]
2. Официальный мануал PureFTPd
3. Slackbook
4. Не помню.

Скачать эту заметку в формате PDF