среда, 21 июля 2010 г.
Вставка нулевых значений в auto_increment поля в MySQL
среда, 14 апреля 2010 г.
Странное поведение mktime относительно летнего времени
На опыте столкнулся с тем, что результат, возвращаемый функцией mktime(3) не учитывает перехода на зимнее/летнее время (т.е. результаты для "лета" оказываются на час больше, чем нужно). Проверено на linux 2.6.18 и FreeBSD 8.0 с корректно установленной зоной MSK/MSD - так что, вероятно, именно такое странное поведение соответствует спецификации POSIX. Самое смешное в том, что (в полном соответствии с документацией) функция mktime не только возвращает типа значение time_t, но и "нормализует" содержимое переданной в нее по указателю struct timespec, заполняя совершенно корректными (учитывающеми перевод времени) значениями поля tm_isdst, tm_gmtoff и tm_zone. Очевидно, где-то в этом направлении и лежит путь борьбы с этой функцией. Т.е вместо очевидного:
struct timespec ts;
time_t tm = mktime(&ts);
Пишем теперь так:
struct timespec ts;
time_t tm = mktime(&ts) - ts.tm_isdst * 3600;
Эстетам же и забывчивым можно предложить определить вот такой макрос:
#define mktime(t) (mktime(t) - (t)->tm_isdst * 3600)
и использовать mktime, как обычно.
Еще идеи?
пятница, 12 марта 2010 г.
Проброс сессии ssh из внешнего мира в немаршрутизируемую сеть (ssh tunnel)
На эту тему в инете написано немало статеек, но наличие некоторых мелких и легкозабываемых подробностей вынуждает пошагово задокументировать процесс.
В задаче участвуют три хоста: машина, за клавиатурой которой мы находимся (имя: my-cons, адрес: 11.0.0.11), машина, к которой хотим получить доступ (имя: in-serv, адрес: 10.0.0.10) и машина-шлюз, с которой доступны обе эти машины (имя: gat-serv, адрес: 12.0.0.12). В дальнейшем хост, на котором будет вводиться команда, обозначается приглашением командной строки.
Пусть на всех трех хостах имеется учетная запись bigadm, под которой мы и будем работать. Также предполагается, что на in-serv и gat-serv запущен sshd
Т.к. наиболее рациональным способом авторизации в ssh является использование публичных ключей, что напишем, какие ключи, где надо прописать.
- ключ my-cons:~bigadm/.ssh/id_rsa.pub должен быть добавлен в in-serv:~bigadm/.ssh/authorized_keys
- ключ gat-serv:~bigadm/.ssh/id_rsa.pub должен быть добавлен в gat-serv:~bigadm/.ssh/authorized_keys
- т.к. скорее всего процесс настраивается с помощью того же ssh, то ключ my-cons:~bigadm/.ssh/id_rsa.pub не помешает в gat-serv:~bigadm/.ssh/authorized_keys (строго говоря, для решения самой задачи это НЕ необходимо - если у нас напр. при настройке был доступ к консоли этого сервера - или мы производили настройку с какого-то другого хоста).
Все достаточно просто:
bigadm@gat-serv$ ssh -f -N -g -L 2222:10.0.0.10:22 bigadm@12.0.0.12
(следует обратить внимание на ключ -g - без него 2222 порт открывается на адресе 127.0.0.1 - т.е. туннелем можно воспользоваться только локально - а это вовсе не то, что нам сейчас требуется (хотя применимо напр. для проброса по шифрованному каналу нешифрованного трафика - POP3, etc).
bigadm@my-cons$ ssh -p2222 12.0.0.12
и мы должны оказаться в консоли in-serv.
вторник, 2 февраля 2010 г.
nsswitch.conf для FreeBSD, пересобранной без NIS
Дальнейшие опыты проверены на FreeBSD 8.0
NIS в наше время используется достаточно редко, так что при пересоборке мира существует соблазн добавить в /etc/src.conf строку WITHOUT_NIS=YES (для более ранних версий править надо файл /etc/make.conf). После пересборки с этой опцией все вроде работает, но порой замечаются легкие странности - например, демон cron не отправляет стандартный вывод выполенных комманд по почте, а в /var/log/cron пишет:
NSSWITCH(_nsdispatch): nis, passwd_compat, endpwent, not found, and no fallback provided
Очевидно, проблему надо искать в /etc/nsswitch.conf
Там по умолчанию стоит:
passwd: compat
man-страница nsswitch.conf(5) сообщает, что compat означает подержку в файлах /etc/passwd и /etc/group строк + и - , что на самом деле имеет какой-то смысл только при использовании NIS (кто с ней знаком, помнит, зачем это надо - прочим нормальным людям едва ли необходимо об этом знать). Очевидно, система, собранная без поддержки NIS, просто перестает понимать какой-такой это compat - и пасует. Решение представляется очевидным. Меняем строку на банальное:
passwd: files
...и ожидаем новых сюрпризов. Мораль - хочешь спать спокойно, нечего править /etc/src.conf ;)
понедельник, 19 октября 2009 г.
Postfix + Procmail для виртуальных ящиков

В дальнейшем предполагается, что виртуальные почтовые ящики расположены в директориях вида: /var/virtmail/domainname/username и принадлежат пользователю virtmail
В файле master.cf описываем транспорт procmail (все - в одну строку):
procmail unix - n n - - pipe flags=RO user=virtmail argv=/usr/bin/procmail -t -o SENDER=${sender} -m USER=${user} DOMAIN=${domain} /etc/procmailrc
включаем этот транспорт для виртуальных пользователей в main.cf:
virtual_transport = procmail
procmail_destination_recipient_limit = 1
Последняя опция означает, что письмо, адресованное нескольким получателям, будет "превращаться" во много писем - каждое с одним получателем. Иначе procmail не вполне правильно разбирается с такими множественными письмами.
Теперь самое интересное - что писать в /etc/procmailrc:
SHELL=/bin/sh
PATH=/bin:/usr/bin
MAILDR=/var/virtmail/${DOMAIN}/${USER}/
# на всякий случай создадим эту папку
DUMMY=`test -d $MAILDR | mkdir -m 700 $MAILDR`
# тут какие-то правила, ради которых и прикручивается procmail
# ...
# и последнее правило - куда класть почту по умолчанию:
:0:
${MAILDR}
По ходу экспериментов было замечено, что хранение имени почтовой директории в "стандартной" переменной MAILDIR приводило к необъяснимому поведению при вызове внешней команды - потому было выбрано "усеченное" имя.
вторник, 23 июня 2009 г.
Странная работа резольвера в Xubuntu 9.04

В Xubuntu 9.04 (не из коробки, а после рядя миграций из одной сети в другую) был обнаружена странная работа резольвера: команда
$ host some.host.somedomain.net
находит ip-адрес, а ping (или напр. firefox) при попытке обратиться к этому хосту, говорят, что хост не найден.
Методом тыка было предположено, что проблема - в файле /etc/nsswitch.conf (т.к. утилиты работы с DNS, такие как host, должны его игнорировать, а "нормальные" сетевые команды - наоборот - использовать).
Строка hosts в этом файле из коробки выглядит нечеловечески страшно:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
Что-то не нравился мне этот mdns4_minimal - да еще и return после него - потому меняем на более понятное:
hosts: files dns
после перезагрузки проблема больше не наблюдалась.
понедельник, 4 мая 2009 г.
ПППингвины over Ethernet

Настраиваем PPPoE на Linux
Сервер
Для опытов использовалась OpenSUSE 11.1
Необходимо поставить следующие RPM: ppp, rp-ppoe и freeradius-client. Про то, как настраивать авторизацию на сервере RADIUS уже написано тут.
Проверить, как работает авторизация можно командой
# radexample
(да, именно с правами root - иначе она не сможет прочесть файл конфигурации, но в этом не признается - и выдаст Authentication FAILURE)
Проверив, что все работает, нужно в файле /etc/radiusclient/radiusclient.conf нужно убрать следующие строки (pppd на них сильно ругается):
radius_deadtime 0
bindaddr *
Если мы уберем эти строки заранее, ничего страшного не случится, но от radexample толку не ждите - она выпадет в кору.
Файл параметров сервера /etc/ppp/pppoe-server-options предельно прост:
+chap
-pap
auth
proxyarp
plugin radius.so
Запускается сервер командной строкой:
# pppoe-server -I eth1 -L 10.11.12.13
(стартовый скрипт для него придется сочинять самим)
- Первый параметр - интерфейс, на котором ждем подключения клиентов. Он должен быть поднят - иначе pppoe-server не поднимется IP адрес этому интерфейсу может быть как присвоен, так и не присвоен.
- Второй параметр - адрес, который будет отдаваться клиентам как адрес конца тоннеля (насколько мне удалось выяснить, он может быть как равен адресу нашего интерфейса - если таковой присвоен - так и не равен ему - на работу это не влияет).
Для того, чтобы сервер был реально полоезен, нужно разрешить на нем роутинг. В файле /etc/sysctl.conf пишем:
net.ipv4.ip_forward=1
Аналогичная конфигурация работоспособна на CentOS 5.3 и Ubuntu 9.04 (там пакет, содержащий pppoe-server, называется pppoe). Нужно заметить, что эти системы не нуждаются в прятание строк в файле /etc/radiusclient/radiusclient.conf (для CentOS ищется на http://rpmfind.net пакет radiusclient для fc или el, а в убунте есть аналогичный пакет radiusclient1).
Клиент
Опыты проводились на Ubuntu 9.04
Ничего доставлять не надо - все нужное в дистрибутиве уже есть.
Файл /etc/ppp/peers/pppoe:
user "myname"
defaultroute
replacedefaultroute
noauth
noipdefault
plugin rp-pppoe.so eth0
Последний параметр в последней строке - интерфейс, через который будем выходить на сервер. Он должен быть поднят, ip-адрес на нем может как быть, так и не быть.
Файл /etc/ppp/chap-secrets:
"myname" * "mysecret" *
myname и mysecret - это (как вы догадались) наши имя и пароль на RADIUS-сервере.
Соединение запускам командой:
# pppd call pppoe
Если возникли проблемы, добавляем в конфиг сервера и клиента строчку debug - и получаем довольно неплохой уровень отладочных сообщений.
Аналогичная конфигурация работает на Mandriva 2009.1
P.S. в Mandriva 2009.1 pppoe-server не вполне работоспособен - по крайней мере, мне вообще не удалось заставить его отвечать на LCP Request. Судя по всему, проблема заключается в pppd. Лечится сборкой из исходников ppp-2.4.4.XXXX.rpm для FedoraCore (pppoe плагин в него входит), а файлы в /etc/radiusclient копируются из ${RPMROOT}/BUILD/ppp-X.X.X/pppd/plugins/radius/etc (нюансы этой операции описаны в предыдущем посте).