суббота, 27 декабря 2008 г.

четверг, 25 декабря 2008 г.

Векторизация растровых изображений

Помнится, курсе на третьем нам очень долго рассказывали, как осуществлять векторизацию растровых изображений и вот впервые я увидел прогу, которая это АДЕКВАТНО умеет делать, vectormagic.ru
Можно бесплатно сконвертировать два изображения после регистрации :)

среда, 3 декабря 2008 г.

Отладка ядра Linux посредством kgdb, подготовка

Хост машина
Ставим на хост машине отладчик:
sudo apt-get install gdb
sydo apt-get install xxgdb # X фронтэнд для gdb
sudo apt-get install socat # релей

Запускаем релей:
socat -d -d /home/nrg/kernel_debug_pipe pty:

А релей нам нужен по причине: GDB can't connect directly to a unix-domain socket, so you'll need to use the socat ("socket cat") utility.

Если вирт машина с виртуальным комом не включена, то увидим мы примерно следующее:

2008/12/03 03:17:21 socat[18494] N opening regular file "/home/nrg/kernel_debug_pipe" for reading and writing
2008/12/03 03:17:21 socat[18494] N PTY is /dev/pts/1
2008/12/03 03:17:21 socat[18494] N starting data transfer loop with FDs [3,3] and [4,4]
2008/12/03 03:17:21 socat[18494] N socket 1 (fd 3) is at EOF
2008/12/03 03:17:22 socat[18494] N exiting with status 0


А вот что увидим в случае успешного коннекта:


2008/12/03 03:18:55 socat[18532] N successfully connected via
2008/12/03 03:18:55 socat[18532] N PTY is /dev/pts/1
2008/12/03 03:18:55 socat[18532] N starting data transfer loop with FDs [3,3] and [4,4]



Машина с отлаживаемым ядром (Дебиян Ленни на 2.6.26 ядре)

Для отлаживаемой в VirtualBox машины нужно включить виртуальный ком порт вот таким образом:


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

Матчасть по KGDB:
http://oslab.info/index.php/Misc/KGDB основной мануал по настройке всего добра
http://www.dumbare.com/kgdb в картинках
http://kgdb.linsyssoft.com/intro.htm офсайт
http://en.wikipedia.org/wiki/KGDB вики

вторник, 2 декабря 2008 г.

Многообразие отладчиков ядра Линукс - целых два!

http://oss.sgi.com/projects/kdb/ встроенный, запускается прямо на отлаживаемой машине.

http://kgdb.linsyssoft.com/downloads.htm пошаговый, позволяет подключиться к отлаживаемой машине по последовательному порту и отлаживать в стиле "а ля отладка обычного софта".

материал с http://www.linuxdevices.com/news/NS4947411696.html:
Amit Kale, maintainer of the KGDB Linux kernel debugger, reports that the company he founded is offering commercially supported versions of KGDB. LinSysSoft distributes KGDB Pro as a pre-built binary supporting the latest Red Hat kernels, with support, bug fixes, patches, and a 48-hour response-time guarantee to critical bugs.

KGDB, along with KDB, is one of two popular Linux kernel debuggers. Whereas KDB runs on the system being debugged, and can be used to debug any Linux kernel, KGDB runs on a separate development host, and works on kernels with compiled-in debugging support. According to Kale, KGDB aims to let users debug Linux kernels much as they would debug applications, setting breakpoints and stepping through code line by line while observing variable values.

According to Kale, "After talking to a lot of KGDB users, we realized their frustrations stemmed from lack of dedicated support. Installations required lot of reading, posting mails on lists, and it took forever to get things going. KGDB Pro aims to solve most of these issues."

Availability

KGDB Pro is available now, priced at $1,500, including qualified packages for various Linux distributions and kernels, installation support, bug fixes, support for four new Linux kernels per year, five troubleshooting/bug fixes per year, and discounted rates on requested feature enhancements.

Отладка ядра Linux в VirtualBox

apt-get install kernel-patch-kdb
apt-get install linux-source-2.6.26
apt-get install kernel-package
apt-get install zlib1g-dev

cd /usr/src
tar xvjf linux-source-2.6.26.tar.bz2
cd linux-source-2.6.26
cp /boot/config-2.6.26-1-486 .config
make oldconfig

# чесслов, не знаю, зачем это
echo "patch_the_kernel := YES" >> /etc/kernel-pkg.conf

make-kpkg --added-patches kdb --append-to-version "-kdb" --revision=2.6.26.kdb --initrd kernel-image

После этого можно наблюдать deb пэкадж с ядром в папке /usr/srс, который ставим командой dpkg -i имя_пакета.deb

После этого перезагружаемся с новым ядром (желательно в single mode) и переходим к отладке посредством нажатия кнопки "pause" (на клавиатуре есть такая), выход из отладчика осуществляется командой go.

Не знаю, как у вас, но у меня при установке kdb без поддержки USB клав клавиатура очень тупила, так что пробую пересобрать с усб, в надежде, что заработает нормально :)

источник:
http://d.hatena.ne.jp/n314/20080412/1207994145
рекомендуемо к прочтению:
http://www.ibm.com/developerworks/linux/library/l-kdbug/
http://www.ibm.com/developerworks/linux/library/l-debug/

О сектах

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

Чтобы продавать продукт не нужно знать его востребованность. Достаточно рекламы, которая сделает его востребованным.

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

Не нужно кем-то быть или что-то иметь. Достаточно лишь, что бы все знали, что ты есть тот-то, что ты имеешь то-то.

Не нужно ничего... Достаточно лишь, чтобы все верили, что...

Напоминает Матрицу, неправдали.

И если тот же Яндекс - это не секта, то почему яндексойды "осознанно" надевают корпоративные рясы и кичаются ими?

В другой секте накачивают силиконом сиськи, жарят тело в солярии и также думают, что чем-то отличаются от других "сектантов".

Вы вот представьте, что за пачку разноцветных бумажек можно получить неплохое средство передвижения. А за чуть большую пачку - жильё. И большинство людей спит и видит, как увеличивается его пачка цветных бумажек. Разве это не секта умалишенных почитателей цветных бумажек?

Я уж не говорю про секту почитателей дёргающихся графиков...

С самого детства ты ходишь в школу, каждое буднее утро встаёшь в 7-30, ходишь на 45-минутные уроки, где учитель говорит тебе, что ты должен делать и почему нужно гордиться цифрами, под названием оценки. И оказывается всё это для того, чтобы ты потом пришёл в какую-то корпорацию и уже знал, что ходить 5 дней в неделю на работу к 9-00, работать там 8 часов, выполнять указания начальника и получать за это другие, не менее виртуальные, цифры - всё это считается нормальным.

Так что сектантство - это вопрос точки отсчёта. И самое сложное - найти нулевые координаты.

Чуть позже постараюсь откомментировать.

Стащено с: http://michael.mindmix.ru/612-538-sektantstvo.zhtml

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

Установка Zabbix PHP Фронтэнд на CentOS 5

Вступление
После того, как сервер мониторинга запущен, стоит прикрутить к нему мордочку :)
Тут всё довольно просто, т.к. у мордочки есть инсталлятор.

Установка
1. Ставим необходимый софт:
yum install -y httpd http php-pgsql php-gd php-bcmath

2. Добавляем Апача в автозапуск:

/etc/init.d/httpd start
chkconfig httpd on

3. Копируем в папку вирт сервера файлы из frontends/php/
cp -R frontends/php/* /var/www/html/

4. Прописываем таймзону и max время исполнения в /etc/php.ini
date.timezone = Europe/Moscow
max_execution_time = 360

5. Открываем http://zabbix.servername.ru/setup.php
6 Следуем указаниям мастера, ставим Zabbix,
7. Логинимся как Admin | zabbix и тащимся с потрясающего интерфейса Заббикса :)

MySQL Workbench Linux версия

Довольно давно пробегала новость, что данная тулза была портирована на линукс, но потестить руки не доходили, ну что же, вперёд http://dev.mysql.com/workbench/?p=158 !

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

Удаление ограничений на минимальную длину пароля в Debian

Делается довольно легко: в файле /etc/pam.d/common-password ищем слово "min" в незакомменченой строке, ставим в единицу и радуемся легким (э, ну все поняли, что онли на тестовых машинах, огражденных от внешнего мира?) паролям :)

Конвертировать QCOW в RAW QEMU

Вот так:
qemu-img convert debian_arm_hda.img -f qcow -O raw debian_arm_hda_raw.img
:)

воскресенье, 30 ноября 2008 г.

Установка Debian на ARM архитектуру

Установка эмулятора
sudo apt-get install qemu

Поиск initrd инсталлятора
Идём на список зеркал Дебияна http://www.debian.org/mirror/list

Вот примерно по такому пути "debian/dists/etch/main/installer-arm/current/images/rpc/netboot/" на (почти, если данных папок нету -- смените зеракало на другое) любом из зеркал вы можете скачать необходимый нам файл: initrd.gz (это собственно и есть инсталлятор)

Создаём образ жесткого диска:
qemu-img create -f qcow debian_arm_hda.img 2G

Поиска ядра под данную платформу
Вот здесь http://people.debian.org/~aurel32/arm-versatile/ требуется скачать файлик vmlinuz-2.6.18-6-versatile это ядро, специально собранное под процессор ARM versatile. Также надо стянуть файлик initrd.img-2.6.18-6-versatile, он нам понадобится после окончания установки.

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

/usr/bin/qemu-system-arm -M versatileab -kernel '/home/nrg/arm_debian/vmlinuz-2.6.18-6-versatile' -append 'root=/dev/ram' -initrd '/home/nrg/arm_debian/initrd.gz' -hda '/home/nrg/arm_debian/debian_arm_hda.img' -m 128

Инсталляция
Ну вот и всё :) Должны пойти буковки загрузки Линукс ядра и через некоторое время вы увидите обычный инсталлятор Дебияна. Внимание! Установка будет производиться по сети, так что запаситесь нормальным соединением и кучей трафика :) Также в процессе установки будет варнинг "Continue the install without loading kernel modules", с этим стоит согласиться, модули мы подсунем позже :)

Далее получим варнинг о том, что "No installable kernel was found in the defined APT sources" (т.е. ядра необходимого нам нету в пакетном менеджере), соглашаемся на установку без ядра.

Финальная настройка
После того, как установка закончена ждем ребута и во время следующей загрузки выключаем машинку.
Теперь нам надо ребутнуца в рабочем окружении:
/usr/bin/qemu-system-arm -M versatileab -kernel '/home/nrg/arm_debian/vmlinuz-2.6.18-6-versatile' -append 'root=/dev/sda1' -initrd '/home/nrg/arm_debian/initrd.img-2.6.18-6-versatile' -hda '/home/nrg/arm_debian/debian_arm_hda.img' -m 128

Как видите, мы заменили intrd инсталлятора на родной и сменили root раздел :)
Теперь запускаем систему, ждём пока отработает fsck (почему он запускается -- большой вопрос) и радуемся полноценной системе на ARM платформе %)



Проблемы
При таком подходе у меня загрузка доходила до fsck, потом зависала или ребуталась т.к. fsck не завершался успешно. Сначала попробовал -m поставить в 256, тестирование прошло почти мгновенно, но вылете по ошибки в самом конце. Вторым этапом было конвертирование образа винта из QCOW в RAW формат, как это сделать читайте здесь, потом просто меянем диск на -hda '/home/nrg/arm_debian/debian_arm_hda_raw.img'

После всего этого запускаем систему так:
/usr/bin/qemu-system-arm -M versatileab -kernel '/home/nrg/arm_debian/vmlinuz-2.6.18-6-versatile' -append 'root=/dev/sda1' -initrd '/home/nrg/arm_debian/initrd.img-2.6.18-6-versatile' -hda '/home/nrg/arm_debian/debian_arm_hda_raw.img' -m 128

Ещё очень желательно добавлять ключик -localtime при запуске, так будет время нормальное ;)

Установка родных модулей ядра

apt-get install initramfs-tools
wget http://people.debian.org/~aurel32/arm-versatile/linux-image-2.6.18-6-versatile_2.6.18.dfsg.1-18etch1+versatile_arm.deb (актуальную ссылку смотрите на сайте с патченым ядром, он указан выше; а вообще, лучше сам сайт откройте прямо с arm машинки в links)
dpkg -i linux-image-2.6.18-6-versatile_2.6.18.dfsg.1-18etch1+versatile_arm.deb



Использованные материалы
Основано на замечательной статье: http://www.goitexpert.com/entry.cfm?entry=ARM-Emulation-With-QEMU

четверг, 20 ноября 2008 г.

Vim и CentOS 5

У товарищей довольно странный подход к именованию пакетов, поэтому sudo yum install vim меня обрадовал сверхадекватным "No package vim available", неприятно, да. Правильный ответ был:
sudo yum install vim-enhanced

Установка vsftpd на Centos5

Для начала ставим пакет ФТП сервера:
sudo yum install vsftpd
Затем его запускаем:
sudo /etc/init.d/vsftpd start
Добавляем первого фтп юзера:
sudo /usr/sbin/useradd expand_backup -G ftp -m
Ставим юзеру пароль:
sudo passwd expand_backup

Ну вот, собственно, и всё :)
Единственное, хотелось бы запретить этому пользователю доступ по SSH, у кого есть идеи, как это сделать?

пятница, 14 ноября 2008 г.

HTML::Template vs Template::Alloy

Встала необходимость заменить HTML::Template на что-то более удобоваримое (кроме TT), заменили, довольны :)

Вот пример кода:
http://paste.org.ru/?l6ybly где закомменчено -- H::T

А вот пример шаблона:
http://paste.org.ru/?1aju7w где [% %] -- Template::Alloy, где монструозные -- HTML::Template.

понедельник, 10 ноября 2008 г.

Найти все используемые в проект Perl модули

Все Perl модули, от которых зависит проект можно найти командой:
grep -hiR '^use' * | sort -u

А есть более Perl way: http://search.cpan.org/~smueller/Module-ScanDeps-0.89/lib/Module/ScanDeps.pm

Ruby + gem + RubyOnRails + Debian 4 Etch

Ну для начала apt-get install ruby
ruby -v
ruby 1.8.5 (2006-08-25) [i486-linux]


Теперь нам надо поставить gem и Ruby On Rails.
Что первый, что второй есть в репозитории -- rubygems / rails
Апдейтим рельсы: sudo gem install rails

Список всех существующих пакетов довольно широк:
gem list -r

Список установленных пакетов можно посмотреть вот так:
gem list -l

Найти какой-либо пакет по имени можно так:
sudo gem query -r --name-matches часть_имени_пакета

Удаление пакета:
sudo gem uninstall progressbar

Обновление всех пакетов:
sudo gem update

А вот для просмотра документации есть просто ЗАШИБЕННЫЙ способ:
gem_server
после этого идём по адресу: ваш_хост:8808 и читаем документацию в НУ ОЧЕНЬ удобном виде :)

Ну для начала хватит :)

суббота, 8 ноября 2008 г.

Немного жизненных принципов

# Автор текста: А. Дементьев

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

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

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

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

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

среда, 5 ноября 2008 г.

Биллинг, сам код

Все файлы можно скачать вот отсюда: http://slil.ru/26302780
А теперь все файлы доступны в svn репо на Гугле, прошу:
svn checkout http://mybill.googlecode.com/svn/trunk/ mybill-read-only

Немного потюненая таблица для ulogd:
DROP TABLE IF EXISTS `ulog`;
CREATE TABLE `ulog` (
id INT UNSIGNED AUTO_INCREMENT UNIQUE,

raw_mac VARCHAR(80),

oob_time_sec INT UNSIGNED,
oob_time_usec INT UNSIGNED,
oob_prefix VARCHAR(32),
oob_mark INT UNSIGNED,
oob_in VARCHAR(32),
oob_out VARCHAR(32),

ip_saddr INT UNSIGNED,
ip_daddr INT UNSIGNED,
ip_protocol TINYINT UNSIGNED,
ip_tos TINYINT UNSIGNED,
ip_ttl TINYINT UNSIGNED,
ip_totlen SMALLINT UNSIGNED,
ip_ihl TINYINT UNSIGNED,
ip_csum SMALLINT UNSIGNED,
ip_id SMALLINT UNSIGNED,
ip_fragoff SMALLINT UNSIGNED,

tcp_sport SMALLINT UNSIGNED,
tcp_dport SMALLINT UNSIGNED,
tcp_seq INT UNSIGNED,
tcp_ackseq INT UNSIGNED,
tcp_window SMALLINT UNSIGNED,
tcp_urg TINYINT,
tcp_urgp SMALLINT UNSIGNED,
tcp_ack TINYINT,
tcp_psh TINYINT,
tcp_rst TINYINT,
tcp_syn TINYINT,
tcp_fin TINYINT,

udp_sport SMALLINT UNSIGNED,
udp_dport SMALLINT UNSIGNED,
udp_len SMALLINT UNSIGNED,

icmp_type TINYINT UNSIGNED,
icmp_code TINYINT UNSIGNED,
icmp_echoid SMALLINT UNSIGNED,
icmp_echoseq SMALLINT UNSIGNED,
icmp_gateway INT UNSIGNED,
icmp_fragmtu SMALLINT UNSIGNED,

pwsniff_user VARCHAR(30),
pwsniff_pass VARCHAR(30),

ahesp_spi INT UNSIGNED,

KEY index_id (id),
INDEX (ip_saddr),
INDEX (ip_daddr),
INDEX (oob_time_sec)
);


Модуль работы с БД DB.pm:
#!/usr/bin/perl
#===============================================================================
#
# FILE: DB.pm
#
# USAGE: use DB;
#
# DESCRIPTION: Some functions for work with db.
#
# REQUIREMENTS: DBI.
# BUGS: ---
# NOTES: ---
# AUTHOR: Pavel Odintsov (nrg),
# COMPANY:
# VERSION: 1.0
# CREATED: Mon Dev 10 23:53:08 SAMT 2007
# REVISION: ---
#===============================================================================

package DB;

use strict;
use warnings;
use Exporter 'import';
use DBI;

our @EXPORT = qw(db_connect db_disconnect vquery query );
our $VERSION = '1.0';

our %DB_CONFIG = (); # hash for db settings
my $data_base_handle = ''; # variable for database handle
my $last_error = 'no error';


# connect to db, save db handle in private module variable $data_base_handle
sub db_connect {
my $db_connect_string = "DBI:mysql:database=$DB_CONFIG{'db_name'};" .
"host=$DB_CONFIG{'db_host'};" .
"port=$DB_CONFIG{'db_port'}"; # db connection string
$data_base_handle = DBI->connect($db_connect_string, $DB_CONFIG{'db_user'}, $DB_CONFIG{'db_passwd'}, { PrintError => 1, 'RaiseError' => 1 })
}


# disconnect from db
sub db_disconnect {
if ($data_base_handle) {
return ($data_base_handle->disconnect) ? 1 : 0;
}
return 0;
}


# execute query to db with data (preferably for SELECT)
sub query {
if ($data_base_handle) {
unless ($data_base_handle && $data_base_handle->FETCH('Active') && eval { $data_base_handle->ping }) { # check db connect
db_connect() or return;
}
map {
$_->execute(@_); # execute query
@{$_->fetchall_arrayref({})};
} $data_base_handle->prepare(shift)
} else {
return;
}
}


# execute query to db without data (proferably for INSERT, DELETE, UPDATE)
sub vquery {
if ($data_base_handle) {
unless ($data_base_handle && $data_base_handle->FETCH('Active') && eval { $data_base_handle->ping }) { # check db connect
db_connect() or return;
}
my $sql_request = shift;
$data_base_handle->do($sql_request, undef, @_) if $data_base_handle; # standard DBI do request
} else {
return;
}
}

1;



Основной файл:

#!/usr/bin/perl

use strict;
use warnings;
use lib qw/./;

use DB;
use Data::Dumper;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw/:standard/;


%DB::DB_CONFIG = (
'db_name' =] 'traffic',
'db_port' =] q(),
'db_user' =] 'root',
'db_passwd' =] q(phahde4I),
'db_prefix' =] q()
);

my %dev_names = (
'00:e0:29:90:05:91:00:1c:f0:a9:78:9c:08:00 ' =] 'nrgs eeePC 900', # trailing space!!
);

# check entered date
sub check_date {
my $date = shift;

if ( $date =~ /\d{4}\-\d{1,2}\-\d{1,2}/ ) {
return 1;
}

return 0;
}

sub error_params {
print '[font color="red"]Диапазон дат указан неверно!!![/font]';
print '[/body][/html]';
exit;
}

print "Content-type: text/html\n\n";
print '[html][head][meta http-equiv="Content-Type" content="text/html; charset=utf8" /][/head][body]';

db_connect() or die "DB not avaliable\n";


my @devices = query("SELECT INET_NTOA(ip_daddr) AS dip, raw_mac FROM ulog GROUP BY ip_daddr ORDER BY ip_daddr");

my @month_dates = query("SELECT LAST_DAY(CURDATE()) AS last_day,
DATE_SUB( CURDATE(), INTERVAL DAY(CURDATE()) day) AS first_day;"); # -1 if last_day required

print [[DOC;
[a href ="/cgi-bin/bill.pl"]Статистика за сегодня[/a][br/]
[a href ="/cgi-bin/bill.pl?start_date=$month_dates[0]-]{first_day}&end_date=$month_dates[0]-]{last_day}"]Статистика за текущий месяц[/a][br/]
[form action="/cgi-bin/bill.pl" method="GET"]
Выдать статистику с [input type="text" name="start_date"] по [input type="text" name="end_date"]
[input type="submit" value="Сделать запрос"][br/]
Формат даты: YYYY-MM-DD (год-месяц-число)
Например, чтобы получить статистику за 1е января 2002года нужно ввести: 2002-01-01 2002-01-02
[/form]
[br][br]
DOC

if (@devices) {
print "В системе обнаружены следующие устройства:\n";

print '[ul]';
for (@devices) {
my $name = $dev_names{ $_-]{raw_mac} } || 'n/a';
print "[li]IP: $_-]{dip} Mac: $_-]{raw_mac} Имя: $name[/li]\n"
}
print '[/ul]';
}

my $start_date = param('start_date');
my $end_date = param('end_date');

my $posix_start_time = '';
my $posix_end_time = '';


if ( $start_date && $end_date ) {
if ( check_date($start_date) && check_date($end_date) ) {

my @period = query("SELECT UNIX_TIMESTAMP(?) AS start_period,
UNIX_TIMESTAMP(?) AS end_period", $start_date, $end_date );

if ( ($a = $period[0]-]{start_period} ) && ( $b = $period[0]-]{end_period} ) ) {
### print "[h3]Ы, параметры верны -- $a $b[/h3]";
( $posix_start_time, $posix_end_time ) = ( $a, $b );
} else {
error_params();
print 1;
}
} else {
error_params();
print 2;
}


} else {
# если диапазон не выбран, то текущий день
my @curr_day = query("SELECT UNIX_TIMESTAMP(CURDATE()) AS start_period,
UNIX_TIMESTAMP( date_add( CURDATE(), interval 1 day)) AS end_period,
CURDATE() AS cur_day,
DATE_ADD(CURDATE(), interval 1 day) AS next_day
;");


### print Dumper (\@curr_day);

( $posix_start_time, $posix_end_time ) = ( $curr_day[0]-]{start_period}, $curr_day[0]-]{end_period} );
( $start_date, $end_date ) = ($curr_day[0]-]{cur_day}, $curr_day[0]-]{next_day});

unless ($start_date && $end_date) {
print '[font color="red"]Хм, неожиданная ошибка[/font]';
print '[/body][/html]';
exit;
}
}


print "Статистика за указанный период ($start_date - $end_date):[br/][p][table]";
for (@devices) {
my @result = query("
SELECT SUM(ip_totlen) / 1024 / 1024 AS summ_traffic
FROM ulog
WHERE oob_time_sec ]= ? AND oob_time_sec [= ? AND ip_daddr = INET_ATON(?)",
$posix_start_time, $posix_end_time, $_-]{dip}
);
### print Dumper( [ '333', $posix_end_time, $posix_start_time] );
# ip_saddr
print "[tr][td]IP: $_-]{dip}[/td][td]Трафик: @{ [ $result[0]-]{summ_traffic} || 0 ] } mb[/td][/tr]\n";
}
print '[/table][/p]';

print "[/body][/html]";


Перед использованием заменить все [ на > и ] на >.

Вспомогательная инфа:

mysql -uroot -pphahde4I -Dtraffic -e 'source scheme.sql;'
http://192.168.155.51/cgi-bin/bill.pl?start_date=2002-1-1&end_date=2010-1-22
sudo tar -cjf nrgs_billing.tar.bz2 *



Собственно, сия программенция (web-интерфейс) умеет показывать через трафик, собранный демоном ulog.
Умеет показывать "за сегодня", "за текущий месяц", "за требуемый диапазон". Лицензия -- Artistic.
Пожелания, исправления, запросы фич -- приниманиются :) // хотя навряд ли кому такое нуна, но все же :)

вторник, 4 ноября 2008 г.

Веб мордочка для биллинга на Perl (Debian + ulogd-mysql): начало

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

Бан осуществляется так:
sudo iptables -A FORWARD -s 192.168.1.10 -j DROP разбанедь
sudo iptables -D FORWARD -s 192.168.1.10 -j DROP забанедь


Выборки по мак адресу производятся так:
select FROM_UNIXTIME(oob_time_sec), raw_mac, INET_NTOA(ip_saddr) as sip,INET_NTOA(ip_daddr) as dip, sum(ip_totlen) / 1024 / 1024 from ulog group by raw_mac;

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

sudo apt-get install lighttpd bzip2
sudo lighty-enable-mod cgi # включаем cgi
/etc/init.d/lighttpd force-reload

Идём в папку: /usr/lib/cgi-bin
sudo vim bill.pl
и туда:

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";


sudo chmod 755 bill.pl

Потом открываем http://192.168.155.51/cgi-bin/bill.pl и должны увидеть соотв-ую надпись :)
Всё, с подготовительными работами всё, продолжение читайте дальше =)

Подсчёт трафика на Debian Linux

Ставим: ulogd-mysql

Вот так выглядит дефалтовый конфиг: /etc/ulogd.conf

# Example configuration for ulogd
# $Id: ulogd.conf.in 714 2005-02-19 21:33:43Z laforge $
# Adapted to Debian by Achilleas Kotsis

[global]
######################################################################
# GLOBAL OPTIONS
######################################################################

# netlink multicast group (the same as the iptables --ulog-nlgroup param)
nlgroup=1

# logfile for status messages
logfile="/var/log/ulog/ulogd.log"

# loglevel: debug(1), info(3), notice(5), error(7) or fatal(8)
loglevel=5

# socket receive buffer size (should be at least the size of the
# in-kernel buffer (ipt_ULOG.o 'nlbufsiz' parameter)
rmem=131071

# libipulog/ulogd receive buffer size, should be > rmem
bufsize=150000

######################################################################
# PLUGIN OPTIONS
######################################################################

# We have to configure and load all the plugins we want to use

# general rules:
# 1. load the plugins _first_ from the global section
# 2. options for each plugin in seperate section below


#
# ulogd_BASE.so - interpreter plugin for basic IPv4 header fields
# you will always need this
plugin="/usr/lib/ulogd/ulogd_BASE.so"


# output plugins.
plugin="/usr/lib/ulogd/ulogd_LOGEMU.so"
#plugin="/usr/lib/ulogd/ulogd_OPRINT.so"
#plugin="/usr/lib/ulogd/ulogd_MYSQL.so"
#plugin="/usr/lib/ulogd/ulogd_PGSQL.so"
#plugin="/usr/lib/ulogd/ulogd_SQLITE3.so"
#plugin="/usr/lib/ulogd/ulogd_PCAP.so"


[LOGEMU]
file="/var/log/ulog/syslogemu.log"
sync=1

[OPRINT]
file="/var/log/ulog/pktlog.log"

[MYSQL]
table="ulog"
pass="changeme"
user="laforge"
db="ulogd"
host="localhost"

[PGSQL]
table="ulog"
schema="public"
pass="changeme"
user="postgres"
db="ulogd"
host="localhost"

[SQLITE3]
table="ulog"
db="/path/to/sqlite/db"
buffer=200

[PCAP]
file="/var/log/ulog/pcap.log"
sync=1


Вот так выглядит конфиг iptables, где пакеты отправляются в ULOG:

#!/bin/sh
INET="eth0" # internet iface
INETIP="192.168.155.51"

# сбрасываем все правила
iptables -F INPUT
iptables -F FORWARD
iptables -F OUTPUT

# политика по умолчанию
iptables -P FORWARD ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT

# это правило и отправляет пакеты на анализ ULOG
iptables -A FORWARD -i $INET -j ULOG --ulog-prefix "FORWARD" --ulog-cprange 0 --ulog-qthreshold 50

iptables -t nat -A POSTROUTING -o $INET -j SNAT --to-source $INETIP
echo "1" > /proc/sys/net/ipv4/ip_forward



Делаем sudo /etc/init.d/ulogd start, перезапускаем фаерволл и смотрим лог проходящих пакетов:
tail -f /var/log/ulog/syslogemu.log там должны замелькать записи :)

Теперь надо переключиться на MySQL для приёма логов, т.к. в таком виде их парсить... нет уж.
sudo apt-get install mysql-server
Потом запускаем mysql_secure_installation и выбираем новый пароль на root, пусть это будет: phahde4I

Теперь идём в /usr/share/doc/ulogd-mysql и там ищем файлик: mysql.table
Создаём БД для хранения трафика: mysqladmin -uroot -pphahde4I create traffic
Создаём таблицу во вновь созданной базе: mysql -uroot -pphahde4I -Dtraffic -e 'source mysql.table;'


Идём в настройки ulogd.conf и делаем следующее:
# output plugins.
#plugin="/usr/lib/ulogd/ulogd_LOGEMU.so"
#plugin="/usr/lib/ulogd/ulogd_OPRINT.so"
plugin="/usr/lib/ulogd/ulogd_MYSQL.so"
#plugin="/usr/lib/ulogd/ulogd_PGSQL.so"
#plugin="/usr/lib/ulogd/ulogd_SQLITE3.so"
#plugin="/usr/lib/ulogd/ulogd_PCAP.so"


и ещё правим блок:

[MYSQL]
table="ulog"
pass="phahde4I"
user="root"
db="traffic"
host="localhost"


Далее ребутаем ulogd: sudo /etc/init.d/ulogd restart и топаем в базу:
mysql -uroot -pphahde4I -Dtraffic
А там следим за ростом числа: select count(*) from ulog; -- это число перехваченных и записаных пакетов.

Итого ulogd конфиг принимает вид:

# Example configuration for ulogd
# $Id: ulogd.conf.in 714 2005-02-19 21:33:43Z laforge $
# Adapted to Debian by Achilleas Kotsis

[global]
######################################################################
# GLOBAL OPTIONS
######################################################################

# netlink multicast group (the same as the iptables --ulog-nlgroup param)
nlgroup=1

# logfile for status messages
logfile="/var/log/ulog/ulogd.log"

# loglevel: debug(1), info(3), notice(5), error(7) or fatal(8)
loglevel=5

# socket receive buffer size (should be at least the size of the
# in-kernel buffer (ipt_ULOG.o 'nlbufsiz' parameter)
rmem=131071

# libipulog/ulogd receive buffer size, should be > rmem
bufsize=150000

######################################################################
# PLUGIN OPTIONS
######################################################################

# We have to configure and load all the plugins we want to use

# general rules:
# 1. load the plugins _first_ from the global section
# 2. options for each plugin in seperate section below


#
# ulogd_BASE.so - interpreter plugin for basic IPv4 header fields
# you will always need this
plugin="/usr/lib/ulogd/ulogd_BASE.so"


# output plugins.
#plugin="/usr/lib/ulogd/ulogd_LOGEMU.so"
#plugin="/usr/lib/ulogd/ulogd_OPRINT.so"
plugin="/usr/lib/ulogd/ulogd_MYSQL.so"
#plugin="/usr/lib/ulogd/ulogd_PGSQL.so"
#plugin="/usr/lib/ulogd/ulogd_SQLITE3.so"
#plugin="/usr/lib/ulogd/ulogd_PCAP.so"


[LOGEMU]
file="/var/log/ulog/syslogemu.log"
sync=1

[OPRINT]
file="/var/log/ulog/pktlog.log"

[MYSQL]
table="ulog"
pass="phahde4I"
user="root"
db="traffic"
host="localhost"

[PGSQL]
table="ulog"
schema="public"
pass="changeme"
user="postgres"
db="ulogd"
host="localhost"

[SQLITE3]
table="ulog"
db="/path/to/sqlite/db"
buffer=200

[PCAP]
file="/var/log/ulog/pcap.log"
sync=1



Собственно, настройка системы подсчета трафика закончена, далее вопрос за её анализом и красивым отображением, но это в следующих статьях :)

Роутер на Debian4

Собственно, тут почти всё очевидно, так что приведу только конфиги.

Ставим Debian 4 Etch как "только standard system".

Правим /etc/apt/sources.list -- убираем строку, начинающуюся deb cdrom, иначе apt-get будет просить диск.

sudo apt-get install sudo bind vim mc ssh

В файл /etc/sodoers добавляем строку:
nrg ALL=(ALL) ALL
где nrg -- имя вашей пользовательской учётной записи, это позволит использовать sudo.

Заранее оговорюсь, что eth0 -- интерфейс, смотрящий на провайдера, а eth1 соответственно внутренний.

/etc/network/interfaces

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0 eth1

iface eth0 inet static
address 192.168.155.51
netmask 255.255.255.0
network 192.168.155.0
gateway 192.168.155.1
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 192.168.155.1 192.168.155.88
# судя по доке, использования этих днс
# опций нужно поставить resolvconf, но оно воркает и без него :)

iface eth1 inet static
address 192.168.1.1
netmask 255.255.255.0
network 192.168.1.0



/etc/network/if-up.d/nat (chmod +x)

#!/bin/sh
INET="eth0" # internet iface
INETIP="192.168.155.51"

# сбрасываем все правила
iptables -F INPUT
iptables -F FORWARD
iptables -F OUTPUT

# политика по умолчанию
iptables -P FORWARD ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT

iptables -t nat -A POSTROUTING -o $INET -j SNAT --to-source $INETIP
echo "1" > /proc/sys/net/ipv4/ip_forward


А этот конфиг скорее для юзерских машин, т.к. серверу он не нужен (т.е. всё работает даже тогда, когда он вообще пуст), все лучше делать через /etc/network/interfaces.
/etc/resolv.conf
nameserver 192.168.155.1
nameserver 192.168.155.88


Ещё может понадобится команда ручной установки шлюза:
sudo route add default gw 192.168.1.1

Конфиги частично взяты с http://linuxopen.ru/2008/07/03/nastrojjka-marshrutizatora-na-osnove.html .

среда, 23 июля 2008 г.

Как изменить комментарии к коммиту?

Вот недавно нарыл на просторах его великого и необъятного следующую штучку:
svn pe svn:log -r 1234 --revprop

Данная команда позволяет изменять комментарии к коммитам (по причине кривости или опечаток). Я, конечно же, сразу захотел её использовать, но репозиторий со мной не согласился:
svn: Repository has not been enabled to accept revision propchanges;
ask the administrator to create a pre-revprop-change hook


Ну лечится это довольно просто: идём в папку /var/spool/svn/имя_репозитория/hooks/ и там cp pre-revprop-change.tmpl pre-revprop-change и chmod +x pre-revprop-change , потом перезапускаем svnserve и вуаля :)

вторник, 1 июля 2008 г.

Lighttpd + WebDAV

Ставим пакеты:
apt-get update
apt-get install -y lighttpd
apt-get install -y lighttpd-mod-webdav

Добавляем в конфиг файл
vi /etc/lighttpd/lighttpd.conf

$HTTP["url"] =~ "^/dav($|/)" {
webdav.activate = "enable" # allow module
webdav.is-readonly = "disable" # enable write
webdav.sqlite-db-name = "/var/run/lighttpd/lighttpd.webdav_lock.db" # access to locaks and metadata database
}

Около блока "server.modules" ищем строку "mod_webdav" и убираем знак диеза слева, если он установлен.

После этого нам требуется создать хотя бы одну папку с доступом по WebDAV. Корнем веб сервера устанавливается папка /var/www, если вас устраивает такое положение, можете её так и оставить, в противном случае можете изменить её местоположение в конфиг файле. После этого создаем папку для WebDAV доступа:
mkdir /var/www/dav
chown www-data:www-data /var/www/dav

Ну и напоследок применяем настройки:
/etc/init.d/lighttpd restart

После это можно каким-нить WebDAV клиентом (я использовал nd) попробовать поиграться с папкой http://ваш_сайт/dav

Я использовал версию (в случае же проблем, обновляемся на более новую):
lighttpd-1.4.13 (ssl) - a light and fast webserver
Build-Date: Apr 15 2008 08:23:10

Играемс:
nd -d http://домен.ru:81/dav/suxx.ics --- удаление файла
nd -p wammu.log http://домен.ru:81/dav/suxx.log -- загружаем файл
nd -m http://домен.ru:81/dav/suxx555.log http://домен.ru:81/dav/suxx.log -- перемещаем файл
nd -v http://домен.ru:81/dav/555suxx.log -- запрос свойств объекта
У меня было выдано:
Status: 0
Last-Modified:
Created:
Size:
Content-Type:
Resource-Type:

Зададим новое свойство:
nd -l http://домен.ru:81/dav/suxx555.log -- блокируем объект
Lock: token="opaquelocktoken:aebb8df4-3321-4604-a8aa-cf69429c2725",
scope="exclusive",
owner-href="",
timeout="Second-600"

nd -u -t opaquelocktoken:aebb8df4-3321-4604-a8aa-cf69429c2725 http://домен.ru:81/dav/suxx555.log -- разлочим объект посредством "ключа", выданного нам при блокировке
nd -k http://домен.ru:81/dav/folder1 -- создаем новую папку

А вот далее интереснее:
nd -e test=12345 http://домен.ru:81/dav/suxx555.log
nd -v http://домен.ru:81/dav/suxx555.log
Name: http://домен.ru:81/dav/suxx555.log
Status: 0
Last-Modified:
Created:
Size:
Content-Type:
Resource-Type:


Как видите, вновь заданное свойство не показывается (хотя в sqlite лайта базе данных оно имеется). Это баг nd / lighttpd или же я туплю ? Попробуем другой WebDAV клиент, пожалуй, это будет cadaver.
[email protected]:~$ cadaver
dav:!> open http://домен.ru:81/dav
dav:/dav/> propset suxx555.log suxx 777
dav:/dav/> propget suxx555.log suxx
Fetching properties for `suxx555.log':
Value of suxx is: 777


Таки выходит, глюк nd. Ну вот и все, осталось только придумать, для чего использовать такой замечательный протокол :)

Офсайт lighttpd.

воскресенье, 29 июня 2008 г.

Документация по Subversion

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

Статья -- сравнение систем контроля версий между собой, здесь расписываются сильные и слабые стороны популярных VCS: RCS, CVS, SVN, Git, Bazaar, Aegis, Monotone.

Большая статья про Subversion:
Первая часть, вторая.

Практическое использование Subversion линк.

Блин, такими темпами скоро не про что писать будет :)

вторник, 24 июня 2008 г.

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

1) Во-первых требуется набрать оптимальную софтово-хардварную конфигурацию для относительно недорогого сервера бэкапов (сторадж 1-2 терабайта с рейдом 1+0 или 5)
2) Требуется продумать схему, по которой сервер бэкапов будет максимально универсален и безопасен (в данный момент предполагается использовать rsync поверх ssh). Требуется довольно немного -- механизм инкрементальных (те при обновлении файла тянем только изменившуюся часть, не изменившиеся файлы не трогаем) копий и возможность отката (с точностью до дня / часа) на месяц другой в прошлое.
3) Нужно как-то собирать логи (много-много-много логов!) с нескольких серверов, причем почти все они представляют собой обычные текстовые файлы и о таких вещах как syslog не слышали. Может есть какие централизованные системы сбора логов?
4) Вот ещё такой интересный вопрос -- все отлично знают, что легкие сервера по типу lighttpd и nginx очень хороши для раздачи статики и проксирования FastCGI / http серверов. А вот как будут они себя вести при раздаче очень больших файлов (такая своего рода "мегастатика")? Эдак очередь человек на 200 и раздача файлов по 1-2 гб. Вот если верить тестам на домашней странице Лайта http://www.lighttpd.net/benchmark , то он очень неплох при раздаче. Надо будет на досуге сравнить его с nginx при раздаче таких файлов.
5) А на каком веб сервере работает Akamai ? Пожалуй, это самый просто вопрос. Точно помню, что ATI раздает через них свои дрова, так сейчас и проверим :)

telnet a248.e.akamai.net 80
Trying 217.212.246.104...
Connected to a248.e.akamai.net.
Escape character is '^]'.
HEAD / HTTP/1.0

HTTP/1.0 400 Bad Request
Server: AkamaiGHost
Mime-Version: 1.0
Content-Type: text/html
Content-Length: 216
Expires: Tue, 24 Jun 2008 14:19:44 GMT
Date: Tue, 24 Jun 2008 14:19:44 GMT
Connection: close

Один вопрос решили, осталось узнать, что это за сервер такой (навряд ли открытый, но все же).
6) А я ведь думал, что когда говорили про kernel-based httpd, то это был стеб, казывается нет, прошу по ссылке: http://dir.filewatcher.com/d/Fedora/ppc64/System%20Environment/Daemons/tux-3.2.18-4.ppc64.rpm.88721.html

По этому же поводу довольно интересное обсуждение в apache-talk: http://www.lexa.ru/apache-talk/msg04850.html . Сам я довольно скептически отношусь к такого рода затеям как эта (вставлять в ядро типичный userspace демон! экий страх!), в первую очередь из-за вопроса безопасности (ну вопрос стабильности тут тоже не на последнем месте -- получить kernel panic посреди рабочего дня -- довольно интересно). Но с другой стороны можно сделать специальный сервер для раздачи и отделить его от основных серверов фаервольной стенкой, так как бы он стоял снаружи :) Если даже и взломают, то ничего ценного кроме конфига указанного сервер они не получат.

понедельник, 23 июня 2008 г.

KLone: каркас для web-программирования на языке C.

Вот довольно давно отрыл вот такую вот весьма извращенную вещь: KLone: каркас для web-программирования на языке C.

Может кому пригодится, у самого пока руки не дошли попробовать.

Списочек легких HTTPD

Вот списочком:
Сам пока не придумал, для чего их можно использовать... но вот последний умеет CGI, так что можно какую-нить админку на нём довольно легко налабать :)

пятница, 13 июня 2008 г.

Пара интересных веб сайтов -- хостинг на Nginx и rss2email

Сегодняшний день оказался довольно плодотворным по части поиска интересных сайтов.
Первый из них вот этот -- http://hosting.dekoda.net/index.html, как я понял из рекламных текстов, они занимаются хостингом на Nginx + MySQL + PHP (через PHP-FPM /* http://php-fpm.anight.org/about.html */ ) + Perl, первые три пункта у меня вопросов не вызвали, танцами и бубнами их можно заставить работать вместе... ну а Перл-то как они прикрутили? Обычный Перл как CGI прикрутить к Нджинксу без бэкэнда можно сказать нереально, остаётся единственный вариант -- подключение его как FastCGI, но тут вылазит куча проблем да и, вообще говоря, данная связка будет потреблять море ресурсов, что в конце-концов приведет к тому, что кто-нибудь из клиентов поест все ресурсы. Хотя с другой стороны предполагаю, что Перл написан на сайте ошибочно, но ради восстановления справедливости все же напишу в техподдержку как заинтересованный клиент :)

Второй сайт -- http://www.rss2email.ru/ представляет из себя типичный (никогда бы не подумал, что так скажу) WEB 2.0 проект. По сути в нём ничего необычного и выделяющегося нету -- просто сайт, где можно заказать перенаправление rss фидов на электронную почту. Но с другой стороны их "интерфейс настройки" ( http://www.rss2email.ru/ ) с моей точки зрения представляет собой идеал интерфейсостроения, ибо там лишь два поля, одно из них адрес -- rss фида, второе -- электронная почта, на которую слать его. Никаких тупых регистраций, никаких CAPTCHA, никаких лицензионных соглашений и прочих гадостей, одно слово -- идеал!

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

Nginx + HTTP Basic Authentication

Ну тема довольно простая и почти полностью описана в документации (http://sysoev.ru/nginx/docs/http/ngx_http_auth_basic_module.html), но все же опишу некоторые моменты.

Для начала открываем файл nginx.conf и ищем там следующие строки:

location / {
root   html;
index  index.html index.htm;
}

И заменяем их на следующее:
location / {
auth_basic            "closed site";
auth_basic_user_file  htpasswd;

root   html;
index  index.html index.htm;
}

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

Файл паролей положим в папку conf -- conf/htpasswd, его формат таков:
# комментарий
имя1:пароль1
имя2:пароль2:комментарий
имя3:пароль3
Пароли генерируются функцией crypt, также для их создания можно воспользоваться утилитой от веб сервера Apache -- htpasswd, ей мы и воспользуемся.
sudo htpasswd -cbd htpasswd nrg 12345
"-d" -- выбираем криптофункцию "crypt"
"-b" -- указываем считывание имени файла с паролями с командной строки
"-c" -- указываем создать новый файл
htpasswd -- имя вновь создаваемого файла
nrg -- имя добавляемого туда пользователя
12345 -- пароль пользователя

В итоге получаем файлик следующего содержания:
nrg:G8XDed1YWlwlM
И рестартим Нджинкс, после этого при попытке открыть главную страницу сайта должна выскакивать страница авторизации :)

Хм, а вот интересно, можно ли подружить Nginx c PAM или LDAP? А-то держать полтора десятка баз пользователей никакого удовольствия, а так можно было бы все сложить в одну базу. Если у кого есть мысли на этот счет, буду благодарен, если оставите их в комментах (:

Установка nginx из исходников

Вот после долгого затишья я снова тружусь на благо телекома :)
Сегодня мы будем заниматься легким веб сервером nginx (http://sysoev.ru), который мне понадобился для раздачи небольшого количества статики.

Сама установка выглядит довольно тривиально: сливаем дистрибутив 0.6й ветки вот отсюда: http://sysoev.ru/nginx/download.html и ставим тривиальным набором команд :

mkdir -p ~/nginx
cd ~/nginx
wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz
tar -xf nginx*
cd nginx*
./configure --prefix=/opt/nginx
make
sudo make install


Довольно стандартная схема без всяких сложностей... ну разве configure скрипт попросит вас поставить zlib и pcre, но относить это к сложностям как-то несерьёзно :) Как Вы могли заметить, мы ставим nginx не в саму систему, а в папку /opt/nginx, так как захламлять рабочую систему кучей хлама у меня лично нету никакого настроения.

Ну а теперь стоит вопрос, как нам все это дело удобно использовать (ну не каждый же день руками делать /opt/nginx/sbin/nginx), а в связи с тем, что в поставке nginx я не обнаружил готового скрипта для init.d, то нам придётся его писать или найти готовый (полагаю, второй вариант намного предпочтительнее) :)

Конечно же, я нашел готовый и его немного модифицировал, оригинал же взят отсюда: http://ssh3.livejournal.com/29252.html?thread=32836 , за что большое спасибо автору.

Скрипт управления сервером nginx:
#!/bin/bash

# v.0.0.3
# nginx - This shell script takes care of starting and stopping nginx.
# chkconfig: 345 20 80
# author site: nginx.net, sysoev.ru
# description: nginx [engine x] is light http web/proxy server
#              that answers incoming ftp service requests.
# processname: nginx
# config: /opt/nginx/conf/nginx.conf
# 
# Исходная версия: http://ssh3.livejournal.com/29252.html?thread=32836
# Изменённая версия: nrg [ at ] cpan [ dot ] org ( http://phpsuxx.blogspot.com/ ) 
#

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0
NGINX=/opt/nginx
CONFIG=$NGINX/conf/nginx.conf
EXEC=$NGINX/sbin/nginx
PID=$NGINX/logs/nginx.pid
PROG=nginx

[ -x $EXEC ] || exit 0

start() {

echo -n $"Starting NGINX: "
# Start daemons.
if [ -e $CONFIG ] ; then
$EXEC -t -c $CONFIG 2> /dev/null
[ $? -eq 0 ] && $EXEC -c $CONFIG &
RETVAL=$?
else
RETVAL=1
fi

if [ $RETVAL -eq 0 ] ; then
echo_success
else
echo_failure
fi

echo

return $RETVAL
}

stop() {
# Stop daemons.
if [ -e $PID ] ; then
echo -n "Shutting down $PROG: "
kill -QUIT `cat $PID`
RETVAL=$?
else
echo -n "Nginx not runned."
RETVAL=1
fi

if [ $RETVAL -eq 0 ] ; then
echo_success
else
echo_failure
fi

echo

return $RETVAL
}


restart() {
# Reload daemons.
if [ -e $PID ] ; then
echo -n "Reload $PROG: "
kill -HUP `cat $PID`
RETVAL=$?
else
echo -n "Nginx not runned."
RETVAL=1
fi

if [ $RETVAL -eq 0 ] ; then
echo_success
else
echo_failure
fi

echo

return $RETVAL
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reconfigure)
restart
;;
status)
status $NAME
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|reconfigure|status}"
exit 1
esac

exit $RETVAL



Теперь остаётся добавить скрипт в систему и все заработает,
как это сделать я описывать отдельно не буду, ssh3 отлично описал этот пункт,
поэтому позволю себе немного плагиата :)

Для автоматического страрта при загрузке системы достаточно скопировать
стартовый скрипт nginx в каталог /etc/init.d и выполнить следующие
команды:

#chkconfig --add nginx
#chkconfig --level 345 nginx on


Проверить статус можно командой:
#chkconfig --list | grep nginx
nginx 0:off 1:off 2:off 3:on 4:on 5:on 6:off


Ну вот, вроде, и все, в идеале, конечно, из этого стоило бы собрать deb / rpm пэкадж, но это уже дело каждого.

воскресенье, 4 мая 2008 г.

Подсветка синтаксиса VIM

В один прекрасный момент осознал, что стандартная подсветка синтаксиса (с белым фоном! о ужас!) в моём любимом vim'е меня категорически не устраивает и хочется чего-то чёрного и более приятного для глаз.

Ну что же, недолго побродив по vim.org я нашёл целую кучу цветовых схем, вот наиболее понравившаяся мне wombat

Ссылочка на скачку: http://www.vim.org/scripts/script.php?script_id=1778

Теперь будем перекрашивать гном :)
Вот и Гном перекрашен вот в это: http://gnome-look.org/content/show.php/Murrina-Black?content=46287

А для полного счастья вот и css для моей любимой пастилки http://php.suxx.us/s/paste.org.ru.css :)

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

воскресенье, 27 апреля 2008 г.

Автодополнение в Bash

Довольно часто при тестировании и отладке приходится рестартить апача для рекомпиляции приложения на mod_perl (тому, кто скажет, как от этого избавится или делать без рестарта Апача, буду несказанно благодарен), для чего приходилось использовать либо su, либо sudo.

Сегодня после небольшого ликбеза по sudo перелез на него с su. Но тут незадача -- если набивать sudo apache2ct<ТАБ>, то автодополнение НЕ сработает и придётся набивать название команды ручками, что жутко нервирует, когда кол-во таких "набивов" приближается к сотне за день.

Решений как всегда в линуксе несколько:

1) Прописать в ~/.bashrc
# включаем автодополнение для sudo
complete -cf sudo


2) Либо поступить более кОмплексно и поставить пакет bash-completion, который к указанной фиче предоставит ещё ряд вкусностей, про которые можете прочитать на http://www.debian-administration.org/articles/316

Попутно мне понадобилось внести коррективы в переменную среды PATH, т.к. в моей Сусе по соображениям безопасности в PATH для простых юзеров не включаются директории бинариков */sbin.

Фиксится это одной строкой в указанно ~/.bash_rc:
# добавим sbin в юзерский патч
PATH=/sbin:/usr/sbin:/usr/local/sbin:$PATH


Первая идея была взята с: ссылко

суббота, 19 апреля 2008 г.

Скачиваем видео с Youtybe посредством wget, sed и linux :)

Вот решил скачать для локального использования давно полюбившийся мне клип группы Леон "Метро 2033".
Искать "ещё один супер пупер качальщик с Ютуба" категорически не хотелось, поэтому довольно быстро было найдено решение, прямо-таки по Unix-way, а именно скрипт на Shell, который скачивает flv и ложит в текущую папку его :)

Скрипт вот:

RAW=`wget -O - $1 | grep 'fullscreenUrl' | sed 's/^.*video_id=//'`
TITLE=`echo $RAW | sed 's/^.*title=//' | sed 's/[^a-zA-Z0-9]//g'`
ID=`echo $RAW |sed 's/&fs.*$//'`
wget -O $TITLE.flv "http://www.youtube.com/get_video.php?hl=en&video_id=$ID"


Взято: http://linux.byexamples.com/archives/302/how-to-wget-flv-from-youtube/#comment-18455


После того, как был слит клип в flv ещё и оказалось, что он отлично играется моим любимым плеером vlc :)

четверг, 17 января 2008 г.

Решение проблемы с Apache2::ModSSL OpenSuse 10.3

При установке данного модуля высыпается несколько проблем -- первая из них, идёт много ругани на отсутствие mod_perl.h, но если путь с этим файликом жёстко прописать в Makefile.PL (который был предварительно сгенерирован посредством perl Makefile.PL, все файлы лежат по пути ~/.cpan/build/Apache2-ModSSL-0.03-некоторые_символы):
INC = -I/usr/include/apache2 -I/usr/include/apache2/modules/perl


То высыпется ещё целая прорва ошибок сборки, которая решается прописыванием путей к заголовочным файлам библиотеки apr:
INC = -I/usr/include/apache2 -I/usr/include/apache2/modules/perl -I/usr/include/apr-1


Ну и конечно же, devel версии пакетов Apache2 и mod_perl должны стоят в системе :)

среда, 16 января 2008 г.

Немного о CPAN

Как удалить модуль с хранилища модулей (локального, конечно же) CPAN?

В общем случае никак (?), но бывают исключения. В конфигурационном файле CPAN (/usr/lib/perl5/5.8.8/CPAN/Config.pm) есть переменная ('build_dir'), отвечающая за расположение папки для временного хранения модулей перед установкой. Как можно понять, в этой папке хранятся инсталяцонные файлы модулей, которые представляют из себя стандартный комплект -- Makefile.PL / Build.pl и обычно уже созданный Makefile (т.к. данные модули уже были установлены Вами), который и устанавливает модуль в хранилище. А у Данного Make файла присутствует цель uninstall, т.е. можно выполнить make uninstall и либо удалить модуль сразу, либо получить рекомендации для удаления.

Но, к несчастью, данный метод не универсальный, но почти во всех случаях, когда мне было необходимо по тем или иным причинам удалить модуль, он срабатывал :)


Конфигурирование CPAN.

CPAN при запуске очень любит доставать вопросами о конфигурации. Чтобы отучить его заниматься сим противным занятием давайте напрямую отредактируем конфиг файл /usr/lib/perl5/5.8.8/CPAN/Config.pm
(его расположение меняется от дистрибутива к дистрибутиву, так что если что проявите смекалку и отыщите его). Ниже привожу свой конфиг файл.


# This is CPAN.pm's systemwide configuration file. This file provides
# defaults for users, and the values can be changed in a per-user
# configuration file. The user-config file is being looked for as
# ~/.cpan/CPAN/MyConfig.pm.

$CPAN::Config = {
'build_cache' => q[100],
'build_dir' => q[/home/nrg/.cpan/build],
'cache_metadata' => q[1],
'cpan_home' => q[/home/nrg/.cpan],
'cpan_version_check' => q[1],
'dontload_hash' => { },
'ftp' => q[/usr/bin/ftp],
'ftp_proxy' => q[],
'getcwd' => q[cwd],
'gpg' => q[/usr/bin/gpg],
'gzip' => q[/bin/gzip],
'histfile' => q[/home/nrg/.cpan/histfile],
'histsize' => q[100],
'http_proxy' => q[],
'inactivity_timeout' => q[0],
'index_expire' => q[1],
'inhibit_startup_message' => q[0],
'keep_source_where' => q[/home/nrg/.cpan/sources],
'lynx' => q[],
'make' => q[/usr/bin/make],
'make_arg' => q[],
'make_install_arg' => q[],
'makepl_arg' => q[INSTALLDIRS=site],
'ncftp' => q[],
'ncftpget' => q[],
'no_proxy' => q[],
'pager' => q[/usr/bin/less],
'prerequisites_policy' => q[follow],
'scan_cache' => q[atstart],
'shell' => q[/bin/bash],
'tar' => q[/bin/tar],
'term_is_latin' => q[1],
'unzip' => q[/usr/bin/unzip],
'urllist' => [q[ftp://cpan.makeperl.org/pub/CPAN], q[ftp://cpan.nx1.ru/], q[ftp://cpan.rinet.ru/pub/mirror/CPAN/], q[ftp://ftp.aha.ru/CPAN/], q[ftp://ftp.chg.ru/pub/lang/perl/CPAN/], q[ftp://ftp.spbu.ru/CPAN/], q[http://ftp.silvernet.ru/CPAN/], q[http://mirror.rol.ru/CPAN/]],
'wget' => q[/usr/bin/wget],
};
1;
__END__


Вот примерно такой вид должен иметь наш конфиг файл, но в случае проблем при его использовании придётся переконфигурировать Цпан вручную, это делается довольно просто -- удаляем указанный конфиг файл Цпана и запускаем сам cpan :)

А вот для пользователей убунту данный конфиг стоит искать по адресу: /etc/perl/CPAN/Config.pm

Как бороться с ошибками вида: "Has already been unwrapped into directory /root/.cpan/build/ИМЯ_модуля-некая_уникальная_последовательность" ?

Такое бывает, когда сваливаются тесты модуля или Вы любите поэксперементировать с Цпаном. Это решается в лоб: rm -r /root/.cpan/build/ИМЯ_модуля-*

понедельник, 14 января 2008 г.

Новое в Перл 5.12 и немного о my и local

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

Вот уже третий день усиленно вычитываю статьи на opennet.ru, вот сегодня наткнулся на очень хорошее описание разницы (хотя не совсем разницы, скорее указываются тонкости применения каждого из них) между my и local в Перл5, а вот и ссылка.

воскресенье, 13 января 2008 г.

MVC Catalyst + Apache2 mod_perl

Ах, кто к нам такой пришёл ?) А пациентом у нас сегодня будет Perl приложение (простите, но скриптом уже язык не поворачивается называть) на очень прогрессивном MVC фреймворке Catalyst... стоп, а что за Каталист-то? А вот, пожалуйста статья.

По ссылке довольно хорошее введение в предмет, так что не думаю, что возникнет много вопросов. В этой же статье описывается создание простейшего (но вот "простоту" своего нового Стартапа определяете сами :) приложения на данной платформе, у меня оно будет расположено по следующему пути: /home/nrg/dev/my_catalyst_app/lib, так что все последующие конфиги будут идти с учётом оного.

А вот по данной ссылке можно наблюдать описание процесса настройки mod_perl2 для исполнения Каталист приложений. Открываем конфиг файл /etc/apache2/conf.d/mod_perl.conf и внутри тегов <IfModule mod_perl.c> и </IfModule> после всех остальных записей добавляем следующее:

PerlSwitches -I/home/nrg/dev/my_catalyst_app/lib
PerlModule my_catalyst_app
<Location /cat>
SetHandler perl-script
PerlResponseHandler my_catalyst_app
</Location>

Строчка с PerlSwitches указывает веб серверу путь, по которому искать наш обработчик событий для mod_perl (им и будет наше приложение), директива "PerlModule my_catalyst_app" указывает о том, что компиляция нашего проекта будет проведена сразу после запуска Апача, а о назначении остальных строк, думаю, можно догадаться самим, там всё предельно просто - указываем тип обработчика и выбираем наше приложение обработчиком.

После данных манипуляция, перезапускаем Апача - service apache2 restart и смотрим tail -n20 /var/log/apache2/error_log, если там присутствует ошибка Can't locate Catalyst/Engine/Apache2/MP20.pm in @INC, то от имени суперпользователя root устанавливаем недостающий модуль: cpan Catalyst::Engine::Apache2::MP20

Ну вот, пожалуй, и всё, снова перезапускаем сервер и открываем страницу http://127.0.0.1/cat, где видим красивый лейбл Каталиста :)

Добавление от 24 июня.

Вот приобрел хостинг на Дебияне, нашел более удобный способ конфигурирования -- добавить все настройки в отдельный файл /etc/apache2/mods-available/perl.load (который создан ранее).

В итоге у меня получился вот такой небольшой конфиг для Каталиста на отдельном домене:

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so

PerlSwitches -I/home/nrg/MyApp/lib

<VirtualHost 72.4.76.1:80>

ServerName www.goosync.ru
ServerAlias host.ru *.host.ru

<IfModule mod_perl.c>
PerlModule MyApp
SetHandler perl-script
PerlResponseHandler MyApp
</IfModule>

</VirtualHost>

суббота, 12 января 2008 г.

Циклические ссылки и сборщик мусора в Perl (perl trash garbage)

Я, конечно, понимаю, что из-за одной ссылки делать целый пост аморально, но статья очень хорошая и для разработчика под mod_perl и FastCGI относится к разряду MUST READ, ссылка в студию: http://www.opennet.ru/base/dev/perl_destruction.txt.html

Apache2 MPM Worker + mod_perl2 на OpenSuse 10.3

В установке данной связки ничего сильно сложного нету, но тем не менее на некоторые моменты стоит обратить внимание. Для начала ставим пакеты apache2, apache2-worker, apache2-utils, apache2-mod_perl и apache2-example-pages через Yast2 или вручную, это уже зависит от Ваших предпочтений. В заголовке статьи я специально сделал акцент на то, что настройка именно для Опенсусе, т.к. некоторые моменты при конфигурировании могут отличаться от дистрибутива к дистрибутиву. Все рассуждения и выводы будут основаны на данной статье.

После того, как всё было успешно (а я ,надеюсь, это так и будет) установлено переходим к настройке. Для начала запустим Апач командой service apache2 start, после этого будет выведено: Starting httpd2 (worker) done, это означает, что запуск веб сервера Apache2 c MPM Worker выполнен успешно.

Далее нам необходимо просмотреть список модулей, которые загружаются сервером, для этого можно воспользоваться командой: apache2ctl -t -D DUMP_MODULES, как можно видеть, там нету perl_module (именно так зовётся модуль mod_perl), поэтому нам нужно сообщить серверу о том, что мы хотим использовать именно его. Список модулей, загружаемых Apache2, хранится в файле /etc/apache2/sysconfig.d/loadmodule.conf, но его особенность в том, что все изменения в нём живут до перезапуска сервера, т.к. в это время конфиг файл затирается и приводится в первоначальную форму. Как можно понять, добавлять в этот конфиг mod_perl2 бесполезно, но куда же его прописывать? Некоторое время поломав голову, я-таки понял, что где-то есть внешний конфиг файл, где и хранится список модулей, на основе которого и создаётся loadmodule.conf - это файл /etc/sysconfig/apache2. Открываем его на редактирование любимым редактором текстов, например vim, ищем строку APACHE_MODULES="а здесь список модулей" и добавляем в неё mod_perl, не забывая, что имена модулей отделяются друг от друга пробелами.

Далее снова ерезапускаем Apache2 и смотрим список модулей командой apache2ctl -t -D DUMP_MODULES, теперь же в этом списке должен появиться "perl_module (shared)". Ещё один способ убедиться в успешной загрузке mod_perl - это команда tail -n20 /var/log/apache2/error_log, далее ищете в лог файле строку наподобие вот этой:
[Sat Jan 12 11:51:58 2008] [notice] Apache/2.2.4 (Linux/SUSE) mod_ssl/2.2.4 OpenSSL/0.9.8e mod_perl/2.0.3 Perl/v5.8.8 configured -- resuming normal operations

Теперь попробуем запустить обычный perl cgi скрипт. Просмотрев конфиг файл /etc/apache2/default-server.conf, можно понять, что обычным местом для CGI приложений является папка /srv/www/cgi-bin (если её нету, то Вам потребуется её создать). В указанной папке создаём файл hello.pl следующего содержания:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Standard CGI!\n";

После этого нам нужно поставить права 755 для файла hello.pl, для этого можно использовать команду chmod a+rx hello.pl. Всё, можете пробовать открыть ссылку http://127.0.0.1/cgi-bin/hello.pl, если отобразится "Standard CGI!", то с настройкой обычного CGI мы закончили. Переходим непосредственно к настройке к mod_perl.

Создадим папку для наших mod_perl2 приложений - mkdir /srv/www/cgi-fast. Далее переименуем старый конфиг mod_perl2 mv /etc/apache2/conf.d/mod_perl.conf /etc/apache2/conf.d/conf_old, т.к. мы его будем заменять на новый, а старый лишь сохраняем на всякий случай, вдруг пригодится.

Создаём файл /etc/apache2/conf.d/mod_perl.conf следующего содержания:
Alias /cgi-fast/ /srv/www/cgi-fast/

<IfModule mod_perl.c>
PerlRequire "/etc/apache2/mod_perl-startup.pl"
<Location /cgi-fast/>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
# PerlResponseHandler ModPerl::PerlRun 
# выбор конкретного модуля определяется
# условиями решаемой задачи
# более подробно про модули на search.cpan.org
PerlOptions +ParseHeaders
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
</IfModule>


Далее в папке /srv/www/cgi-fast создаём файл test.pl следующего содержания:
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Standard CGI from mod_perl folder!\n";
print $ENV{MOD_PERL};


Выставляем права chmod a+rx test.pl, проверяем http://127.0.0.1/cgi-fast/test.pl, скрипт должен напечатать строки: Standard CGI from mod_perl folder! и mod_perl/2.0.3, что повествует о работоспособности mod_perl. Как можно понять, в этом случае мы произвели запуск обыкновенного Perl скрипта через mod_perl.

Создаём в папке /srv/www/perl-lib подпапку MyApache2 и во вновь созданной папке создаём файл Rocks.pm следующего содержания:
#file:MyApache2/Rocks.pm
#----------------------
package MyApache2::Rocks;

use strict;
use warnings;

use Apache2::RequestRec ();
use Apache2::RequestIO ();

use Apache2::Const -compile => qw(OK);

sub handler {
my $r = shift;

$r->content_type('text/plain');
print "mod_perl2 application rocks!!!\n";

return Apache2::Const::OK;
}
1;



Теперь добавляем в конфиг /etc/apache2/conf.d/mod_perl.conf следующий блок:
<Location /rocks>
SetHandler perl-script
PerlResponseHandler  MyApache2::Rocks
</Location>


Таким образом конфиг примет вид:
Alias /cgi-fast/ /srv/www/cgi-fast/

<IfModule mod_perl.c>
PerlRequire "/etc/apache2/mod_perl-startup.pl"
<Location /cgi-fast/>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
# PerlResponseHandler ModPerl::PerlRun
PerlOptions +ParseHeaders
Options +ExecCGI
Order allow,deny
Allow from all
</Location>
<Location /rocks>
SetHandler perl-script
PerlResponseHandler  MyApache2::Rocks
</Location>
</IfModule>


Теперь открываем http://127.0.0.1/rocks и, надеюсь, радуемся увиденному :)

Apache2 prefork vs worker

Довольно продолжительное время при установке веб сервера Apache я сомневался, ставить ли мне apache2-worker или apache2-prefork, вот и настал момент, когда стоит устранить все неясности в этом выборе и явно описать, что и когда лучше использовать.

Официальная документация сервера говорит о следующем:
Choosing an MPM

Apache 2.x supports pluggable concurrency models, called Multi-Processing Modules (MPMs). When building Apache, you must choose an MPM to use. There are platform-specific MPMs for some platforms: beos, mpm_netware, mpmt_os2, and mpm_winnt. For general Unix-type systems, there are several MPMs from which to choose. The choice of MPM can affect the speed and scalability of the httpd:

* The worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.
* The prefork MPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork's threadless design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.

For more information on these and other MPMs, please see the MPM documentation


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

В документации рассказывается, что у сервера Apache2 мультипоточность реализована посредством подключаемых модулей - MPM (по поводу перевода я сомневаюсь, но, на мой взгляд, лучше перевести как "модули мультипоточной обработки", хотя далее я буду использовать аббревиатуру в виду громоздкости данного названия), которые являются платформозависимыми. Существует две основных модели MPM модулей - это worker MPM и prefork MPM.

Worker работает следующим образом - при запуске создаётся несколько дочерних процессов, по несколько потоков в каждом (сколько именно подразумевается под "несколько" задаётся в конфиг файле Apache2). В качестве преимущества данного модуля указывается пониженное потребление памяти по сравнению с Prefork модулем. Также этот модуль рекомендуется для высоконагруженных веб серверов.

Prefork же создаёт некоторое количество дочерних процессов, но в отличие от Worker, в каждом из них ровно по одному потоку. Т.е. каждый процесс обрабатывает только одно соединение. По поводу скорости указывается, что скорость обоих модулей более-менее соизмерима, но Prefork потребляет больше памяти. Использование безпоточного модуля Prefork предпочтительно в случае использования модулей, который не обладают безопасной мультипоточностью. Также рекомендуется использовать Prefork на платформах, где отладка мультипоточных приложений не реализована на должном уровне (к слову говоря, отлаживать мультипоточные приложения даже на системах с хорошей поддержкой оного - занятие не из простых).


В заключение хотелось бы добавить, что однозначного выбора не существует, всё определятся решаемыми задачами, но следует помнить, что модель Prefork (она, кстати, была единственной моделью, которую поддерживали сервера на Apache 1.3) является заведомо более стабильной, т.к. сбой в одном процессе не затрагивает другие процессы, а в случае Worker сбой в одном потоке может вывести из строя ещё несколько соседних потоков, хотя Worker показывает более высокую скорость в определённом спектре задач (в частности высоконагруженные сервера).

А вот данные реального тестирования: http://www.camelrichard.org/apache-prefork-vs-worker
Стабильности серверов в обоих случаях была 100%, а вот Worker почти в 2 раза обогнал Prefork, но тем не менее это не значит, что и на большем количестве соединений результаты будут в том же самом соотношении да и тест синтетический, в реальных условиях всё может быть иначе.

А вот на тему скорости работы: http://www.camelrichard.org/apache-prefork-vs-worker (mpm worker показывает двухкратный прирост производительности на Solaris!) Для Линукса такого роста, к несчастью, нету: http://www.thrull.com/corner/webserver/prefork-vs-worker/

Сейчас попробуем провести тесты, как будет работать Apache+ mod_fcgi PHP в конфигурациях Prefork и Worker.