воскресенье, 20 мая 2012 г.

Защищаем паролем редактирование меню в загрузчике grub2

При использовании загзузчика grub/grub2 существует простой способ получить права суперпользователя в системе. Для этого в меню загрузчика нужно нажать "E" и добавить в строку с параметрами ядра опцию init=/bin/bash. После загрузить систему и сменить пароль на нужный.
Чтобы исключить возможность менять конфигурацию загрузчика вне загруженной системы нужно установить пароль на загрузчик. В этом случае загрузить систему можно будет любому, а вот поменять конфигурацию только тем, кто знает логин/пароль.
Создание пароля - процесс простой:
# grub-mkpasswd-pbkdf2 
Enter password: 
Reenter password: 
Your PBKDF2 is grub.pbkdf2.sha512.10000.2D4EE33EEE342503888D967084246F3CB9328B9A5C731439FD1AD70E3AB7637FA294942A049546CECBFBCFE8582D1F833B92B18C0F124C1003F766259DFB9BD2.86F1A8963F23E588FF3D04F104E9245858CD12BB8F0A9A8B849B61735E8300D33CD399F28A58AB696E2F7F482ABB93C65B8B79342B94C9C2A7A59DA3AF03B8D8
Полученную строку нужно добавить в скрипт из которого генерируется конфигурация grub2. Чтобы не было проблем с конфигом при обновлении пакета, я создал отдельный файл /etc/grub.d/05_password.
#!/bin/sh

set -e

cat << EOF
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.2D4EE33EEE342503888D967084246F3CB9328B9A5C731439FD1AD70E3AB7637FA294942A049546CECBFBCFE8582D1F833B92B18C0F124C1003F766259DFB9BD2.86F1A8963F23E588FF3D04F104E9245858CD12BB8F0A9A8B849B61735E8300D33CD399F28A58AB696E2F7F482ABB93C65B8B79342B94C9C2A7A59DA3AF03B8D8
EOF
Последний штрих - поправить права на новый файл и сгенерировать новый конфиг:
# chown root:root /etc/grub.d/05_password
# chmod 600 /etc/grub.d/05_password
# update-grub

суббота, 19 мая 2012 г.

Лучшее враг хорошему или работает - не трогай

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

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

Вот наконец разобрался. Началось с того, что потребовался VPN клиент для IPSec. Я быстренько сделал бэкпорт пакета ike (VPN клиент от Shrew Soft Inc.) версии 2.1.7 для squeeze, закинул его в структуру репозитария и запустил скрипт обновления.

По окончании работы скрипта я начал ставить пакет и очень удивился, когда в доступных версиях оказалась только 2.1.5, которая доступна для squeeze из его родного репозитария. Далее я посмотрел список доступных версий для пакета ike - была доступна только одна версия.

Полез проверять, туда ли я закинул пакет (уже пару раз ошибался в спешке и в итоге пакет не добавляло в списки). В этот раз все было в порядке.

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

Быстренько поправил скрипт, синхронизировал изменения на сервере (чтобы повторно не заливать все изменения, которые нагенерил buildbot за это время) и запустил обновление еще раз.

В этот раз все прошло как и ожидалось и aptitude предложил поставить нужную версию.

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

среда, 16 мая 2012 г.

Делаем бэкап перед обновлением системы средствами LVM

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

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

Чтобы не было неприятных сюрпризов перед обновлением, мне нужно сделать бэкап, причем желательно таким образом, чтобы была возможность возиться с "последствиями" обновления и иметь возможность быстро переключиться на стабильный Squeeze. Если делать это по-старинке, то мне придется делать зеркало системных файлов на домашний комп, причем в двух вариантах (стабильный squeeze и обновление на wheezy). Понятное дело, что восстановиться из такого бэкапа в полевых условиях не получится (если вдруг всплывет косяк, связанный с обновлением). Нужна возможность держать всю информацию на самом нетбуке, но проблема в том, что там просто нету столько свободного места, чтобы держать две полные копии системы. Потому я начал искать новое решение...

В общих чертах меня могла бы спасти BTRFS у которой есть поддержка снапшотов на уровне файловой системы (т.е. в снапшотах хранится только разница относительно базы, с которой они были созданы). Но btrfs еще в стадии разработки и спотыкаться об ее недоработки нет желания.

Далее вспомнилось, что в самом начале освоения LVM я пробовал делать снапшоты перед обновлением системы. Если обновление нужно было отменить, то приходилось монтировать снапшот и затем rsync'ом приводить систему в чувство. Но хочется чего-то проще. Что-то вроде сделал снапшот и если результат обновления не нравится - просто возвращаем исходное состояние нужному LVM тому, используя для этого соответствующий снапшот.

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

Разбивка диска на нетбуке у меня не слишком мудреная:

/dev/sda1  /boot  ext2
/dev/sda2  LVM PV
/dev/sda3  SWAP

/dev/laptop/rootfs  /  ext4
/dev/laptop/home  /home

Посколько /boot находится вне LVM, то я сделал его копию:

# rsync -a /boot/ /boot~lvm/

Смотрим, сколько у меня места в группе томов (VG), еще не размеченного под логические тома (LV):

# vgs
  VG        #PV #LV #SN Attr   VSize   VFree
  laptop      1   2   0 wz--n- 156,2g  15,44g

Далее делаем снапшоты всех разделов:

# sync
# lvcreate -s -n rootfs-before -L 5G laptop/rootfs
# lvcreate -s -n home-before -L 1G laptop/home

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

# lvcreate -s -n rootfs-after -L 7G laptop/rootfs
# lvcreate -s -n home-after -L 1G laptop/home
# lvconvert --merge laptop/rootfs-before
# lvconvert --merge laptop/home-before

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

Если в процессе обновления поменялось содержимое /boot, то после перезагрузки или при помощи LiveCD/LiveUSB его можно восстановить так:

# rsync -a --delete /boot~lvm/ /boot/
# rm -fr /boot~lvm
# update-grub

После завершения слияния, пространство, занятое под laptop/rootfs-before и laptop/home-before освободится. Аналочично поступаем, если нужно вернуться в играм с обновлением.

понедельник, 14 мая 2012 г.

Windows XP: замена материнской платы

Как правило замена материнской платы в компьютере под управлением Windows влечет набор неудобств начиная от необходимости повторной активации до BSOD "Stop 0x0000007B". В последнем случае windows не находит загрузочное устройство, поскольку отсутствуют драйвера для дискового контроллера.

Есть небольшая хитрость, позволяющая избежать BSOD и поставить драйвера на уже новую материнскую плату. Для этого перед заменой платы нужно обновить драйвер дискового контроллера на "Standard Dual Channel PCI IDE Controller". После этого загрузка на новой плате должна пройти без проблем.

Остается только удалить драйвера для устройств, которые использовались на старой плате. Для этого нужно выполнить две команды в сеансе интерпретатора:

\> set devmgr_show_nonpresent_devices=1
\> devmgmt.msc

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

четверг, 10 мая 2012 г.

Вышел английский перевод книги "The Debian Administrator's Handbook"

Как и обещали авторы книги "The Debian Administrator's Handbook" ее английский перевод доступен для всех желающих под свободной лицензией. Книга доступна для скачивания в нескольких форматах: pdf, epub и mobipocket.

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

Примечательно то, что эта книга написана разработчиками Debian и содержит актуальную информацию.

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

Deadbeef 0.5.4 (bugfix release)

Today available deadbeef 0.5.4 with some minor (at least for me) fixes. For those who curious about changelog I placed it below

changelog since 0.5.3

  • fixed starting the player using "deadbeef" command without path
  • fixed missing ; in deadbeef.desktop
  • fixed big-endian support in sndfile plugin
Ubuntu/Debian packages available at project download page.

среда, 9 мая 2012 г.

Deadbeef 0.5.3 released

New deadbeef music player was released recently. For this release author prepared binary builds for Debian/Ubuntu (available at there). For other platforms available static binary build which distributed as tar.gz archive.

Changelog very impressive. Added many features and also many bugs fixed.

changelog since 0.5.2

  • m3u: fixed few parser bugs; added audio/x-scpls mime-type support; fixed m3uext support
  • adplug: upgraded to 2.2.1, added fake-surround support and emu selection
  • added ShellExec GUI configuration support (thanks to Azeem Arshad)
  • fixed id3v2 parser whitespace trimming bug
  • "Stop after current" can be reconfigured to be auto-reset each time
  • auto-save EQ state on every change
  • gcc 4.7 compile fix in SID plugin
  • added new Sort->Random feature, to randomize the playlist (thanks to Defusix)
  • converter: fixed writing wav files sized over 2 gigs
  • converter: added support for reconstructing of the folder structrure based on longest common root folder
  • converter: added support for writing files to the source track folders
  • fixed possible hang caused by race condition in the alsa/streamer interaction
  • wildmidi: fixed possible linking errors
  • fixed ignoring cuesheet and log fields in search
  • added support for TXX DATE field as written by FB2K
  • bogus "plugin.so file not found" errors are no longer printed
  • fixed bug in search window causing all tracks to become selected on some actions
  • fixed possible crash when loading corrupted playlist files
  • EQ window will reflect changes in the DSP chain configuration
  • fixed excessive CPU load while streamer is waiting for the last track to finish
  • alsa: fixed sleep time bug, which should improve CPU load (thanks to Martin Panter)
  • alsa: fixed buffer underrun handling problem which was causing sound jittering on slow media like sshfs, cd, etc (thanks to Martin Panter)
  • mp3: added option to disable gapless playback, but improve speed (thanks to Martin Panter)
  • aac: fix to potential reading past the end of array (thanks to Martin Panter)
  • new default cover-art image by TheSame
  • fixed loading m3u/pls over http when the file size is unknown
  • added m3u and pls url mime types (audio/x-mpegurl;audio/x-scpls) to deadbeef.desktop
The most notable thing in Debian/Ubuntu package - deadbeef binary placed in /opt/deadbeef/bin. So if you want to run binary from command line you should add /opt/deadbeef/bin to your PATH variable. Example for bash:

$ cat >> ~/.bashrc << EOF
if [ -d /opt/deadbeef/bin ]; then
     export PATH=/opt/deadbeef/bin:$PATH
fi
EOF

Enjoy new release.

суббота, 5 мая 2012 г.

Новый провайдер

Старый провайдер замучил своим криво работающим шейпером для безлимитных тарифов. Я пользовался услугами BelInfoNet (adsl.by) и в принципе был доволен, пока сидел на тарифе с предоплаченным траффиком. Был доволен почти, т.к. для доступа в интернет они используют PPTP и мой старенький D-Link DIR-320 с OpenWRT на борту не справлялся с 10Mb/s потоком. Максимум, что могло удержать железо - 4-5 Mb/s. Конечно можно было бы поиграться с accel-pptp, но мне было лениво.

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

pptp[17208]: anon log[decaps_gre:pptp_gre.c:414]: buffering packet 61512626 (expecting 61512621, lost or reordered)

Это наводило на мысль о проблемах с шейпером провайдера (т.к. до перехода на безлимит проблемы не было). Реализация PPTP клиента в Linux не самая идеальная, в добавок потери пакетов... короче надоело. С мая решил переключиться на ByFLY, т.к. с ними таких проблем не будет.

Подключался к BelInfoNet я через заявку на сайте (т.е. в офис ехать не пришлось), а вот чтобы отключиться пришлось. Мало того, что настоятельно попросили пояснить причины отключения, так еще это оказалось платной услугой! Недорогой к слову (примерно 2.5$), но я первый раз сталкиваюсь с ситуацией, когда хотят денег за отключение.

Этот пост пишется уже будучи подключенным к ByFLY. Немного пришлось поковыряться в сервере, вспомнить про существование pppoeconf и сейчас все работает. Очень надеюсь, что будет не хуже, чем у предыдущего прова.

пятница, 4 мая 2012 г.

Пароль админа в MySQL сервере если стоит панель Plesk

Если на сервере стоит панель управления Parallels Plesk, то зачастую владелец сервера понятия не имеет о пароле root в MySQL. Чтобы узнать его самостоятельно логинимся в SSH под root. Затем находим пароль в /etc/psa/.psa.shadow

# cat /etc/psa/.psa.shadow
therootpassword

Имя пользователя будет не root, а admin. Чтобы не вводить его каждый раз руками я рекомендую сохранить его в ~/.my.cnf (доступный на чтение только root)

# touch ~/.my.cnf
# chown root:root ~/.my.cnf
# chmod 600 ~/.my.cnf
# cat > ~/.my.cnf << EOF
[client]
user=admin
password=therootpassword
EOF

После этого mysql и mysqladmin просить пароль перестанут.

UPDATE: На одном из серверов столкнулся с тем, что в /etc/psa/.psa.shadow пароль не в plain text, а в виде хеша. Рядом лежит файлик /etc/psa/README.psa.shadow в котором говорится следующее
Starting from version 10.2, Panel encrypts the Administrator's password before
saving it to /etc/psa/.psa.shadow. For security reasons, only users with root
permissions are able to get the plain password. To obtain the password, such
users should run the following command:

/usr/local/psa/bin/admin --show-password
Выполнив эту команду вы получите пароль для пользователя "root" (в старых версиях был "admin").

Пытаюсь разобраться с работой setxkbmap в неактивной сессии

Есть потребность выставить запускать setxkbmap для залогиненых пользователей у которых сессия в данный момент неактивна (не multi-seat и потому только одна сессия может быть одновременно активной либо все неативны).

Так вот setxkbmap замечательно работает в активной сессии. Например

$ setxkbmap us; sleep 1m; setxkbmap $(cat ~/.Xkbmap)

дает желаемый результат и раскладка сначала выставляется на US, а через минуту восстанавливаются мои настройки, заданные в ~/.Xkbmap. Если же сначала выставить US, а затем с другого компа зайти по SSH и выставить правильные DISPLAY и XAUTHORITY, то setxkbmap не дает результата. При этом другие приложения нормально запускаются в неактивной сессии (их видно, если переключиться в нее)

Возможно я чего-то не знаю о setxkbmap и XKB extension вообще... пока попросил помощи в рассылке debian-russian. Возможно кто-то и поможет.

среда, 2 мая 2012 г.

XobotOS: проект по портированию Android на C#

Заинтересовала новость от проекта XobotOS о достижениях в портировании Android на платформу Mono/C#. Вместо переписывания исходников Android 4.0 (ICS) с Java на C# был применен инструментарий sharpen, который выполнил трансляцию кода.

Интересны результаты сравнения производительности аналогичного кода:

Из него следует, что Mono/C# в несколько раз превосходит по скорости Dalvik/Java. Хотя разработчики и не собираются создавать отдельную операционную систему, результаты их работы могут оказать влияние как на Mono, так и на Android.

вторник, 1 мая 2012 г.

Использование autotools для сборки grabinput

Сегодня дописал grabinput - утилиту, которая может быть полезна для блокировки клавиатуры/мыши от посягательств маленьких детей (а возможно и любого другого, кто не знаком со способом снятия блокировки).

Grabinput поддерживает три режима работы:
  • перехват событий клавиатуры (действие по-умолчанию);
  • перехват событий клавиатуры и мыши (при использовании ключа -l);
  • блокирование дисплея посредством запуска заставки (при использовании ключа -s).
Для себя я подключил комбинацию Ctrl+Win+Scroll Lock для блокировки клавиатуры и Alt+Win+Scroll Lock для блокировки клавиатуры и мыши. Чтобы отменить блокировку нужно последовательно нажать Scroll Lock, Print Screen и Pause (последовательность задается в заголовочном файле src/grab.h).

Исходники состоят из двух файлов:
  • src/grab.c
  • src/grab.h
 И первоначально для сборки использовался простой Makefile:

grabinput: src/grab.c src/grab.h
    gcc -o grabinput -Wall -lX11 src/grab.c

clean:
    rm -f grabinput

И этого было достаточно, чтобы собрать бинарник. Позже пришла идея попробовать использовать для сборки autotools.

Для начала почитал пару примеров и заглянул в исходники пары opensource проектов. Основная сложноть была в том, что часть мануалов была ориентирована на устаревшие версии autoconf/automake, но с горем пополам родилась более-менее рабочая последовательность внедрения autotools:
  • в директории, где лежит src/ запускаем autoscan. При этом создается файл configure.scan, который нужно переименовать в configure.ac.
  • в configure.ac правим параметры макроса AC_INIT, чтобы соответствовать названию и версии исходников. В итоге у меня получилось так:
    #                                               -*- Autoconf -*-
    # Process this file with autoconf to produce a configure script.
    
    AC_PREREQ([2.67])
    AC_INIT([grabinput], [0.3], [tataranovich@gmail.com])
    AM_INIT_AUTOMAKE(grabinput, 0.3)
    AC_CONFIG_SRCDIR([src])
    AC_CONFIG_HEADERS([config.h])
    
    # Checks for programs.
    AC_PROG_CC
    AC_CHECK_PROG([PKGCONFIG], [pkg-config], [yes], [no])
            if test "x$PKGCONFIG" == "xno"; then
                    AC_MSG_ERROR([pkg-config not found])
            fi
    
    # Checks for libraries.
    PKG_CHECK_MODULES([X11], [x11], [], AC_MSG_ERROR([X11 libraries not found]))
    
    # Checks for header files.
    AC_CHECK_HEADERS([stdio.h stdlib.h unistd.h string.h signal.h errno.h])
    
    # Checks for typedefs, structures, and compiler characteristics.
    
    # Checks for library functions.
    
    AC_OUTPUT(Makefile src/Makefile)

    В моем случае инициализируется autoconf/automake и проверяется наличие pkg-config (нужен для поиска libx11-dev), libx11-dev, а также наличие заголовочных файлов: stdio.h stdlib.h unistd.h string.h signal.h errno.h
  • конфигурация automake находится в Makefile.am и src/Makefile.am
    AUTOMAKE_OPTIONS = foreign
    SUBDIRS = src
    EXTRA_DIST = maint
    AUTOMAKE_OPTIONS = foreign выключает жалобы, что исходники разложены не по феншую (не GNU-style), SUBDIRS = src задает директорию с исходниками, а EXTRA_DIST = maint включает в дистрибутив информацию, необходимую для сборки пакета для Debian.
    AM_CFLAGS = -Wall @X11_CFLAGS@
    AM_LDFLAGS = @X11_LIBS@
    
    bin_PROGRAMS = grabinput
    grabinput_SOURCES = grab.c grab.h
    AM_CFLAGS и AM_LDFLAGS задают начальные значения переменных компилятора и линковщика. Обратите внимание на префикс X11_{CFLAGS,LIBS} - эти переменные устанавливаются autoconf при запуске ./configure. bin_PROGRAMS задает расположение бинарника grabinput в $PREFIX/bin, а grabinput_SOURCES - определяет исходники, необходимые для компиляции grabinput
  • чтобы не запускать каждый раз последовательность aclocal, autoheader, automake и autoconf я добавил скрипт autogen.sh, который был содран у какого-то opensource проекта.
    #!/bin/sh
    echo aclocal && aclocal || exit 1
    echo autoheader && autoheader || exit 1
    echo automake && automake --add-missing --copy --force --foreign || exit 1
    echo autoconf && autoconf || exit 1
    
    if test "x$NOCONFIGURE" = "x"; then
      echo configure
      ./configure $*
    fi
Теперь чтобы собрать дистрибутив исходников, я делаю чекаут из репозитория, затем запускаю ./autogen.sh (по-умолчанию скрипт выполняет ./configure). Далее выполняю make dist и в директории появляется архив grabinput-x.x.tar.gz.

Сборка исходников из этого архива знакома многим:

./configure
make
make install

Для Debian-based дистрибутивов в архиве есть директория maint/debian которую нужно скопировать на уровень выше и выполнить

dpkg-buildpackage -rfakeroot -us -uc

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

Ранее я много читал про autotools - мол это говно мамонта, autocrap и т.д. В качестве альтернативы предлагался простой и понятный scons/cmake/qmake/ant/etc - у меня в планах попробовать адаптировать scons для сборки grabinput, чтобы было с чем сравнивать затраты на освоение.