четверг, 30 октября 2008 г.

Явное указание архитектуры процессора при сборке RPM

Если мы компилим rpm пакеты из SRPM, то почему бы не убить двух зайцев сразу - и не оптимизировать пакеты под свой процессор (если, конечно, машина не крутится на стареньком i586). Описываемый ниже спсоб не страдает элегантностью, но он, по крайней мере, работал на Mandriva 2008.1
Наша задача разбивается на два этапа (в приведенных далее командах предполагается что пакет собирается для архитектуры pentium4 - доступные значения архитектуры можно смотреть в man gcc (1) (значения опций -march и -mtune) или в файле /usr/lib/rpm/rpmrc - там нам интересны значения arch_canon):
  1. для компиляции пакета для нужной целевой платформы в строку вызова rpmbuild добавляем опцию --target=pentium4
  2. пакет-то мы на прошлом шаге собрали, только rpm -i не сможет его установить. Побеждется это записью строки pentium4-intel-linux (или как там правильно для Вашей архитектуры) в файл /etc/rpm/platform

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

Заставляем работать software модем на ноутбуке с Linux


Есть ноутбук (если точнее, Fujitsu-Siemens Esprimo U9200) и Linux (если точнее, Mandriva 2009.0), у ноутбука есть встроенный модем (по сообщениям винды Motorola SM56), который автоматически при установке мандривы не обнаруживается. Прикручиваем руками.
Т.к. модем у нас софтверный, то понятно, что для его работы нужна некая софтина. Называтся эта софтина slmodemd. В случае мандривы устанавливатеся так:
# urpmi slmodem
Если в вашем дистрибутиве такого пакета нет, то можно поискать тут.
В простом случае для ее работы достаточно поправить код страны в файле /etc/sysconfig/slmodemd:
SLMODEMD_COUNTRY=RUSSIA
на случай, если вы заблудились вдали от родины, то список допустимых стран покажет команда:
$ slmodemd --countrylist
и запустить демон командой:
# /etc/init.d/slmodemd start
Критерий успеха - появление в каталоге /dev файла ttySL0 (это и будет порт модема для программы дозвона).
Но у меня так просто не заработало. У меня понадобилось включить у модема режим ALSA. Пишем в /etc/sysconfig/slmodemd:
SLMODEMD_MODULE=snd-intel8x0m
а потом (как это не удивительно) надо править скрипт /etc/init.d/slmodemd Причина в том, что в режиме ALSA устройством модема является не умолчательное /dev/slamr0, а устройство, полученное от системы asound. Там другое пространство имен. Нужное имя (из двух цифр) ищем командой:
$ cat /proc/asound/pcm | grep -i modem
Видим что-то типа:
00-06: Si3054 Modem : Si3054 Modem : capture 1
заменяем черточки в номере (первое поле) запятыми - и получаем устройство hw:0,6
Так и пишем в /etc/init.d/slmodem:
SLMODEMD_FULLDEVICE=hw:0,6
(это строчка в ветке if [ "$SLMODEMD_MODULE" = snd_intel8x0m ] - как раз наш случай).
На всякий случай, если slmodemd предполагается запускать не через скрипт /etc/init.d , а из какого-то своего скрипта, то все много короче. Строка вызова такая:
# slmodemd -c RUSSIA -a hw:0,6
(кажется, работоспособен и более простой синтаксис -a modem:0)
Модем часто теряет несущую сразу после соединения. Если для дозвона используется wvdial, то одолеть проблему можно, добавив в /etc/wvdial.conf строку:
Carrier Check = no
(при использовании гольного pppd проблема не наблюдается).
P.S. после этого модем завелся, но связаться с провайдером пока удается только на протоколах V.22bis и ниже. Если кому-то интересны такие скорости, то команда выбора протокола в этом случае такая: at+ms=122
Полный список доступных протоколов можно получить командой at+ms=? (протоколы выводятся в виде цифровых кодов, для их перевода в более принятую V.XX-нотацию, можно заглянуть в файл modem/modem_defs.h в исходниках slmodem - в нем искать описание enum DP_ID. Неплохую справку по АТ-командам, поддерживаемым slmodem, можно найти, почитав файл modem/modem_at.c - надо сказать, что перечень их довольно сильно отличается от официальной документации производителя модема - ежели вам все-таки не хватает списка от Motorola, читайте его тут).

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

Настройка vpn-туннеля по протоколу L2TP в Linux



Дано: Mandriva 2008.1, маршрутизатор Cisco 7200 серии, терминирующий туннели и поддерживающий протокол L2TP, нужно поднять туннель по этому протоколу без поддержки IPSec.
Пусть: адрес Cisco 172.16.0.1, мой шлюз по умолчанию (до поднятия туннеля) 10.0.0.1, имя пользователя vpn_user, пароль vpn_secret (в дальнейшем эти значения в командах и конфигах заменять на реальные).
Перед тем как начнем - два важных пункта подготовки.
Первое.
Маршрут до терминатора vpn должен существовать как до, так и после поднятия туннеля (когда у нас изменится маршрут по умолчанию), потому необходимо прописать его явно:
# route add -host 172.16.0.1 gw 10.0.0.1
Так как в будущем это должно работать при загрузке, то надо либо добавить эту строку в файл /etc/rc.local (грубый вариант, который будет работать в любом Linux), либо (для Mandriva и RedHat-like) добавить строку
172.16.0.1/32 via 10.0.0.1
в файл /etc/sysconfig/network-scripts/route-eth0 (если у вас несколько сетевух, то возможно будет не eth0)
Еще один вариант (точно работает в Mandriva и рекомендуется Mandriva Wiki) - файл называется /etc/sysconfig/network-scripts/eth0.route (UPD: имя route-eth0 тоже работает) и синтакис у него такой:
ADDRESS0=172.16.0.1
NETMASK0=255.255.255.255
GATEWAY0=10.0.0.1
(если маршрут - не первый в фале, то вместо 0 будет 1, 2 и т. д.)
Для других популярных Linux действуем примерно так (прочитано в сети, не тестировалось):
В debian-like (*buntu, etc):
в файле /etc/network/interfaces
в раздел
iface eth0 inet static
добавить строку
<символ табуляции>post-up route add -host 172.16.0.1 gw 10.0.0.1
В OpenSUSE файл называется /etc/sysconfig/network/ifroute-eth0
и синтаксис строк в нем такой:
172.16.0.1 10.0.0.1 32
И второе. Для того, чтобы туннель мог быть успешно установлен, необходимо разрешить прохождение пакетов протокола UDP между портами 1701 терминатора vpn и нашего компьютера в обоих направлениях. Т.е. если конфигурацией файрвола на прохождение пакетов UDP наложены какие-то ограничения (а они у разумного администратора должны быть наложены), то должны быть добавлены примерно такие два правила:
# iptables -A INPUT -p udp -s 172.16.0.1 --sport 1701 --dport 1701 -j ACCEPT
# iptables -A OUTPUT -p udp -d 172.16.0.1 --sport 1701 --dport 1701 -j ACCEPT
Теперь начинаем собственно строить VPN. Входящий в репозиторий Mandriva пакет l2tpd у меня не завелся, потому ставил его форк xl2tpd (брать тут - есть tar.gz и srpm - кому что больше нравится). Версия у меня была 1.2.0-1. Собираем, ставим, пишем конфиг демона (файл /etc/xl2pd/xl2tpd.conf):
[lac c7200]
name = vpn_user
require chap = yes

require pap = no
lns = 172.16.0.1
redial = yes
require authentication = no
ppp debug = no
pppoptfile = /etc/ppp/options.xl2tpd
autodial = yes
hidden bit = no
flow bit = yes
length bit = yes

Опции pppd как видно из прошлого файла, пишем в /etc/ppp/options.xl2tpd:
unit 0
name vpn_user
ipparam l2tp_vpn
connect /bin/true
mru 1460
mtu 1460
noauth
persist
maxfail 0
nopcomp
noaccomp

имя и пароль добавляем в /etc/ppp/chap-secrets:
vpn_user * vpn_secret

И - для поднятия маршрутизации (т.к. pppd не умеет при запуске перзаписать существующий маршрут по умолчанию) пишем такой скрипт /etc/ppp/ip-up.local:
#!/bin/sh

# переменная $6 - это ipparam,
# заданный нами в /etc/ppp/options.xl2tpd
if [ "$6" = "l2tp_vpn" ]
then
route delete default
route add default ppp0
fi

а для обратного отката - скрипт /etc/ppp/ip-down.local:
#!/bin/sh
route delete default
route add default 10.0.0.1

(не забыть, что эти два файла должны быть исполняемыми)
Если при выключенном vpn шлюз по умолчанию Вам не нужен (все равно никуда не пущают ;), то можно вместо таких жестоких путей просто добавить строку:
defaultroute
в файл /etc/ppp/options.xl2tpd
Запускаться наш vpn будет командой:
# /etc/init.d/xl2tpd start
Осталось заметить в скобках, что в ту же мандриву входит модуль ядра pppol2tp. Так вот его в данной конфигурации загружать не надо. xl2tpd вроде должен уметь с ним работать, но у меня не заработал. Возможно, что-то не то с версиями ядра и демона.

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

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

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


#!/usr/bin/perl -w

# netmask <-> prefixlen convert
# usage: $0 mask|len

use strict;

if ($#ARGV != 0 || $ARGV[0] =~ /[^\d.]/) {
print STDERR "Usage: $0 mask|len\n";
exit 1;
}
if ($ARGV[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
# на входе - сетевая маска

# максимально возможная длина префикса
my $r = 32;
# переводим адрес в число
my $n = ($1 << 24) + ($2 << 16) + ($3 << 8) + $4;
# пока не появится 1 в младшем бите,
# сдвигаем адрес вправо - и уменьшаем длину на 1

until ($n & 1) {
$n >>= 1;
$r--;
}
print $r, "\n";
} else {
# на входе - длина префикса

# переводим ее в числовой адрес маски
my $r = (0xffffffff << (32 - $ARGV[0]))
& 0xffffffff;
# и форматируем в dot-нотацию
for (my $i = 24; $i >= 0; $i -= 8) {
print (($r & (0xff << $i)) >> $i);
if ($i) {
print '.';
}
}
print "\n";
}

Запуск ntpd под FreeBSD


Как это ни странно, но в стандартной поставке FreeBSD болванки для файла конфигурации ntpd (8) нет ни в /etc, ни в /usr/share/examples. Поэтому восполняю это досадное упущение. Взято из FreeBSD Handbook и http://support.ntp.org/bin/view/Servers/StratumOneTimeServers (список публичных ntp-серверов 1 страты). Называется файл конфигурации /etc/ntp.conf, минимально необходимое содержимое его такое:
# это сервера, откуда берем время
# если используется restrict, лучше брать те сервера, у которых
# 1 адрес, а не пул - а то придетс яписать доступ всем
server clock.nc.fukuoka-u.ac.jp prefer
server ntp1.mmo.netnod.se
server ntp.nic.cz
# а это ACL
restrict default ignore
restrict 127.0.0.1
# это те, от кого мы берем дату
restrict ntp.nic.cz noquery notrap
restrict ntp1.mmo.netnod.se noquery notrap
restrict clock.nc.fukuoka-u.ac.jp noquery notrap
# а это - наши клиенты
restrict x.x.x.x mask y.y.y.y nomodify notrap
restrict z.z.z.z mask w.w.w.w nomodify notrap

не забыть конечно добавить в /etc/rc.conf такое:
ntpd_enable="YES"
работает ntpd на порте 123 по протоколу UDP - так что эти порт должен быть открыт в firewall
Тестирование с UNIX-like клиента такой командой:
$ ntpdate -d your_server_addr
По ее выводу легко понять, какая дата получена с сервера (и получена ли вообще). Опция -d означает не устанавливать дату фактически, зато показать отладочную информацию (что нам и нужно).
Много полезного можно узнать, запуская на сервере команду ntpq (8) - напр. про соседей нам расскажут субкоманды peer и ass (sic!)

P.S. Во FreeBSD 7.1-PRERELEASE столкнулся со странным поведением стартового скрипта /etc/rc.d/ntpd - он зачем-то запускат два процесса ntpd (с клиента все выглядит нормально, но на сервере второй процесс переодически грязно ругается в логи). На всякий случай, если у кого-нибудь вдруг произойдет тоже самое (в чем лично я сильно сомневаюсь), сообщаю, что методом тыка удалось найти на эту беду управу. Помогает строчка
ntpdate_enable="YES"
в файле /etc/rc.conf Почему помогает - не знаю сам - придумалось оно путем сложных ассоциаций на тему строки REQUIRE в скрипте /etc/rc.d/ntpd