Показаны сообщения с ярлыком linux. Показать все сообщения
Показаны сообщения с ярлыком linux. Показать все сообщения

среда, 17 августа 2016 г.

nDPI, DKMS и здоровый сон сисадмина

DKMS (Dynamic Kernel Module Support) — шикарное решение, если требуемый модуль для ядра нельзя поставить и обновлять штатными средствами, но зато есть его исходники. Не требуется следить за обновлениями ядра и оперативно пересобирать нужный модуль или вовсе блокировать обновления ядра, чтобы ничего не отвалилось после очередного обновления.

Сначала устанавливаем dkms и другие необходимые пакеты:

$ sudo apt-get install dkms build-essential autoconf automake autogen libpcap-dev libtool xtables-addons-dkms pkg-config xtables-addons-source
Скачиваем исходники nDPI:
$ wget https://github.com/vel21ripn/nDPI/archive/netfilter.zip
Распаковываем скачанный архив в /usr/src:
$ sudo unzip netfilter.zip -d /usr/src
Переименовываем распакованную папку в ndpi-x.y.z, где x.y.z — версия модуля:
$ sudo mv /usr/src/nDPI-netfilter /usr/src/ndpi-1.7.0
Создаем файл dkms.conf в этой папке:
$ sudo tee /usr/src/ndpi-1.7.0/dkms.conf << EOF
# Версия модуля 
PACKAGE_VERSION="1.7.0"
# Название модуля в /usr/src
PACKAGE_NAME="ndpi"
# Папка для компиляции
BDIR="\${dkms_tree}/\${PACKAGE_NAME}/\${PACKAGE_VERSION}/build"
# Аргументы для make 
ARGS="-C \${kernel_source_dir} SUBDIRS=\${BDIR} M=\${BDIR}/ndpi-netfilter/src"
# После компиляции созданный модуль перемещается туда, где DKMS может его найти
MAKE[0]="make \${ARGS} modules ; find \${BDIR} -name '*.ko' -exec mv -v {} \${BDIR} \;"
CLEAN="make \${ARGS} clean"
# Название модуля ядра
BUILT_MODULE_NAME[0]="xt_ndpi"
# Папка, где обычно устанавливается модуль в ядре
DEST_MODULE_LOCATION[0]="/extra/"
# Не пересобирать initrd ядра
REMAKE_INITRD="no"
# Установка модуля после компиляции
AUTOINSTALL="yes"
EOF
Теперь компилируем и устанавливаем библиотеку nDPI
$ cd /usr/src/ndpi-1.7.0
$ sudo ./autogen.sh
$ sudo sh -c './configure && make'
$ cd /usr/src/ndpi-1.7.0/ndpi-netfilter
$ sudo make install
После чего в DKMS добавляем запись о нашем модуле:
$ sudo dkms add -m ndpi -v 1.7.0
Собираем модуль из исходников:
$ sudo dkms build -m ndpi -v 1.7.0
Собранный модуль устанавливаем папке /dkms/:
$ sudo dkms install -m ndpi -v 1.7.0

вторник, 10 декабря 2013 г.

Установка параметров загрузки ядра Linux с помощью Grub

  1. В grub до версии 0.97 включительно
    В файле «/boot/grub/menu.lst» найти строку, начинающуюся с «# kopt=» и дописать в её конец через пробел новый параметр:
    # kopt=root=/dev/sda1 ro newparameter=newvalue

    В grub2 до версии 1.99 включительно
    Добавить (изменить) переменную «GRUB_CMDLINE_LINUX_DEFAULT» в файле «/etc/default/grub» и вписать через пробел новый параметр, как в примере:
    GRUB_CMDLINE_LINUX_DEFAULT="quiet newparameter=newvalue"
  2. Далее обновить grub командой:
    $ sudo update-grub

вторник, 12 ноября 2013 г.

Переадресация некоторых портов в VoIP-шлюзе Audiocodes MP-202

Чтобы в VoIP-шлюзе Audiocodes MP-202 переадресовать порты 80, 8080 или 443 на сервер внутри локальной сети, кроме соответствующих настроек в разделе «Переадресация портов», в разделе «Системные настройки» требуется изменить совпадающие порты для удаленного управления.

воскресенье, 24 марта 2013 г.

NAT для VirtualBox с возможностью прямого доступа к виртуальным машинам с хоста

Когда создавал новую виртуальную машину в Virtualbox (Ubuntu 12.04 LTS) решил спрятать его за NAT в виртуальной сети, но таким образом чтобы иметь возможность достучаться до него напрямую через SSH.
Для этой цели поднял виртуальный сетевой интерфейс, настроил NAT, настроил раздачу айпи и обработку DNS-запросов создаваемой виртуальной сети:

  1. Устанавливаем пакет uml-utilities с утилитой для создания интерфейса tap0
    $ sudo apt-get install uml-utilities
    В файл «/etc/network/interfaces» добавляем описание нового интерфейса
    auto tap0
    iface tap0 inet static
            address 10.0.55.1
            netmask 255.255.255.0
     pre-up /usr/sbin/tunctl -t tap0
     post-down /usr/sbin/tunctl -d tap0
    Поднимаем новый интерфейс
    $ sudo ifup tap0
  2. Теперь настраиваем NAT. Для этой цели используем идущее с системой средство настройки брандмауэра ufw. Редактируем файл «/etc/ufw/before.rules» и добавляем в самом начале строки
    *nat
    :POSTROUTING ACCEPT [0:0]
    -F POSTROUTING
    -A POSTROUTING -s 10.0.55.0/24 -j MASQUERADE
    COMMIT
    Редактируем файл «/etc/default/ufw» и меняем следующие параметры
    DEFAULT_INPUT_POLICY="ACCEPT"
    DEFAULT_OUTPUT_POLICY="ACCEPT"
    DEFAULT_FORWARD_POLICY="ACCEPT"
    Запускаем ufw
    $ sudo ufw enable
  3. Чтобы каждый раз вручную не прописывать айпишники днс-сервера вновь созданным виртуальным машинам устанавливаем dnsmasq
    $ sudo apt-get install dnsmasq
    В файл конфигурации «/etc/dnsmasq.conf» добавляем следующие строки
    # Слушаем порты только на указанном интерфейсе
    bind-interfaces
    # Слушаем на созданном нами интерфейсе
    interface=tap0
    # Не слушаем на локальном интерфейсе. Там как правило слушает запущенный Netwok Manager процесс dnsmasq
    except-interface=lo
    # Диапазон раздаваемых по DHCP адресов виртуальным машинам.
    dhcp-range=10.0.55.10,10.0.55.200,72h
    # Домен создаваемой сети
    domain=virtual
    Запускаем dnsmasq с новыми настройками
    $ sudo service dnsmasq stop
    $ sudo service dnsmasq start

понедельник, 5 декабря 2011 г.

Синтаксис команды route в Android

  • route add default dev DEVICE
  • route add default gw IP dev DEVICE
  • route add -net IP netmask NETMASK gw IP
Нашел здесь: zecke.blogspot.com

четверг, 24 февраля 2011 г.

OpenVZ: Упрощение автомонтирования разделов

Чтобы не писать для каждой гостевой машины по два скрипта, для монтирования и демонтирования разделов или директорий, создал один универсальный для всех. Сохраняем представленный ниже скрипт в директории «/etc/vz/scripts» под именем «mount» и назначаем ему права на выполнение. Далее, в директории «/etc/vz/conf» создаем симлинки скрипта под именем «VEID.mount» и «VEID.umount», где VEID – идентификатор гостевого хоста. В этой директории создаем еще один файл под именем «VEID.fstab», где прописываем монтируемые разделы в формате «fstab». Обратите внимание, что точки монтирования должны указываться с корневого раздела «/» гостевого хоста.

Собственно сам скрипт:

#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

source /etc/vz/vz.conf
source ${VE_CONFFILE}

FSTAB="$(dirname $0)/${VEID}.fstab"
ACTION="$(basename $0 | sed -r 's/^[^\.]+\.//')"

if [ -e "$FSTAB" ]
then
        if [ $ACTION = "mount" ]
        then
                cat "$FSTAB" | sed -r "/^(#|$)/d" | \
                        awk -v VE_ROOT="${VE_ROOT}" '{ print "-t " $3 " -o " $4 " " $1 " " VE_ROOT $2; }' | \
                        xargs -n 1 -d'\n' -I{} sh -c 'echo mount {}; /bin/mount {};'
        elif [ $ACTION = "umount" ]
        then
                cat "$FSTAB" | sed -r "/^(#|$)/d" | \
                        awk -v VE_ROOT="${VE_ROOT}" '{ print VE_ROOT $2; }' | \
                        xargs -n 1 -d'\n' -I{} sh -c  'echo umount {}; /bin/umount {};'
        fi
fi

exit 0

понедельник, 13 сентября 2010 г.

Чемезов – Медведеву: национальная программная платформа создается на базе «Альт Линукс»

На встрече президента России Дмитрия Медведева и главы «Ростехнологий» Сергея Чемезова обсуждалось внедрение свободного программного обеспечения. «Я ещё когда в правительстве работал, начал заниматься вопросами свободного программного обеспечения, - напомнил Медведев. - Тогда мы некоторые программы подготовили и передали в школы, университеты. В общем, это дело пошло, тем более что, если прикинуть, то наши образовательные структуры тратят большие деньги, это, наверное, сотни миллионов долларов в годовом исчислении на приобретение программных продуктов у основных грандов производства. Это не всегда правильно, тем более, что СПО так называемое по своему качеству не хуже, а зачастую, то, что называется интерфейсом, то есть оболочкой, даже удобнее для общения, для того чтобы работать».
Чемезов сообщил, что в «Ростехнологиях» был создан ИТ-холдинг «Сириус». «В него вошло новое предприятие, которое является создателем как раз свободного программного обеспечения – «Альт Линукс». И на базе вот этого предприятия мы сейчас создаем нашу национальную программную платформу», - заявил он.
- На базе общей платформы Linux? – уточнил Медведев. - Да, общей платформы, - подтвердил Чемезов. - Потому что нам не нужно создавать чего-то отдельного, это всё-таки линуксовская платформа, но с нашей спецификой, - заключил президент.
В качестве примера, по словам Чемезова, национальная программная платформа внедряется в трёх областях – Самарской, Новгородской и Тульской. «Тоже на базе «Альт Линукс», - добавил Дмитрий Медведев. - Это важно по разным причинам, потому что это всё-таки вопросы безопасности. Потому что зачастую обладатели прав на соответствующие продукты крупных программных компаний, они не передают коды. При возникновении каких-то проблем либо мы не можем настроить системы. А если говорить о более сложных системах, включая оборонные системы, это просто небезопасно».
«Национальная программная платформа – это широкое понятие, его нельзя представлять как исключительно дистрибутив для десктопов и серверных подразделений, - объясняет Алексей Новодворский, заместитель генерального директора «Альт Линукс». – Это и решения для клиентских устройств, начиная со смартфонов, и системы для датацентров и суперкомпьютеров».

Источник: CNews

суббота, 3 июля 2010 г.

Первый стабильный релиз системы распознавания текстов Cuneiform 1.0

Вышла первая стабильная версия системы распознавания текста Cuneiform для платформы Linux. В новой версии проведена большая работа по исправлению ошибок и чистке исходных текстов, что дало разработчикам основание полагать о стабилизации кодовой базы проекта. Код Cuneiform для Linux распространяется под упрощенной лицензией BSD и основан на коде, открытом компанией Cognitive Technologies в 2007 году.

OCR CuneiForm может распознавать любые полиграфические, машинописные гарнитуры всех начертаний и шрифты, получаемые с принтеров за исключением декоративных и рукописных. В систему встроены специальные алгоритмы для распознавания текста с матричного принтера, плохих ксерокопий факсов и машинописи. Поддерживается более чем 20 языков. Отдельно стоит отметить отличную поддержку распознавания текста на русском и украинском языках. Результат распознавания может быть сохранен в форматах HTML, hOCR, RTF или PDF с сохранением особенностей начертания оригинала (выделение жирным, курсивом и т.д.).

Источник: www.opennet.ru

понедельник, 26 апреля 2010 г.

Некорректная работа mountall с разделами на LVM

На днях, решив обновить Ubuntu до версии Lucid Lynx, не предполагал, что он преподнесет головоломку, на поиск решения которого уйдет два дня.
Утилита mountall, установленная из официального репозитория, начала некорректно работать с созданными в LVM разделами. При загрузке системы они начинают теряться случайным образом. Т.е. глюк не всегда появляется. А когда появляется, начинает радовать сообщениями вроде «the disk drive for ... is not ready yet or not present».
Решение нашел тут:


  1. Подключаем PPA-репозиторий с исправлениями
    $ sudo add-apt-repository ppa:scott/ppa

  2. Обновляем индексы
    $ sudo apt-get update

  3. Обновляем систему
    $ sudo apt-get upgrade

  4. Проверяем версию mountall, оно должно быть не ниже 2.14~ppa1
    $ dpkg-query -W mountall

вторник, 13 апреля 2010 г.

Watchdog для контроля состояния линка

Для контроля состояния линка будем пинговать шлюз провайдера. Утилита ping, идущая вместе с FreeBSD и Linux, нам не подходит, т.к. не выдает никаких сообщений при отсутствии ответа проверяемого хоста. То есть нам требуется поведение присущее ping из windows, выводящей в аналогичном случае «timeout». После недолгих поисков утилита oping оказалась идеальным кандидатом.
Собственно шаблон скрипта с подробными комментариями:

#!/bin/sh
# $1 - проверяемый IP-адрес
# $2 - режим работы скрипта

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Выходим если не задан проверяемый IP
if [ -z $1 ]; then exit 1; fi

# Проверка режима работы
if [ -z $2 ]
then
# Отслеживание падения линка

# Создаем временный файл для хранения статуса линка
SAVE=$(mktemp)
# Ловим сигнал завершения и удаляем файл статуса
trap 'rm -f $SAVE; exit 0;' INT TERM QUIT
# Пингуем заданный IP-адрес с интервалом в 5 секунд
# и с помощью xargs вызываем самого себя, передавая
# результат пинга и имя файла состояния как параметры
# командной строки.
oping -4 -i 5 $1 | \
sed \
-e '1d' -e '/^--- /d' \
-e '/packets transmitted/d' \
-e '/^$/d' -u | \
xargs -n 1 --delimiter='\n' -I'{}' $0 none check "{}" $SAVE \
>> /var/log/vpn-watchdog.log
# Удаляем файл статуса
rm -f $SAVE
elif [ $2 = check -a ! -z $4 ]
then
# Watchdog
# $3 - результат пинга
# $4 - имя файла состояния

# Получение состояния линка
STATUS=$(echo $3 | grep -oE '(ms|timeout)$')
# Сравнение
if [ ! -z "$STATUS" ]
then
# Определение состояния линка и исключение
# ложного срабатывания
if [ "$STATUS" = timeout -a "$(cat $4)" != $STATUS ]
then
# Реакция на событие
echo -n "$(date +'%Y-%m-%d %H-%M-%S') TIMEOUT - Restarting... "
# Далее идет несколько строк команд
# ...
echo " done!"
fi
# Сохраняем текущее состояние для последующей проверки
echo -n $STATUS > $4
fi
fi
Достоинства данного подхода: не требуется вызывать из крона по расписанию, мониторинг идет непрерывно и, если требуется, время реакции на событие может составить одну-две секунды.

воскресенье, 31 января 2010 г.

Общесистемные настройки Mozilla Firefox

Общесистемные настройки Mozilla Firefox хранятся в директории «/etc/firefox-3.x», где 3.x - версия браузера.
Для примера отключим режим «Safe Browsing». Браузер с включенным «Safe Browsing» может выкачать от 3 до 11 мегабайт данных в день, используемых для оценки безопасности сайтов.
Открываем файл «/etc/firefox-3.x/pref/firefox.js» и в конец файла добавляем эти строки

// Отключаем Safe Browsing
pref ("browser.safebrowsing.enabled", false);
pref ("browser.safebrowsing.malware.enabled", false);

суббота, 14 ноября 2009 г.

Запрет запуска второй копии скрипта

Пример кода с пояснениями

#!/bin/sh

pid_file=/tmp/script-name.pid

#########################
# Создаем файл с правом только на чтение
# и вписываем туда идентификатор процесса (pid)
umask 333
(echo $$ > "$pid_file") 2>/dev/null

#########################
# Если процесс уже запущен, то попытка записи pid
# в файл будет завершена с ошибкой
if [ $? -ne 0 ]
then
umask 22

echo "Already started :("
exit 1
fi

umask 22
#########################
# Что-то долго делаем...
#########################

#########################
# Удаляем файл с pid
rm -f "$pid_file"

воскресенье, 1 ноября 2009 г.

WiFi vs Ubuntu Karmic Koala

Радость от обновления Ubuntu на своем ноутбуке (Dell Vostro A860) до версии 9.10 Karmic Koala омрачилась нерабочим вайфаем. Причем в логах наблюдалась абсолютная тишина. Модуль ath5k грузится без ошибки и правильно распознает чип от Atheros. А Network Manager скупо пишет "Устройство не готово".
После продолжительного гугления выяснилось, что все дело в некорректной работе функциональной кнопки (Fn + F11), отвечающей за включение/отключение вайфая и блютуза. К слову – я им никогда и не пользовался, так как казалось, она как-то не так работает.

$ tail /sys/class/rfkill/*/{state,name,type,persistent}
==> /sys/class/rfkill/rfkill1/state <==
0

==> /sys/class/rfkill/rfkill2/state <==
0

==> /sys/class/rfkill/rfkill3/state <==
0

==> /sys/class/rfkill/rfkill1/name <==
phy0

==> /sys/class/rfkill/rfkill2/name <==
dell-wifi

==> /sys/class/rfkill/rfkill3/name <==
dell-bluetooth

==> /sys/class/rfkill/rfkill1/type <==
wlan

==> /sys/class/rfkill/rfkill2/type <==
wlan

==> /sys/class/rfkill/rfkill3/type <==
bluetooth

==> /sys/class/rfkill/rfkill1/persistent <==
0

==> /sys/class/rfkill/rfkill2/persistent <==
0

==> /sys/class/rfkill/rfkill3/persistent <==
0
Как видим, rfkill1 и rfkill2 имеют тип wlan. Состояние (state) у обоих равно 0, означающему SOFT LOCK. Кроме состояния 0 могут быть 1 и 2, UNLOCK и HARD LOCK соответственно.
Вся проблема состоит в том, что при нажатии на упомянутую ранее функциональную кнопку состояние переключается только между значениями SOFT LOCK и HARD LOCK, минуя UNLOCK. Из-за этого блокируется переход интерфейса файвая в активный режим, наглядно демонстрируемый командой
$ sudo ifconfig wlan0 up
SIOCSIFFLAGS: Unknown error 132
Решение состоит в принудительном переводе в состояние UNLOCK.
Для этого пишем простой скрипт
#!/bin/sh

for i in /sys/class/rfkill/rfkill*/type;
do
type="`cat $i`"
if [ "$type" = "wlan" ];
then
n="`echo $i | sed -r 's%/type$%%'`";
echo 1 > ${n}/state;
fi;
done;
Сохраняем скрипт в файл «/usr/local/sbin/unlock-wlan» и делаем его исполняемым
$ sudo chmod +x /usr/local/sbin/unlock-wlan
После ручного запуска скрипта надо перезапускать Network Manager – иначе он ничего не заметит.
Теперь настраиваем Upstart для исполнения нашего скрипта при загрузке системы, перед стартом Network Manager. Для этого создаем файл «/etc/init/unlock-wlan.conf»
# unlock-wlan - unlock wireless device
#

description "unlock wireless device"

# Скрипт запускается перед настройкой сетевых интерфейсов
start on starting networking

task

exec /usr/local/sbin/unlock-wlan

суббота, 27 июня 2009 г.

Какой дистрибутив установлен linux на компьютер

можно узнать с помощью утилиты lsb_release.
Пример использования

$ lsb_release -irc
Distributor ID: Ubuntu
Release: 9.04
Codename: jaunty
Если этой утилиты в исследуемой системе нет, то версию дистрибутивов, основанных на Debian/RedHat/Gentoo можно узнать так (спасибо Ярославу Шаповалу)
$ cat /etc/*release*
в дистрибутивах, основанных на Slackware
$ cat /etc/slackware-version
в SUSE
$ cat /etc/issue

суббота, 13 июня 2009 г.

Настройка DHCP клиента в Ubuntu

Дополнительная настройка DHCP-клиента может понадобится когда у вас есть локальный DNS-сервер или если DHCP-сервер провайдера работает с перебоями.

Пример файла конфигурации «/etc/dhcp3/dhclient.conf»

#
# dhcp3-client 3.1.1-5ubuntu8
#
# Сюда вписываем локальный адрес DNS-сервера
prepend domain-name-servers 127.0.0.1;

# Какие данные нужно затребовать с DHCP-сервера
request subnet-mask, broadcast-address, time-offset, routers,
# Комментируем, так как у нас локальный DNS-сервер
# domain-name, domain-name-servers, domain-search, host-name,
netbios-name-servers, netbios-scope, interface-mtu,
rfc3442-classless-static-routes, ntp-servers;

#
# dhclient будет использовать эти настройки, в то время,
# когда недоступен DHCP-сервер провайдера.
#
# Если не знаете что писать - загляните в файл
# /var/lib/dhcp3/dhclient.leases
#
lease {
interface "eth1";
fixed-address 72.xxx.xxx.xxx;
option subnet-mask 255.255.xxx.xxx;
option time-offset 32400;
# Если прописать адреса роутеров, dhclient проверит наличие
# первого роутера. В случае, если роутер не ответил
# на пинг, этот блок (lease) отбрасывается.
option routers 72.xxx.xxx.1;
option dhcp-lease-time 1800;
option dhcp-message-type 5;
option domain-name-servers 127.0.0.1;
option dhcp-server-identifier 72.xxx.xxx.xxx;
# По документации следующие строки должны быть
# в обязательном порядке. Время желательно
# выставить как можно большее, чтобы не стало
# просроченным.
renew 2 2037/01/12 00:00:00;
rebind 2 2037/01/12 00:00:00;
expire 2 2037/01/12 00:00:00;
}
Более подробно о других настройках можно прочитать в «man dhclient.conf»

понедельник, 8 июня 2009 г.

Работа Ubuntu Linux без носителя

Нужно было добиться загрузки Ubuntu в оперативную память компьютера и дальнейшей работы без носителя, с которого он был загружен. Решение получилось достаточно простым.
Вкратце идея такая: initrd.img изменяется так, чтобы, после загрузки и старта ядра, с носителя в память копировался файл со сжатым образом файловой системы корневого раздела (SquashFS). Далее поверх корневого раздела монтируется aufs-tmpfs и стартует Ubuntu.

Ниже будет описание как создать загрузочный iso-образ и бутовую USB-флешку.

  1. Создаем директории
    $ mkdir -p ~/ubuntu-ram/{etc,tmp,image,scripts}

  2. Устанавливаем необходимые пакеты
    $ sudo aptitude install lilo mtools genisoimage debootstrap syslinux squashfs-tools

  3. Копируем настройки initramfs
    Конфиги initramfs для iso-образа
    $ cp -a /etc/initramfs-tools ~/ubuntu-ram/etc/iso
    Конфиги initramfs для iso-образа
    $ cp -a /etc/initramfs-tools ~/ubuntu-ram/etc/usb

  4. Настраиваем окружение загружаемой системы
    $ export IMGROOT=~/ubuntu-ram/image
    $ sudo -E -s
    # debootstrap jaunty $IMGROOT http://mirror.ubuntu.optilink.ru/ubuntu/
    # echo "aufs / aufs rw 0 0" > $IMGROOT/etc/fstab
    # cp /etc/apt/sources.list $IMGROOT/etc/apt/
    # cp /etc/resolv.conf $IMGROOT/etc/
    # cat <<EOF > $IMGROOT/etc/hosts
    127.0.0.1 localhost.localdomain localhost
    127.0.1.1 hostname.domain hostname
    EOF

    # cat <<EOF > $IMGROOT/etc/network/interfaces
    auto lo
    iface lo loopback
    EOF

    # echo "hostname.domain" > $IMGROOT/etc/hostname
    # mount -t proc none $IMGROOT/proc
    # mount -o bind /dev $IMGROOT/dev
    # mount -t devpts none $IMGROOT/dev/pts
    # mount -t sysfs none $IMGROOT/sys
    Входим в изолированное окружение
    # chroot $IMGROOT bash
    Создаем аккаунт администратора и русскую локаль. Также разрешаем группе adm использование команды sudo
    # adduser --gecos 'System Administrator' demiurg
    # usermod -a -G adm demiurg
    # echo "@adm ALL=NOPASSWD: ALL" >> $IMGROOT/etc/sudoers
    # locale-gen ru_RU.UTF-8
    Устанавливаем ядро и требуемые утилиты
    # aptitude update
    # aptitude install linux-image-server grub aufs-tools squashfs-tools
    Настраиваем часовой пояс и консоль
    # dpkg-reconfigure tzdata
    # dpkg-reconfigure console-setup
    Далее система настраивается под себя (ставим дополнительные программы, правим конфиги под себя).

    Выходим из изолированного окружения
    # aptitude clean
    # exit
    Отмонтируем файловые системы
    # umount $IMGROOT/proc
    # umount $IMGROOT/dev/pts
    # umount $IMGROOT/dev
    # umount $IMGROOT/sys
    Выходим из режима суперпользователя
    # exit
    $

  5. Переходим к настройке конфигов initramfs для iso-образа
    Создаём так называемый хук (hook) - скрипт, вызываемый утилитой initramfs
    $ cat <<EOF > $IMGROOT/../etc/iso/hooks/load_modules
    #!/bin/sh
    set -e

    PREREQ=""

    prereqs () {
    echo "$PREREQ"
    }

    case $1 in
    prereqs)
    prereqs
    exit 0
    ;;
    esac

    . /usr/share/initramfs-tools/hook-functions

    force_load squashfs
    force_load isofs
    force_load aufs

    exit 0
    EOF
    $ chmod +x $IMGROOT/../etc/iso/hooks/load_modules
    Создаем скрипты, выполняющиеся во время загрузки initrd
    Скрипт, закидывающий образ системы в память
    $ cat <<EOF > $IMGROOT/../etc/iso/scripts/init-premount/udev_into_ram
    #!/bin/sh

    PREREQ=""

    prereqs () {
    echo "$PREREQ"
    }

    case $1 in
    prereqs)
    prereqs
    exit 0
    ;;
    esac

    mknod /dev/loop0 b 7 0
    mkdir /disk

    WAIT_COUNT=15
    while [ ! -e /dev/scd0 ] && [ "$WAIT_COUNT" -gt 0 ]
    do
    tmp=$((WAIT_COUNT-=1))
    sleep 1
    done

    echo -n "Please wait... "
    mount -t iso9660 -o ro /dev/scd0 /disk
    cp /disk/root.sqfs /
    echo "done"
    umount /disk && rm -Rf /disk
    EOF
    $ chmod +x $IMGROOT/../etc/iso/scripts/init-premount/udev_into_ram
    Скрипт, монтирующий файловую систему aufs
    $ cat <<EOF > $IMGROOT/../etc/iso/scripts/init-bottom/aufs_root
    #!/bin/sh
    #
    # https://help.ubuntu.com/community/aufsRootFileSystemOnUsbFlash
    #
    # Copyright 2008 Nicholas A. Schembri State College PA USA
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program. If not, see
    # <http://www.gnu.org/licenses/>.

    # Thank you Voyage Linux for the idea, http://voyage.hk/ Great job on release 0.5
    #
    # Tested with 8.04.1
    #
    #
    # ****************************************************************************************
    #
    # Change log
    #
    # 2008.08.01 Added debugging comments in "drop to a shell" section. grub option aufs=tmpfs-debug will stop the init script.
    # reviewed *********** fix fstab on tmpfs ******************
    # rootaufs failed when system was booted with /dev/xxx and fstab had uuid= info.
    # BlaYO pointed out the best and simplest solution was to use grep -v. Grep replaces a sed one liner.
    # Add the comment block to fstab
    #
    #
    #

    case $1 in
    prereqs)
    exit 0
    ;;
    esac

    export aufs

    for x in $(cat /proc/cmdline); do
    case $x in
    root=*)
    ROOTNAME=${x#root=}
    ;;
    aufs=*)
    aufs=${x#aufs=}
    case $aufs in
    tmpfs-debug)
    aufs=tmpfs
    aufsdebug=1
    ;;
    esac
    ;;
    esac
    done

    if [ "$aufs" != "tmpfs" ]; then
    #not set in boot loader
    #I'm not loved. good bye
    exit 0
    fi

    # This is a simple overview of the steps needed to use aufs on the root file system and see the /rw and /ro branches.
    # initramfs init-botton script
    # move the root file system to aufs/unionfs readonly /ro
    # root is mounted on ${rootmnt}
    # create tmpfs on /rw
    # create a aufs using /ro and /rw
    # put some files on the tmpfs to fix mtab and fstab
    # move aufs to rootmnt to finish the init process.
    # No changes to the root file system are made by this script.
    #
    # Why!
    # This will allow you to use a usb flash drive and control what is written to the drive.
    # no need to rebuild the squashfs file just to add a program.
    # boot to single user mode. The system works the way you expect. boot aufs=tmpfs and no changes are written to the flash.
    # run ubuntu on an eeePC .

    # Install
    # Install ubuntu 8.04 Hardy. Hardy has aufs installed by default
    # apt-get update
    # apt-get dist-upgrade
    # apt-get install aufs-tools
    # echo aufs >> /etc/initramfs-tools/modules
    # put this file in /etc/initramfs-tools/scripts/init-bottom/rootaufs
    # chmod 0755 rootaufs
    # # clean up menu.lst
    # update-grub
    # update-initramfs -u
    # vi /boot/grub/menu.lst
    # add aufs=tmpfs to the default entry.
    # do not add this line to single user mode.
    # boot to single user mode in order to install software.
    # note: if your home account is on the root file system, your files are in ram and not saved.
    #


    echo
    echo " root-aufs: Setting up aufs on ${rootmnt} as root file system "
    echo

    modprobe -q --use-blacklist aufs
    if [ $? -ne 0 ]; then
    echo root-aufs error: Failed to load aufs.ko
    exit 0
    fi

    #make the mount points on the init root file system
    mkdir /aufs
    mkdir /rw
    mkdir /ro

    # mount the temp file system and move real root out of the way
    mount -t tmpfs aufs-tmpfs /rw
    mount --move ${rootmnt} /ro
    if [ $? -ne 0 ]; then
    echo root-aufs error: ${rootmnt} failed to move to /ro
    exit 0
    fi


    mount -t aufs -o dirs=/rw:/ro=ro aufs /aufs
    if [ $? -ne 0 ]; then
    echo root-aufs error: Failed to mount /aufs files system
    exit 0
    fi


    #test for mount points on aufs file system
    [ -d /aufs/ro ] || mkdir /aufs/ro
    [ -d /aufs/rw ] || mkdir /aufs/rw

    # the real root file system is hidden on /ro of the init file system. move it to /ro
    mount --move /ro /aufs/ro
    if [ $? -ne 0 ]; then
    echo root-aufs error: Failed to move /ro /aufs/ro
    exit 0
    fi

    # tmpfs file system is hidden on /rw
    mount --move /rw /aufs/rw
    if [ $? -ne 0 ]; then
    echo root-aufs error: Failed to move /rw /aufs/rw
    exit 0
    fi



    #*********** fix fstab on tmpfs ******************
    # test for /dev/sdx
    # this is not on the real file system. This is created on the tmpfs each time the system boots.
    # The init process will try to mount the root filesystem listed in fstab. / and swap must be removed.
    # the root file system must be mounted on /ro not on /

    if [ "$aufsdebug" -eq 1 ]; then
    echo " root-aufs debug: Remove the root file system and swap from fstab "
    echo
    echo
    echo " ROOTNAME $ROOTNAME "
    echo " resume $resume "
    echo
    echo ' BlaYO pointed out that grep can be used to quickly remove '
    echo ' the root file system from fstab. '
    echo
    echo ' Thank you BlaYO for the debug info.'
    echo

    fi
    # old code
    # I'm sure that sed can do this in one step but I want to correct on the rootname not matching the root in fstab.
    #cat /aufs/ro/etc/fstab|sed -e s/$ROOTNAME/\#$ROOTNAME/ -e s/$resume/\#$resume/ >/aufs/etc/fstab

    #Add the comment block to fstab
    cat <<EOF >/aufs/etc/fstab
    #
    # RootAufs has mounted the root file system in ram
    #
    # This fstab is in ram and the real fstab can be found /ro/etc/fstab
    # the root file system ' / ' has been removed.
    # All Swap files have been removed.
    #

    EOF

    #remove root and swap from fstab
    cat /aufs/ro/etc/fstab|grep -v ' / ' | grep -v swap >>/aufs/etc/fstab
    if [ $? -ne 0 ]; then
    echo root-aufs error: Failed to create /aufs/etc/fstab
    #exit 0
    fi




    # add the read only file system to fstab
    #ROOTTYPE=$(/lib/udev/vol_id -t ${ROOT})
    ROOTTYPE=$(cat /proc/mounts|grep ${ROOT}|cut -d' ' -f3)
    ROOTOPTIONS=$(cat /proc/mounts|grep ${ROOT}|cut -d' ' -f4)
    echo /dev/loop0 /ro squashfs ro,relatime 0 0 >>/aufs/etc/fstab

    # S22mount on debian systems is not mounting /ro correctly after boot
    # add to rc.local to correct what you see from df
    #replace last case of exit with #exit
    cat /aufs/ro/etc/rc.local|sed 's/\(.*\)exit/\1\#exit/' >/aufs/etc/rc.local
    echo mount -f /ro >>/aufs/etc/rc.local

    # add back the root file system. mtab seems to be created by one of the init proceses.
    echo "echo aufs / aufs rw,xino=/rw/.aufs.xino,br:/rw=rw:/ro=ro 0 0 >>/etc/mtab" >>/aufs/etc/rc.local
    echo "echo aufs-tmpfs /rw tmpfs rw 0 0 >>/etc/mtab" >>/aufs/etc/rc.local
    echo exit 0 >>/aufs/etc/rc.local


    #build remountrw
    echo \#!/bin/sh >/aufs/bin/remountrw
    echo mount -o remount,rw ${ROOT} >>/aufs/bin/remountrw
    chmod 0700 /aufs/bin/remountrw

    #build remountro
    echo \#!/bin/sh >/aufs/bin/remountro
    echo mount -o remount,ro ${ROOT} >>/aufs/bin/remountro
    chmod 0700 /aufs/bin/remountro

    # This should drop to a shell. (rewrite)
    if [ "$aufsdebug" -eq 1 ]; then
    echo
    echo " root-aufs debug: mount --move /aufs ${rootmnt} "
    echo
    echo ' root-aufs debug: init will stop here. '
    echo
    exit 0
    fi

    mount --move /aufs ${rootmnt}

    exit 0
    EOF
    $ chmod +x $IMGROOT/../etc/iso/scripts/init-bottom/aufs_root
    На этом настройка initramfs заканчивается.

  6. Создаём скрипт, создающий iso-образ и сохраняем его в файле «~/ubuntu-ram/scripts/make-iso.sh»
    #!/bin/sh
    WORKDIR=/path/to/ubuntu-ram
    SQUASHFS_ROOT=$WORKDIR/image/
    ISO_ROOT=$WORKDIR/tmp/

    rm -Rf $ISO_ROOT/*

    # Получаем версию ядра в окружении
    version=$(basename $(readlink $SQUASHFS_ROOT/initrd.img))
    version=${version#initrd.img-}

    mount -o bind $WORKDIR/etc/iso $SQUASHFS_ROOT/etc/initramfs-tools
    chroot $SQUASHFS_ROOT mkinitramfs -v -o /boot/initrd.img-$version $version
    umount $SQUASHFS_ROOT/etc/initramfs-tools

    mkdir $ISO_ROOT/isolinux
    cp $SQUASHFS_ROOT/boot/initrd.img-$version $ISO_ROOT/isolinux/initrd.gz
    cp $SQUASHFS_ROOT/boot/vmlinuz-$version $ISO_ROOT/isolinux/vmlinuz
    cp /usr/lib/syslinux/isolinux.bin $ISO_ROOT/isolinux/
    cat <<EOF > $ISO_ROOT/isolinux/isolinux.cfg
    DEFAULT server
    TIMEOUT 1
    LABEL server
    menu label ^Server
    kernel vmlinuz
    append initrd=initrd.gz root=/root.sqfs loop=/dev/loop0 rootfstype=squashfs aufs=tmpfs ro
    EOF

    #
    mksquashfs $SQUASHFS_ROOT $ISO_ROOT/root.sqfs \
    -e $SQUASHFS_ROOT/boot/* \
    $SQUASHFS_ROOT/initrd.img \
    $SQUASHFS_ROOT/vmlinuz

    # Создаём ISO
    mkisofs -o $WORKDIR/image.iso -r \
    -V "MYUSBSERVER" -v -no-emul-boot \
    -boot-load-size 4 -boot-info-table \
    -b isolinux/isolinux.bin \
    -c isolinux/isolinux.boot $ISO_ROOT
    Делаем его исполняемым
    $ chmod +x ~/ubuntu-ram/scripts/make-iso.sh
    После выполнения скрипта в директории «~/ubuntu-ram» будет создан требуемый iso-образ.

  7. Создание загрузочной USB флешки.
    Создаём хук
    $ cat <<EOF > ~/ubuntu-ram/etc/usb/hooks/load_modules
    #!/bin/sh
    set -e

    PREREQ=""

    prereqs () {
    echo "$PREREQ"
    }

    case $1 in
    prereqs)
    prereqs
    exit 0
    ;;
    esac

    . /usr/share/initramfs-tools/hook-functions

    force_load usb_storage
    force_load squashfs
    force_load vfat
    force_load aufs

    exit 0
    EOF
    $ chmod +x ~/ubuntu-ram/etc/usb/hooks/load_modules
    Копируем скрипт «etc/iso/scripts/init-bottom/aufs_root» в «etc/usb/scripts/init-bottom/aufs_root».
    Пишем скрипт, загружающий систему из USB-флешки в оперативную память
    $ cat <<EOF > ~/ubuntu-ram/etc/usb/scripts/init-premount/udev_into_ram
    #!/bin/sh

    PREREQ=""

    prereqs () {
    echo "$PREREQ"
    }

    case $1 in
    prereqs)
    prereqs
    exit 0
    ;;
    esac

    mknod /dev/loop0 b 7 0
    mkdir /disk

    WAIT_COUNT=15
    while [ ! -e /dev/disk/by-label/MYUSBSERVER ] && [ "$WAIT_COUNT" -gt 0 ]
    do
    tmp=$((WAIT_COUNT-=1))
    sleep 1
    done

    echo -n "Please wait... "
    mount -t vfat -o ro /dev/disk/by-label/MYUSBSERVER /disk
    cp /disk/root.sqfs /
    echo "done"
    umount /disk && rm -Rf /disk
    EOF
    $ chmod +x $IMGROOT/../etc/usb/scripts/init-premount/udev_into_ram
    Ниже приведён скрипт создающий бутовую USB-флешку. Скрипт сохраняется в файл «~/ubuntu-ram/scripts/make-usb.sh»
    #!/bin/sh

    WORKDIR=/path/to/ubuntu-ram
    SQUASHFS_ROOT=$WORKDIR/image/
    ISO_ROOT=$WORKDIR/tmp/

    rm -Rf $ISO_ROOT/*

    # Получаем версию ядра в окружении
    version=$(basename $(readlink $SQUASHFS_ROOT/initrd.img))
    version=${version#initrd.img-}

    mount -o bind $WORKDIR/etc/usb $SQUASHFS_ROOT/etc/initramfs-tools
    chroot $SQUASHFS_ROOT mkinitramfs -v -o /boot/initrd.img-$version $version
    umount $SQUASHFS_ROOT/etc/initramfs-tools

    mkdir $ISO_ROOT/isolinux
    cp $SQUASHFS_ROOT/boot/initrd.img-$version $ISO_ROOT/initrd.gz
    cp $SQUASHFS_ROOT/boot/vmlinuz-$version $ISO_ROOT/vmlinuz
    cat <<EOF > $ISO_ROOT/syslinux.cfg
    DEFAULT server
    TIMEOUT 1
    LABEL server
    menu label ^Server
    kernel vmlinuz
    append initrd=initrd.gz root=/root.sqfs loop=/dev/loop0 rootfstype=squashfs aufs=tmpfs ro
    EOF

    #
    mksquashfs $SQUASHFS_ROOT $ISO_ROOT/root.sqfs \
    -e $SQUASHFS_ROOT/boot/* \
    $SQUASHFS_ROOT/initrd.img \
    $SQUASHFS_ROOT/vmlinuz

    echo "Please insert USB flash drive and press Enter"
    read
    # /dev/sdX - Ваша USB-флешка
    lilo -M /dev/sdX
    lilo -A /dev/sdX 1
    mkfs.vfat /dev/sdX1
    syslinux -f /dev/sdX1
    mlabel -i /dev/sdX1 ::MYUSBSERVER
    mount -t vfat /dev/sdX1 /mnt
    cp -a $ISO_ROOT/* /mnt
    umount /mnt
    exit 0
    Делаем скрипт исполняемым
    $ chmod +x ~/ubuntu-ram/scripts/make-usb.sh

понедельник, 25 мая 2009 г.

SANE vs EPSON Perfection V300 PHOTO

Sane для работы с этим сканером требуются проприетарные драйвера. В репозитарии Ubunty 9.04 Jaunty готовых пакетов не оказалось. Но после недолгих поисков в Launchpad.Net нашлось то, что нужно.
Подключаем репозитарий PPA

deb http://ppa.launchpad.net/doctormo/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/doctormo/ppa/ubuntu jaunty main
Добавляем ключи PPA
$ wget -O- 'http://keyserver.ubuntu.com:11371/pks/lookup?op=get&search=0x15A579BF113659DF' | sudo apt-key add -
Ставим требуемые драйвера
$ sudo apt-get update
$ sudo apt-get install iscan iscan-plugins
Создаем правило udev для сканера и сохраняем в файл «/etc/udev/rules.d/50-epson-v300.rules». Этим мы переопределим права на файл устройства. Иначе он будет доступен только для суперпользователя.
SUBSYSTEMS=="usb", ATTRS{idVendor}=="04b8", ATTRS{idProduct}=="0131", MODE="660", GROUP="scanner"
Перезагружаем HAL
$ sudo invoke-rc.d hal restart
Теперь к компьютеру подключаем сканер и запускаем xsane.

понедельник, 4 мая 2009 г.

Скрипт для корректного выключения гостевых хостов в libvirt

Ввиду неспособности libvirt-bin корректно отключать гостевые хосты при выключении/ребуте сервера, решил написать свой скрипт

#!/bin/sh
### BEGIN INIT INFO
# Provides: kvm-shutdown
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Shutdown Guest KVM Hosts
# Description: Shutdown Guest KVM Hosts
### END INIT INFO

# Author: Князь <demiurg (at) propheta.ru>
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Shutdown Guest KVM Hosts"
NAME=kvm-shutdown
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "/usr/bin/virsh" ] || exit 0
[ -S "/var/run/libvirt/libvirt-sock" ] || exit 0

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

export LANG=C

#
# Function that stops the daemon/service
#
virsh_list()
{
virsh list 2>/dev/null | grep -E 'running$' | awk '{ print $2 }'
}

do_stop()
{
LIST=$(virsh_list)
for i in $LIST;
do
virsh shutdown $i 1>/dev/null 2>/dev/null
echo
echo -n "Shutdown $i ";
while [ "$(virsh_list | grep $i)" ];
do
echo -n '.'
sleep 2
done;
done;
if [ "$LIST" ]; then echo; fi;
}

case "$1" in
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Activating $DESC" "$NAME"
do_stop
case "$?" in
0|1)
[ "$VERBOSE" != no ] && log_end_msg 0
break
;;
2)
[ "$VERBOSE" != no ] && log_end_msg 1
break
;;
esac
break
;;
*)
echo "Usage: $SCRIPTNAME stop" >&2
exit 3
;;
esac
Сохраняем скрипт в файл «/etc/init.d/kvm-shutdown» и делаем его исполняемым
$ sudo chmod +x /etc/init.d/kvm-shutdown
Создаем символические ссылки в rc0, rc1, rc6
$ sudo ln -s ../init.d/kvm-shutdown /etc/rc0.d/K19kvm-shutdown
$ sudo ln -s ../init.d/kvm-shutdown /etc/rc1.d/K19kvm-shutdown
$ sudo ln -s ../init.d/kvm-shutdown /etc/rc6.d/K19kvm-shutdown
Префикс K19 выбран для того, чтобы скрипт запускался перед «/etc/init.d/libvirt-bin» (префикс K20)

суббота, 14 марта 2009 г.

xargs: многопоточная обработка

Благодаря посту Владимира Бредникова узнал, что xargs благодаря двум ключам помогает организовать многопоточную обработку файлов:

-n X
Ограничивает количество передаваемых вашей программе аргументов. По умолчанию xargs передаёт программе довольно большое число аргументов, поэтому для обработки одного файла за один раз нужно указывать эту опцию.
-P X
Устанавливает количество одновременно выполняемых процессов. По умолчанию xargs запускает только один процесс, но в нашем случае нужно увеличить это число до количества процессоров.
Например, в паре с утилитой find можно в несколько потоков обработать множество картинок, размер которых больше одного мегабайта
$ find ~/Photos -iname '*.jpg' -and -size +1M -print0 | \
xargs -0 -n 1 -P 2 -I'{}' convert '{}' -resize '800x600>' -quality 100 '{}'
P.S. Надо почаще заглядывать в man :)

среда, 11 марта 2009 г.

Samba + pam_mkhomedir

Возникла необходимость, чтобы при входе на сервер с «samba» для вошедшего пользователя домена создавалась локальная домашняя папка (если отсутствует).

Сперва убедитесь что smbd собран с поддержкой PAM

$ smbd -b | grep WITH_PAM
WITH_PAM
Если PAM не поддерживается, соберите Samba из исходников с ключом «--with-pam».
В файл «etc/smb.conf» (секция «global») добавляем
obey pam restrictions = Yes
Создаем шару для домашних папок пользователей
[homes]
valid users = DOMAIN\%S
read only = no
browseable = no
create mode = 0600
directory mode = 0700
По умолчанию Samba считает, что домашние папки пользователей находятся в «/home/DOMAIN/user». Если вы хотите разместить их в другом месте, задайте явно параметр «template homedir» в секции «global» и рестартуйте winbindd.
Нужно создать директорию «/home/DOMAIN», так как pam_mkhomedir не умеет создавать вложенные директории
$ sudo mkdir /home/DOMAIN
Добавляем в файл «pam.d/samba»
session    required    pam_mkhomedir.so umask=0077
Под занавес ребутаем smbd.