07.05.2012

Сборка пакета PAM-SQLite и NSS-SQLite

Как многим известно, аутентификация в Linux проходит централизованно в PAM. Стандартно PAM использует файлы /etc/passwd (и еще несколько: shadow, group,  и т.д.). В крупных компаниях предпочитают держать пользователей не в файлах, а в LDAP. Но если Вы пишете свое приложение, то наверняка хотите хранить пользователей в базе. Для MySQL и PostgreSQL в репозиториях Debian есть стандартные пакеты libpam-mysql и libpam-pgsql. Но что делать, если пользователи живут в SQlite? Об этом ниже, а пока небольшая вводная, важная к прочтению:

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

Процесс происходит примерно так (рассмотрим на примере SSH). Демон SSH принимает соединение с логином и паролем.
Теперь перед SSH-демоном две задачи:
1) Identity. Установить, что пользователь вообще существует.
(это делается на первом слое: NSS)
2) Authnetication. Проверить его пароль.
(это делается на втором слое: PAM, если конечно в /etc/ssh/sshd_config стоит настройка "UsePAM yes" ).

Далее, через систему NSS он смотрит настройки. Находятся они в файле /etc/nsswitch.conf. По дефолту там стоит так:

passwd:         compat
group:           compat
shadow:        compat
compat - значит локальные файл (/etc/passwd,/etc/shadow,/etc/group)
Можно добавить своё, например:
passwd:         compat   ldap   sqlite
group:           compat   ldap   sqlite
shadow:        compat   ldap   sqlite
В таком случае система сначала будет искать пользователя в файлах, если нет, то в LDAP и наконец в SQLite.

Поэтому кроме пакета libpam-sqlite вам понадобится еще пакет libnss-sqlite, чтобы NSS вообще понимал такую инструкцию как "sqlite".

====
Теперь разберемся откуда брать код.
Поиск кода обоих приложений (libnss-sqlite и libpam-sqlite) приводит на аккаунт github Sectoid. Но ведет его достаточно вяло. libpam-sqlite остановился на версии 0.3. Эта версия поддерживает SQLite2, а вот SQLite3 - нет.
Версию 0.3 уже, в свою очередь форкнул ip1981 и добавил в неё поддержку SQLite3, назвав ее версией 0.4.
Но я внезапно нашел вот уже версию 1.0.1 (с поддержкой SQLite3).



Нам понадобятся пакеты:
apt-get install libpam0g-dev libmhash-dev libsqlite0-dev
И инструменты сборки:
apt-get install dh-make dpatch devscripts autoconf  shtool libtool
Переходим в директорию, где будем работать:
cd /usr/src
Скачиваем исходники с сайта:
git clone https://github.com/dtjm/pam_sqlite3.git libpam-sqlite-1.0.1

05.05.2012

Логин в RHEL/CentOS/OEL под рутом с RSA-ключом

RHEL-like операционные системы, в отличии от Debian, очень сильно защищены. Сразу после инсталляции Вы получите полный набор заборов в виде SElinux, iptables и прочих. Привыкшему человеку это нормально (оно как бы даже спокойнее), а вот новичка такое состояние приведет к эйфории эфтаназии.
Особо "грамотные" советуют выключить все это. Но я бы им по губам бил за такие советы. Умные дяденьки не для того нас оберегали от безопасности, чтобы мы ей пренебрегали. Подобные вопросы надо решать только по-спортивному.

Одна из таких засад: невозможность залогиниться под рутом с ключом.

Причин две.
1) В RHEL-вском SSH по умолчанию стоит StrictModes yes. Это значит, что мы должны создавать директории и файлы SSH с нормальными правами, а не как рубахи-парни.
mkdir /root/.ssh
chmod 700 /root/.ssh
и
touch /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

2) Но и после этого законнектиться ключем будет невозможно. В этот раз вредит SElinux.
Чинится так:
restorecon -R -v /root/.ssh




29.04.2012

Сборка eAccelerator под Debian

Для начала установим необходимые пакеты для сборки PHP и вообще сборки пакетов:
apt-get install php5-dev dh-make autotools-dev gcc-4.3 debhelper devscripts
Так же нужно учесть одну особенность eAccelerator - он будет работать только с той версией PHP, с которой был собран. Если у Вас на тестовом сервере одна версия PHP, например 5.3.3-7+squeeze3,  а на продакшене 5.3.3-7+squeeze8, то eAccelerator не заведется и будет выкидывать такую ошибку:
[eAccelerator] This build of "eAccelerator" was compiled for PHP version 5.3.3-7+squeeze3. Rebuild it for your PHP version (5.3.3-7+squeeze8) or download precompiled binaries.

Чтобы этого избежать, нам надо подтянуть версию на тестовой машине до сервера, где будет использоваться eAccelerator:
apt-get install php5=5.3.3-7+squeeze8 php5-dev=5.3.3-7+squeeze8
Переходим в директорию, где будем работать:
cd /usr/src
Скачиваем туда тарбол с исходниками.

Распаковываем его:
unzip eaccelerator-0.9.6.1.zip
Так как все расширения PHP принято обзывать php5-extention (например php5-tidy, php5-memcached, php5-mysql и т.д.), а имя/версия пакета будет создано на основе имени директории, то переименуем директорию:
mv eaccelerator-0.9.6.1 php5-eaccelerator-0.9.6.1
Заходим в распакованную директорию:
cd php5-eaccelerator-0.9.6.1

Открываем конфиг и настраиваем под себя. Я, например, люблю когда кэш лежит там где он должен лежать по FHS - в /var/cache, а не в /tmp. А еще нужно поправить путь к логу, потому что у нас Debian, а там CentOS-вский путь:
vi eaccelerator.ini

Далее нужно PHP-зировать пакет - подогнать под API PHP:
phpize
И теперь уже можно его конфигурировать:
./configure --with-eaccelerator-debug

26.04.2012

Аутентификация SSH через LDAP public key

До того, как начать, нужно обязательно научить SSH работать с LDAP.  Без этого дальше можно не читать.


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

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

Например. Мы видим, что есть патчи под 5.1, 5.3, 5.4. А у нас Squeeze, с которым идет 5.5. Значит смотрим Lenny - там шла 5.1. А на эту версию у нас патч как раз есть. Добавляем репозиторий Lenny:

vi /etc/apt/sources.list

## Debian Lenny base:
deb http://archive.debian.org/debian/ lenny main non-free contrib
deb-src http://archive.debian.org/debian/ lenny main non-free contrib
Обновляем:
apt-get update

Перейдем в директорию работы с исходным кодом:
cd /usr/src/

Смотрим какие версии нам стали доступны после подключения репозитория от Lenny:
apt-cache show openssh-server | grep Version
Скачаем исходники OpenSSH нужной нам 5.1-версии:
apt-get source openssh-server=1:5.1p1-5

И затем зайдем туда:
cd openssh-5.*p1

07.04.2012

Где достать репозитории Debian Lenny

С тех пор, как Lenny перешел в состояние устаревшего, все его репозитории переместили в archive*


## Debian Lenny base:
deb http://archive.debian.org/debian/ lenny main non-free contrib
deb-src http://archive.debian.org/debian/ lenny main non-free contrib

## Debian Lenny updates:
deb http://archive.debian.org/debian/ lenny-updates main non-free contrib
deb-src http://archive.debian.org/debian/ lenny-updates main non-free contrib

## Debian Lenny Security updates:
deb http://archive.debian.org/debian-security/ lenny/updates main contrib non-free
deb-src http://archive.debian.org/debian-security/ lenny/updates main contrib non-free

## Debian Volatile updates:
deb http://archive.debian.org/debian-volatile lenny/volatile main contrib non-free
deb-src http://archive.debian.org/debian-volatile lenny/volatile main contrib non-free

## Debian Lenny Backports
deb http://archive.debian.org/debian-backports lenny-backports main contrib non-free
deb-src http://archive.debian.org/debian-backports lenny-backports main contrib non-free

26.02.2012

Сборка PHP в Debian в альтернативную директорию

На просторах Интернета имеется достаточно большое количествео разнообразных мануалов на тему сборки PHP. К сожалению, всех их объединяет одно: все они делаются через make install (читайте: через интимное место). О причинах распыляться не буду, порекомендую лишь статью на Хабре с многоговорящим названием: Хочется взять и расстрелять, или ликбез о том, почему не стоит использовать make install.

В данном мануале я не ограничусь только сборкой одного пакета.Мы соберем все популярные версии и {в}рапперы для него.

Все, что собирается - собирается на Debian Squeeze для FastCGI. Шаг влево/шаг вправо и мануал уже не подходит. Например на Lenny даже близко не так все будет. Я очень рекомендую установить чистенькую свежую систему, чтобы не спотыкаться об пакеты из неродных репозиториев и их разломанными зависимостями.


Начнем с того, что поставим зависимости, которые возможно нам и не понадобятся, но они указаны к стандартному PHP мейнтейнерами:
apt-get install apache2-prefork-dev autoconf automake bison chrpath flex freetds-dev hardening-wrapper libapr1-dev  libbz2-dev libc-client-dev libcurl4-openssl-dev libenchant-dev libevent-dev libexpat1-dev libfreetype6-dev libgcrypt11-dev libgd2-xpm-dev libglib2.0-dev libgmp3-dev libicu-dev libjpeg-dev libkrb5-dev libldap2-dev libmcrypt-dev libmhash-dev libmysqlclient-dev libonig-dev libpam0g-dev libpng12-dev libpq-dev libpspell-dev libqdbm-dev librecode-dev libsasl2-dev libsnmp-dev libsqlite0-dev libsqlite3-dev libt1-dev libtidy-dev libtool libwrap0-dev libxmltok1-dev libxml2-dev libxslt1-dev locales-all mysql-server quilt re2c unixodbc-dev firebird2.1-dev libgdbm-dev libcurl4-openssl-dev libssl-dev  libreadline-dev libedit-dev

Отлично. Теперь поставим утилиту, которой будем собирать пакеты:
apt-get install checkinstall
Конечно эта утилита - детская лопатка для игры в песочнице. Настоящие мейнтейнеры таким не пользуются, но у меня пока не хватает знаний и ума сделать все вообще по высшему пилотажу. Да и quilty нам не особо пока нужен.

Создадим директории для работы над нашими пакетам:
mkdir -p /usr/src/php/php5.2 /usr/src/php/php5.3 /usr/src/php/php5.4 /usr/src/php/php-switcher

Итак перейдем с сборке первого пакета - PHP 5.2

09.01.2012

Какой файл .php исполняется как FastCGI на моем сервере и грузит CPU?

Ответа нет, потому как вопрос задан некорректно. Чтобы докапаться до истины расскажу в кратце как работает FastCGI.
От клиента, будь это браузер или реверс-прокси перед вэб-сервером, поступает запрос на исполнение некоего .php файла (пусть в нашем примере будет index.php). Вэб-сервер создает отдельный от себя процесс, который видно в топе как php-cgi, и говорит ему: "Ты создан! Теперь вот тебе файл index.php, исполни его и верни мне результат." Далее происходит вот что. FastCGI процесс берет файл index.php и проходится по его коду (вопрос компиляции я тут опущу за ненадобностью). На пути встречает include соседних файлов и их соответственно тоже запускает. И, напомню, все это один процесс php-cgi, который пробегает по многим .php файлам.
Затем, как только php-cgi процесс отдаст результаты обратно вэб-серверу, вэб-сервер, исходя из конфига, решит что делать с этим процессом - либо убить, либо оставить для обработки следующих запросов (чтобы заново его не рожать). Но, опять же согласно конфигу, он будет еще поглядывать за этим процессом: сколько раз он выполнял задачи, как часто проставивает, не превратился ли в зомби, не завис ли, не обработал ли слишком много запросов и так далее, пока все-таки не найдет достаточного основания для убийства этого процесса и порождения нового на его место.
То есть один php-cgi процесс - это не только не один .php файл, это еще и не одна порция таких файлов.Чтобы было более понятно, процесс php-cgi, который мы видим в ps, это ничто иное как контейнер, запущенный в памяти интерпретатор, наподобии как Tomcat у Java.
Именно поэтому не нужно удивляться, что при ограничении max_execution_time = 120 секунд в php.ini, в списке процессов вдруг виден процесс, который висит вот уже неделю. Он таких по 120 секунд за свою недельную жизнь видал не перевидал, все через него прошли, как через матрешку.


Для наглядности проведем эксперимент.

Посмотрим, сколько процессов у нас на сервере запустил некто user1316 (много строк я потер, чтобы не получалась длинная простыня).

node1-2:~# ps aux | grep user1316 | grep -v grep

user1316 48214  5.1  0.1 234148 33148 ?        S    10:54   1:52 /usr/bin/php5-cgi php
user1316 48215  5.0  0.1 249040 48068 ?        S    10:54   1:50 /usr/bin/php5-cgi php
user1316 48238  5.9  0.1 244976 43980 ?        S    10:54   2:11 /usr/bin/php5-cgi php
user1316 48242  3.7  0.2 251160 49780 ?        S    10:54   1:22 /usr/bin/php5-cgi php
user1316 48367  5.4  0.1 242904 43752 ?        S    10:54   1:58 /usr/bin/php5-cgi php
user1316 48383  5.3  0.1 244968 43856 ?        S    10:54   1:57 /usr/bin/php5-cgi php
user1316 48388  5.7  0.1 243432 42452 ?        S    10:54   2:06 /usr/bin/php5-cgi php
user1316 48399  4.4  0.1 244968 43968 ?        S    10:54   1:37 /usr/bin/php5-cgi php
user1316 51261  5.6  0.1 243436 42456 ?        S    11:01   1:37 /usr/bin/php5-cgi php
user1316 51262  5.8  0.1 244712 43736 ?        S    11:01   1:41 /usr/bin/php5-cgi php
user1316 52196  8.6  0.1 234540 33568 ?        S    11:04   2:16 /usr/bin/php5-cgi php
user1316 58913  2.9  0.1 244928 43772 ?        S    11:22   0:14 /usr/bin/php5-cgi php
user1316 59862  5.3  0.1 246504 47040 ?        R    11:25   0:18 /usr/bin/php5-cgi php
user1316 59863  4.4  0.1 242908 43448 ?        S    11:25   0:15 /usr/bin/php5-cgi php
user1316 61984  1.6  0.1 248832 49344 ?        S    11:30   0:00 /usr/bin/php5-cgi php
user1316 62000  1.1  0.1 242684 43180 ?        S    11:30   0:00 /usr/bin/php5-cgi php
user1316 62001  4.3  0.1 247412 47692 ?        R    11:30   0:01 /usr/bin/php5-cgi php
user1316 62006  3.1  0.1 231848 32376 ?        S    11:30   0:01 /usr/bin/php5-cgi php
user1316 62323  9.2  0.1 248028 48408 ?        R    11:30   0:01 /usr/bin/php5-cgi php
user1316 62324  2.3  0.1 242688 43188 ?        S    11:30   0:00 /usr/bin/php5-cgi php

Обратите внимание, есть процессы S (sleeping), а есть процессы R (running).
Sleeping - это процесс, который уже обработал основной .php, выданный ему вэб-сервером и все его инклуды. Теперь он просто висит в памяти и спит, пока его не пнёт вэб-сервер с новым заданием.
Running - это процесс, который в данный момент действительно что-то делает для вэб-сервера, а как сделает, то уснёт (S), если вэб-сервер его не убьет.

Теперь попробуем подцепиться к спящему процессу (бегущие (R) процессы нам неинтересны - пока мы будем писать команду, они уже умрут). Возьмем самый последний в списке. Его PID - вторая колонка:

strace -p 62324
Process 62324 attached - interrupt to quit
accept(0,

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

Но если все же вопрос "так какие файлы то?" остался неотвеченным, то вот, что даст ответ:
strace -e open,access -p 62324
А вот так можно померять, на что сколько времени уходит у данного процесса. Эта команда ничего не покажет, ее нужно прервать на ^C через произвольный промежуток времени. Но при выходе стрейс выплюнет красивую табличку с отчетом:
strace -c -p 62324
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 66.04    0.010125           0     20990      1314 open
 11.51    0.001765           0     75052         6 read
  3.59    0.000551           0     19012           munmap
  3.36    0.000515           0     28905           fstat
  2.44    0.000374           0     19012           mmap
  2.37    0.000363           0     19848           close
  2.17    0.000332           0      4536           write
  2.16    0.000331           0     29262           lseek
  1.72    0.000264           0     14543      1385 lstat
  1.21    0.000185           0      3301           poll
...
    <вырезано еще около 20-ти системных вызовов
      но они занимают менее 1% времени каждый>
...


Что-то интересное на эту тему есть в статье Оптимизируем загрузку PHP-кода в 22 раза, или почему FastCGI не ускоряет PHP



03.01.2012

Аутентификация SSH через LDAP

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

Делается это следующим образом. Как многие знают, сегодня считается моветоном делать самостоятельные проверки паролей, групп и прочего. Давным давно уже изобрели единый центр проверок PAM. Даже утилита login, которая запускается, когда Вы коннектитесь к консоли, проверяет не сама, а отдает эту задачу "на аутсурс" PAM'у. Соответственно и OpenSSH сам не проверяет пароли.
Изначально у нас есть PAM-модуль для проверки через passwd (вообще их намного больше). Мы же поставим еще один PAM-модуль: для проверки через LDAP. А еще мы дополним NSS-переключатель новой опцией, чтобы он говорил всем, что можно проверять не только через passwd, но и через LDAP.

Сложность аутентификации SSH состоит в том, что запроcы будут идти к объектам PosixAccount, а в нормальном LDAP таким делать нечего. Кроме того, желательно также, чтобы в LDAP проверялись не пароли, а публичная часть ключа.

Итак сначала сделаем, чтобы проверялись хотя бы пароли, а уж потом и ключи допилим.
В моем случае используются:
OS: Debian Squeeze
LDAP: Oracle DSEE7

Начнем с того, что сохраним в безопасное место файл nsswitch.conf, который каждая вражеская программа пытается изкорёжить:
cp /etc/nsswitch.conf /etc/nsswitch.conf.orig
chattr +i /etc/nsswitch.conf.orig

Теперь научим наш PAM работать с LDAP-сервером. Для этого нам понадобятся модуль PAM, которому собственно предстоит работать с LDAP, и модуль NSS ( Name Service Switch), который к этому LDAP доступ для PAM'а обеспечит. Ну и консольные LDAP-утилиты для удобство дебага проблем:
apt-get install ldapscripts libnss-ldapd libpam-ldapd
Прошу обратить внимание на букву "d" в конце слов libnss-ldapd и libpam-ldapd. Раньше эти модули назывались без нее: libnss-ldap и libpam-ldap. Но потом их улучшили и переименовали. Если ошибетесь и поставите старые, то будете сами конфигурировать nscd и nslcd. И вообще там больше геморроя. А новые модули сами все делают.

В процессе установки будут запрошены некоторые параметры (ваши ответы врядли совпадут с моими, так как у меня специфический LDAP-сервер, я просто привожу пример):
LDAP server Uniform Resource Identifier:
ldaps://ldap.nodesquad.com:1686/
Distinguished name of the search base:
dc=nodesquad,dc=com
* (напротив всех сервисов поставить галочки )


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

vi /etc/pam.d/common-session


#Automatically create home direcory if not exist
session required          pam_mkhomedir.so skel=/etc/skel/ umask=0077


Для тех, кто хочет использовать аутентификацию по паролю, а их LDAP использует PosixAccount, на этом мануал будет закончен. Но у нас не все так сладко.

Для пользователей Oracle/SUN DSEE (Directory Server Enterprise Edition) придется каждому существующему пользователю добавить дополнительный класс и несколько его полей.
Как это сделать, написано тут.

Теперь можно пробовать приконнектиться по SSH со своим пользователем. Если не получилось, нужно смотреть логи запросов LDAP - как правило только они и спасают.

Если все ровно, то вот Вам новая проблема. Обратите внимание, что любая команда, подразумвающая обращение к LDAP (да хотябы ls, который показывает владельца файла) отвечает долго. Это из-за того, что она каждый раз обращается к LDAP. Во избежание этого нужно включить кэширование всех NSS-запросов: nscd. Но этому посвящено пол интернета, так что я обойду эту тему.

**********





Oracle/Sun DSEE 7 и его отношение к NIS-схеме. (posixAccount)

В Oracle/Sun DSEE по умолчанию нету атрибутов из NIS-схемы, а в частности класса объектов posixAccount, который бывает жизненно необходим, например для аутентификации SSH через LDAP). Но... он там есть! И спасибо большое статье Adding UNIX users to DS6. Я не смог найти как скачать DSE (похоже вражеский Oracle тупо убил этот проект после покупки Sun) или по другому заставить DSEE отображать все, что он умеет, а не только то, что популярно, но мы всегда можем добавить ручками для каждого существующего аккаунта объект posixAccount и его поля.
Подготовим LDIF:
tee > add.posixAccount.ldif

dn: uid=michael.abramovich,ou=people,dc=nodesquad,dc=com
changetype: modify
add: objectClass
objectClass: posixAccount
-
add: homeDirectory
homeDirectory: /home/michael.abramovich
-
add: uidNumber
uidNumber: 1007
-
add: gidNumber
gidNumber: 1007
-
add: loginshell
loginshell: /bin/bash

Ну а теперь вгружаем этот чендж:
ldapmodify -x -D 'cn=Directory Manager' -W -H ldap://:1389/ -f add.posixAccount.ldif

21.12.2011

Как по фэн-шую установить нужную версию Java на Debian/Ubuntu

Вариантов вообще много. От дебиановского пути до аналога RVM/PyEnv под Java.
Я покажу ручной.

Сначала скачиваем ее на сайте Oracle под свою платформу в tar.gz.

Затем распаковываем и получаем в результате директорию вроде jdk1.7.0_02 :
tar xzf jdk-7u2-linux-x64.tar.gz
Если у Вас старая версия Java, у которой расширение .bin, то надо сделать так:
chmod +x jdk-1_5_0_22-linux-amd64.bin
./jdk-1_5_0_22-linux-amd64.bin

Эту директорию мы переносим туда, где должны храниться все Java-машины:
mkdir /usr/lib/jvm
mv jdk1.7.0_02 /usr/lib/jvm/.

Так как в перспективе будут выходить новые версии Java, то мы создадим симлинк и будем работать только с ним, а в случае установки новой версии, просто положим ее рядом и перенаправим симлинк:
cd /usr/lib/jvm/
ln -s jdk1.7.0_02 java-7-sun

Маленькая ремарка для незнакомых: во всех операционных системах есть переменная $PATH, которая содержит набор путей, где должны лежать программы. То есть если Вы не пишете полный путь к программе (например /bin/ls), а просто пишете ls (понятно, что в текущей директории этого бинарника нету), то система возьме переменную $PATH и проверит в каждой из этих директорий. Как правило, если Вы напишете слово java, то искать его система будет в /usr/bin/java - и он там есть. Но обратите внимание, что это не бинарник, а всего лишь ссылка (симлинк) на него:

# ls -l /usr//bin/java
lrwxrwxrwx 1 root root 22 2011-12-21 13:23 /usr/bin/java -> /etc/alternatives/java

И обратите внимание, что ведет она опять же не туда, где у нас лежит Java-машина, а в alternatives - то есть в точку, где мы можем "диспетчерить" направление между версиями.

Далее смотрим какие у нас версии уже заданы:
update-alternatives --display java

И видим, что на сейчас у нас сконфигурирован всего лишь один путь: /usr/lib/jvm/java-6-sun/jre/bin/java (или вообще ничего нету, а может наоборот накопились версии).
Главное обратите внимание: последний столбик - приоритет. Чем он больше, чем выше.

Но нам нужно добавить свою альтернативу. И добавляем ее со своим приоритетом (обратите внимание, что путь идет до бинарника включительно, и причем идет через симлинк, а не через версию конкретной Java):
update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-7-sun/bin/java 99

Ну вот и все.
Если захотите откатить, то просто переконфигурируйте с выбором другого номера пути:
update-alternatives --config java

А вот команда для тех, кто еще хочет поставить плагин на FireFox (внимание на архитектуру, поставьте свою: amd64 или i386):
update-alternatives --install "/usr/lib/mozilla/plugins/libjavaplugin.so" "mozilla-javaplugin.so" "/usr/bin/java java /usr/lib/jvm/java-7-sun/lib/amd64/libnpjp2.so" 1

Проверяется переходом в FireFox на страничку about:plugins


06.12.2011

Как заставить Suexec игнорировать несоответствие UID/GID директорий, программ и запускающего

Вариант для Debian.
Придется пересобрать Suexec.

Нам понадобятся следующие пакеты:
apt-get install dpatch libaprutil1-dev libapr1-dev sharutils libcap-dev autoconf devscripts
Переходим в директорию, где обычно все собираем:
cd /usr/src
Скачиваем:
apt-get source apache2-suexec
Переходим в директорию, из которой надо работать:
cd apache2-2.2.16
Редактируем исходный код:
vi +569 support/suexec.c

И комментируем полностью весь блок:
    /* if ((uid != dir_info.st_uid) ||
        (gid != dir_info.st_gid) ||
        (uid != prg_info.st_uid) ||
        (gid != prg_info.st_gid)) {
        log_err("target uid/gid (%ld/%ld) mismatch "
                "with directory (%ld/%ld) or program (%ld/%ld)\n",
                uid, gid,
                dir_info.st_uid, dir_info.st_gid,
                prg_info.st_uid, prg_info.st_gid);
        exit(120);
    } */

Теперь собираем то, что получилось:
debuild -uc -us
По истечении этой команды директорией выше появятся много пакетов Apache. Нам нужен только один из этих двух:
ls -l ../apache2-suexec*


03.12.2011

Управление хардверным RAID-контроллером LSI MegaSAS

Начну с того, что очень не рекомендую пользоваться контроллерами этого производителя даже не смотря на то, что он показывает неплохие результаты бенчмарков на фоне конкурентов. Причина: полное отсутсвие документации на сайте. Даже опция -help выглядит как издевательство:
...
MegaCli -PdMarkMissing -physdrv[E0:S0,E1:S1,...] -aN|-a0,1,2|-aALL
MegaCli -PdGetMissing -aN|-a0,1,2|-aALL
MegaCli -PdReplaceMissing -physdrv[E0:S0] -arrayA, -rowB -aN
MegaCli -PdPrpRmv [-UnDo] -physdrv[E0:S0] -aN|-a0,1,2|-aALL
MegaCli -EncInfo -aN|-a0,1,2|-aALL
MegaCli -EncStatus -aN|-a0,1,2|-aALL
MegaCli -PhyInfo -phyM -aN|-a0,1,2|-aALL
MegaCli -PhySetLinkSpeed -phyM -speed -aN|-a0,1,2|-aALL
...

Так впечатление, что писать документацию отдали на аутсурс в ЦРУ :)
Так что будем пытаться допереть научным тыком - благо он не раз нас спасал.


Существуют следующие утилиты:
MegaCLI - (CLI - command line interface). Основная управляющая утилита для просмотра состояния и конфигурирования работы контроллера.
MegaRC -  устаревшая текстовая утилита для управления контроллером.
MegaMon - (Mon - monitoring). Демон + клиент для мониторинга.
MegaSM - (SM - storage manager). Какая-то неведомая GUI-ёвая херня на Java. Весит как ядро Linux и требует иксов, что на сервере неприемлемо (не знаю для кого писали, не уж то для десктопов с адаптерами по несколько сотен долларов...).

В официальных репозиториях основных дистрибутивов, видимо, утилиты не распространяются, но скачать их можно тут: LSI public downloads.

Но для Linux там есть только .rpm пакет и неподходящая по битности библиотека lybsysfs.
Пользователи Debian x64 могут воспользоваться собранным мной .deb-пакетиком для 64-битных ОС из всего этого.

Итак следующие команды помогут облегчить жизнь:

22.11.2011

Трассировка iptables

Включаем модуль в ядре:
modprobe ipt_LOG

Включаем правила, которые будут перебрасывать все на трейс (обратите внимание на новую цепочку raw вместо nat/filter). В моем случае я трассировал ping'и и потому включил для ICMP, но Вам надо отконфигурировать под свою задачу:
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE

И смотрим за трафиком:
tailf /var/log/kern.log


Когда попользуетесь, не забудьте удалить правила, а то раздел /var забьете (а многие и рутовый):
iptables -t raw -D OUTPUT -p icmp -j TRACE 
iptables -t raw -D PREROUTING -p icmp -j TRACE



Proxmox: гибридная сеть Bridge+NAT

Иногда нужно иметь часть виртуальных машин с внешним ("белым") IP и нормальным функционированием с Интернетом, а иногда виртуальным машинам нежелательно висеть наружу потрохами (как например LDAP-серверу). Если физическая хост-машина только одна, а виртуалки надо делать и так и так, то вот выход - создать еще одну сеть, только виртуальную, и к ней зацепиться бриджем.

Итак у нас есть интерфейс eth0 с сетью 222.111.123.231 (маска и шлюз тоже имеются) и ничего больше. Пусть внутренняя сеть имеет адресацию 192.168.0.0/24.

Сначала нам понадобится дополнительный интерфейс-пустышка, у которого будет собственный внутренний адрес, чтобы хост-машина могла общаться со своими виртуалками, а также работать им шлюзом:
lsmod | grep dummy

Если вывода не было, значит нужно подключить модуль, а если показалось что-то, то этот шаг пропустить.
Импорт модуля:
echo "dummy" >> /etc/modules
modprobe dummy

Теперь надо настроить два интерфейса (реальный eth0 и виртуальный dummy0) и два бриджа (в реальную сеть vmbr0 и в виртуальную vmbr1). Вот так изменится конфиг интерфейсов:
vi /etc/network/interfaces

# Loopback device:
auto lo
iface lo inet loopback

# Wide Area Network
auto vmbr0
iface vmbr0 inet static
  address  
222.111.123.231
  netmask   255.255.255.196
  gateway  
222.111.123.227
  bridge_ports eth0
  bridge_stp off
  bridge_fd 0

# Real phisical device: eth0
auto  eth0
iface eth0 inet manual

# default route to access subnet
up route add -net
222.111.123.226 netmask 255.255.255.196 gw 222.111.123.227 vmbr0

# Local Area Network
auto vmbr1
iface vmbr1 inet static
  address  192.168.0.1
  netmask  255.255.255.0
  bridge_ports dummy0
  bridge_stp off
  bridge_fd 0
  post-up echo 1 > /proc/sys/net/ipv4/ip_forward
  post-up    iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -o vmbr0 -j SNAT --to-source
222.111.123.231
  post-up    iptables -t nat -A POSTROUTING -o vmbr1 -j SNAT --to-source 192.168.0.1
  post-down  iptables -t nat -D POSTROUTING -s 192.168.0.0/16 -o vmbr0 -j SNAT --to-source 222.111.123.231
  post-down  iptables -t nat -D POSTROUTING -o vmbr1 -j SNAT --to-source 192.168.0.1


# Dummy device for LAN
auto  dummy0
iface dummy0 inet manual

20.11.2011

Как запретить обычным пользователям биндиться на все порты, включая непривилегированные

Нужно ковыряться в ядре.


Вот здесь объявляется символическое имя:
grep -B 1 PROT_SOCK include/net/sock.h

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024 

А здесь PROT_SOCK используется:
Infiniband: drivers/infiniband/core/cma.c
SCTP: net/sctp/socket.c
IPv6: net/ipv6/af_inet6.c
IPv4: net/ipv4/af_inet.c
SunRPC: net/sunrpc/svc_xprt.c

15.11.2011

Как обычному пользователю забиндиться на привилегированный порт (1-1023)

Как известно все ядра компилируют так, чтобы не-root не мог забиндится на порт 1-1023. Можно конечно пересобрать ядро и поменять эту настройку до компиляции, но поменять этот параметр на готовой работающей системе нельзя.
Есть еще вариант забиндить на непривилегированный порт, а привилегированный туда соединить либо через rinetd, либо через iptables такой командой:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

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


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


Единственные три варианта, это

либо использовать возможность setcap/getcap в новых ядрах:
apt-get install libcap2-bin
setcap 'cap_net_bind_service=+ep' /path/to/daemon

запуск:
/path/to/daemon

либо запускать через authbind:
apt-get install authbind
install -o my_user -m 500 /dev/null /etc/authbind/byport/443

запуск:
authbind /path/to/daemon

либо воспользоваться посредником supervisor:
apt-get install supervisor
и отконфигурировать его так.


***************
вообще команда install не особо популярна, но я ее написал, чтобы сократить количество команд. Если не понимаете, что она делает, то просто сделайте так:
touch /etc/authbind/byport/443
chown my_user /etc/authbind/byport/443
chmod 500 /etc/authbind/byport/443
***************

10.11.2011

Как заставить OpenLDAP работать на основе posixGroup и groupOfNames одновременно

Обычно все при установке применяют схему nis.schema, чтобы была совместимость с Samba и тем самым переводят работу LDAP с groupOfNames на posixGroup.
К сожалению это имеет обратный негативный момент:

"Its use is strongly discouraged because it is very inefficient, but mostly because posixGroup membership is a badly designed grouping philosophy"

Получается, что мы не сможем подключить к нашему LDAP множество хороших сервисов, как например Atlassian Jira. Нужно подключать groupOfNames.

Переходим в директорию со схемами:
cd /etc/ldap/slapd.d/cn=config

Открываем для редактирования схему, посвященную загрузке модулей:
vi cn=module{0}.ldif

В ней будет уже подгружен один модуль - бэкэнд hdb (или bdb):
dn: cn=module{0}
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_hdb
structuralObjectClass: olcModuleList
entryUUID: 0a04d41e-3161-1030-9fef-abf604861a01
creatorsName: cn=admin,cn=config
createTimestamp: 20110622211920Z
entryCSN: 20110622211920.678877Z#000000#000#000000
modifiersName: cn=admin,cn=config
modifyTimestamp: 20110622211920Z

07.11.2011

SSH JailKit

Устанавливаем необходимые для сборки пакеты:
apt-get install debhelper devscripts

И желательные для конфигурации:
apt-get install libcap-dev

Переходим в директорию, где будем собирать пакет:
cd /usr/src

Скачиваем его:
wget http://olivier.sessink.nl/jailkit/jailkit-2.14.tar.gz

Распаковываем:
tar xzf jailkit-2.14.tar.gz

Переходим в директорию с пакетом и с удивлением находим, что самый обычный тарбол с сорцами уже готов к сборке на Debian (об этом говорит директория debian с внутренними файлами):
cd jailkit-2.14

В пакете есть неболшой косячок с LSB-тэгами, поэтому можно их до сборки руками поправить:
vi extra/jailkit
#!/bin/sh
#
### BEGIN INIT INFO
# Provides:          jailkit
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      $network $time
# Should-Stop:       $network $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start and stop the jailkit syslog daemon
### END INIT INFO
#
Осталось только запустить сборку. Во время прохождения инструкций, сборщик споткнется об отсутствие файла *orig*, но не беда. Жмем на Y и идем дальше:
debuild -uc -us
Устанавливаем свежесобранный пакет:
 dpkg -i ../jailkit_2.14-1_i386.deb
Конфигурирование находится под катом.



25.10.2011

Просмотр трафика MySQL

Сначала соберем пакет.

Установим pcap-библиотеку:
apt-get install libpcap-dev

Создаем и переходим в директорию:
mkdir /usr/src/mysqlsniffer
cd /usr/src/mysqlsniffer

Скачиваем:
wget hackmysql.com/code/mysqlsniffer.tgz

Разархивируем:
tar xzf mysqlsniffer.tgz

Компилируем:
gcc -O2 -lpcap -o mysqlsniffer mysqlsniffer.c packet_handlers.c misc.c

Кидаем утилиту туда, куда полагается по фэн-шую FHS:
mv mysqlsniffer /usr/bin/


Ну и пользуемся благами общества:
mysqlsniffer --verbose --no-mysql-hdrs eth0 | grep COM_QUERY

23.10.2011

Использование WevDAV как замена FTP/FTPS/SFTP/SMB/CIFS

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

Сначала включаем необходимые модули в Apache:

a2enmod dav dav_fs


Далее включаем в виртхосте использование этого модуля директивой DAV On (опять же я опущу все некасающиеся данной темы настройки как например логи, хэндлры и аутентификация):
<VirtualHost *:443>
ServerName upload.nodesquad.com
DocumentRoot /var/www/upload

<Location />
DAV On
<
/Location>

</VirtualHost>
И перегружаем его, чтобы применились настройки:
invoke-rc.d apache2 restart

Теперь можно использовать.
Windows-GUI-клиенты:
плагин WebDAV для Total Commander
JScape AnyClient
WebDrive
BitKinex

Debian-CLI-клиенты:
cadaver и nd - просто консольные клиенты
davfs2 - монтировка ресурсов на постоянной основе как полноценная файловая система
fusedav - тоже самое, что davfs2, только с использованием FUSE

ВНИМАНИЕ: возможность подключить и зааплоадить файлы есть у любого человека, включая злоумышленника. Поэтому в секцию Location очень желательно добавить авторизацию:
<Location />
DAV On

AuthName "My DAV service"
AuthType Basic
AuthUserFile /etc/some_site/htpasswd.users
AuthUserFile /etc/some_site/htpasswd.users
Require valid-user

<
/Location>