OpenVZ Debian 7 Wheezy Template

Недавно вышел Debian 7 Wheezy. Среди прочего произошел переход на ядро 3.2 и из-за этого произошел отказ от поддержки OpenVZ. Печально, но Wheezy прекрасно работает на ядре 2.6.32 от Squeeze, а еще лучше работает Proxmox 3. Разумеется под него хочется иметь свою сборку Debian7. Сделать это можно так.

Во-первых, vzctl в Proxmox не содержит в себе конфиги для шаблонов, которые упрощают жизнь. Те, что обычно лежат в /etc/vz/conf и именуются типа ve-basic.conf-sample ve-light.conf-sample ve-unlimited.conf-sample и т.п. Поэтому качаем их из основного дистрибутива:

cd /tmp
wget http://mirror.yandex.ru/debian/pool/main/v/vzctl/vzctl_3.0.30.2-4_amd64.deb
dpkg -x vzctl_3.0.30.2-4_amd64.deb .
cp etc/vz/conf/*sample /etc/vz/conf/

Теперь приступим к сборке почти по стандартной процедуре.
Она содержит три этапа. Первый и третий на хосте, а второй — внутри контейнера.

Первый этап:

Создадим файловую структуру контейнера:

aptitude install debootstrap
debootstrap --arch amd64 wheezy /var/lib/vz/private/777 http://mirror.yandex.ru/debian/

Произведём базовые настройки контейнера:

vzctl set 777 --applyconfig basic --save
echo 'OSTEMPLATE="debian-7.0"' >> /etc/vz/conf/777.conf
vzctl set 777 --ipadd 192.168.35.110 --save
vzctl set 777 --nameserver 8.8.8.8 --nameserver 8.8.4.4 --save
mknod --mode 666 /var/lib/vz/private/777/dev/ptmx c 5 2
mkdir -p /var/lib/vz/root/777

Контейнер подготовлен. Запустим его и залезем внутрь:

vzctl start 777
vzctl enter 777

Теперь мы внутри контейнера.

Второй этап:

Будем патриотически использовать локальное зеркало Debian:

echo "deb http://mirror.yandex.ru/debian wheezy main non-free contrib" > /etc/apt/sources.list
echo "deb http://mirror.yandex.ru/debian/ wheezy-updates main contrib non-free" >> /etc/apt/sources.list
echo "deb http://security.debian.org wheezy/updates main non-free contrib" >> /etc/apt/sources.list

aptitude update
aptitude upgrade

chmod 700 /root

sed -i -e '/getty/d' /etc/inittab
sed -i -e '/^#/d' /etc/inittab
sed -i -e '/^\s*$/d' /etc/inittab
echo "1:2345:respawn:/sbin/getty 38400 tty1" >> /etc/inittab

sed -i -e 's@\([[:space:]]\)\(/var/log/\)@\1-\2@' /etc/*syslog.conf

rm -f /etc/mtab
ln -s /proc/mounts /etc/mtab

rm -f /etc/ssh/ssh_host_*

echo '
#!/bin/sh
### BEGIN INIT INFO
# Provides:          Generates new ssh host keys on first boot
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Generates new ssh host keys on first boot
# Description:       Generates new ssh host keys on first boot
### END INIT INFO
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ""
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -N ""
insserv -r /etc/init.d/ssh_gen_host_keys
rm -f \$0
' > /etc/init.d/ssh_gen_host_keys

chmod a+x /etc/init.d/ssh_gen_host_keys
insserv /etc/init.d/ssh_gen_host_keys

dpkg-reconfigure tzdata


Удалим лишние пакеты, если знаем какие. 😉 Например:

dpkg --purge modutils ppp pppoeconf pppoe pppconfig module-init-tools

Далее доставляем всё что нужно в этом шаблоне. Например:

aptitude install ssh quota less mc mtr

Очищаем кэш и вылезаем из контейнера.

aptitude --purge clean
exit

Третий этап:

Теперь контейнер надо собрать в шаблон (template):

vzctl set 777 --ipdel all --save
>/var/lib/vz/private/777/etc/resolv.conf
rm -f /var/lib/vz/private/777/etc/hostname
vzctl stop 777
cd /var/lib/vz/private/777
tar --numeric-owner -zcf /var/lib/vz/template/cache/debian-7.0-amd64-custom.tar.gz .

Вот и всё. Теперь у нас есть template для установки Debian 7 Wheezy в контейнер OpenVZ, например, в Proxmox.

Проверим — работает ли:

# vzctl create 888 --ostemplate debian-7.0-amd64-custom --config basic
Creating container private area (debian-7.0-amd64-custom)
Performing postcreate actions
CT configuration saved to /etc/pve/openvz/888.conf
Container private area was created

Теперь можно наши эксперименты удалить (или оставить — по желанию):

# vzctl destroy 777
# vzctl destroy 888

Как иногда собираются серваки

Пару недель назад были закуплены внутренности для нового терминального сервера. На прошлой неделе под него привезли подходящий блок питания. И вот пока все вокруг празднуют первомай и не путаются под ногами решил я всё это собрать. Сборкой серваков я никогда не занимался и единственный 2U сервер собрал лет 10 назад, а то и больше. Конечно, ожидал трудностей, но не таких…

Дано:

Нужно:

  • Собрать сервак.

Распаковал материнку, процы, память. Поставил. Распаковал один кулер. Поставил. Распаковал второй кулер… WTF?!
Проблема номер раз. Второй кулер просто не помещается. А мешает ему первый. Причём сильно — никак не менее полсантиметра.


2cpu_fuckup012cpu_fuckup02

Первой же мыслью было отпилить кусок радиатора. Но ножовки или напильника под рукой не оказалось.
Немного подумав и посмотрев картинки в гугле было решено купить пару оригинальных Intel’овских кулеров. Они-то уж точно должны подойти. Под это дело был послан гонец в магазин.

Тем временем сервак был собран с одним процом и, соответственно, радиатором. Настало времени поставить память. По рекомендации производителя память для одного процессора нужно вставлять в слоты A и B. И тут снова WTF?!
Проблема номер два. Память во B слот не ставится — мешает кулер…


2cpu_fuckup112cpu_fuckup12

Как хорошо, что была куплена материнка Supermicro… Память прекрасно встала в слоты C и D. После некоторых танцев вокруг сервака он запустился и показал наличие одного процессора и двух планок памяти в сумме на 32GB. Если бы это был Gigabyte, то врядли бы всё это заработало. Установленная Fedora 16 загрузилась пости без проблем, если не считать двух потерянных сетевых интерфейсов, которые, впрочем, были ей предъявлены при помощи udev совершенно без проблем.

Теперь хотя бы стало ясно, что за потраченные 50+ килорублей на меня не будут косо смотреть. 😉

К этому времени вернулся гонец. После бодрой установки первого радиатора… WTF?! Имеем копию первого факапа. Теперь есть 4 кулера, которые не ставятся парой, а в результате я стал «счастливым» обладателем двух Intel’овских «пропеллеров» за 1800 руб.

Но соображалку не пропьёшь! Поскольку радиатор пластинчатый, то лопасти первого радиатора можно пропустить между лопостями второго. Разбираем кулеры. Ставим голые радиаторы на процы. Первый раз что-то срастается. 🙂


2cpu_puremetal02cpu_puremetal1

Разумеется, пропеллеры не встают при таком раскладе на радиаторы. После изучения и разбора пропеллеров от крепёжного элемента был отрезан «лишний» кусок.


2cpu_cooler02cpu_cooler12cpu_cooler2

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

Зато в результате мы получили почти то что было нужно. 😉

2cpu_profit

Теперь терминальный сервере имеет 24 виртуальных ядра и 32 гига оперативки. Юзеры будут довольны. >:E

P.S. качество фоток соответствует качеству китайской пяти мегапиксельной камере…

Небольшое хранилище для небольших файлов

В процессе разработки одного проекта появилось требование хранить множество файлов (более 4 млн. штук). И в процессе количество файлов постоянно росло. Когда из количество перевалило через 6 млн. появилась проблема с работой с этими файлами. Даже разложив их по каталогам и создав разветвлённое дерево обход даже части этих каталогов стал занимать часы. Разумеется вначале никто не задумался над тем как это будут хранить и использовали обычный винт и ext4. В какой-то момент скорость чтения с этого раздела достигла 9MB/sec. Это слишком медленно. Экспериментальный переход на btrfs поднял в результате эту скорость до 13MB… Хотя это тоже не впечатляет. ssd для этого никто не собирался использовать да и объём уже перевалил через 1TB. Т.е. всё шло к использованию райдов. Поскольку коммерческий успех проекта остаётся под сомнением, то стоимость должна быть минимальной. А значит реализация должна быть программной.

Итак, нужно небольшое хранилище — на одном сервере/компьютере, т.е. до 4х дисков. Хранить нужно небольшие файлы — 1-3Mb каждый.
btrfs в нашем случае уже оказалась быстрее ext4, поэтому она и будет использоваться.
Кандидатами на управление хранилищем стали raid0 и raid10. Raid0 очевидно и объективно самый быстрый. Нередко утверждение, что самый быстрый raid10. Если подумать, то raid10 теоретически может быть таким же быстрым как и raid0 при чтении. Но вот для записи — очень сомнительно. Да и без особого труда можно найти различные тесты производительности аппаратных raid’ов.
Очевидное преимущество raid10 — надежность — не так уж и очевидно для не очень важных данных. Тем не менее, если надо хранить много, то используют либо raid, либо lvm. Можно и по старинке — вручную разделить данные по винтам. Надёжность везде одинаковая. Теряем винчестер — теряем данные. В raid0 размер strip’а (chunk) настраивается, поэтому при небольшом размере файлов большую часть данных можно будет таки восстановить.

В качестве подобытных были взяты 4 hdd Western Digital Caviar Blue 1TB
Пожалуй, один из самых быстрых среди имеющихся в свободном доступе без завышения цены.

raid0 собираем совершенно штатным образом:

mdadm -v —create /dev/md0 —level=raid0 —raid-devices=4 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1

Создание происходит мгновенно, ибо копировать и переразмечать нечего.
Сохраняем конфиг, чтоб при перезагрузке массив остался:

mdadm —examine —scan —config=mdadm.conf >> /etc/mdadm.conf

Создаём файловую систему:

#mkfs.btrfs -Lraid0 /dev/md0

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

fs created label raid0 on /dev/md0
        nodesize 4096 leafsize 4096 sectorsize 4096 size 3.64TB
Btrfs Btrfs v0.19

Интересно то, что FS всё еще экспериментальная. Впрочем это нисколько не помешало разработчикам Fedora 18 сделать btrfs файловой системой по умолчанию.

Проведём быстрый тест на скорость:

# hdparm -t /dev/md0

/dev/md0:
 Timing buffered disk reads: 2008 MB in  3.00 seconds = 669.11 MB/sec

В общем-то скорость линейного чтения колеблется от 650 до 690MB/sec.
Это, для сравнения, быстрее чем любой sata3 ssd ибо скорость больше чем способна пропустить sata3.
Полезный объём устройства 3,7T
Двух дневный тест показал устойчивую скорость и произвольного чтения и произвольной записи в 202MB/sec и 220MB/sec при операциях с файлами. Если ограничиться только чтением или только записью, то получаем 560MB/sec. Это устойчивые средние значения.
Весьма неплохо. Кстати, многие домашние ssd до этого не дотягивают.
Скорость весьма приличная на текущий момент. Поэтому собственно на нём и остановились. В случае, если один из винтов начнёт сыпаться, то придётся остановить весь raid, скопировать посекторно данные на новый винт и вернуть raid в активное состояние. Вполне допустимо для не очень важного хранилища. Если оно внезапно станет важным, то можно будет повысить его надежность и общую отказоустойчивость при помощи drbd.
В процессе тестирования нередко наблюдались пиковые скорости чтения и записи в 700MB/sec. Но поскольку файлы у нас маленькие, то такие пики возникали при параллельном чтении множества файлов. Видимо сказывается размер chunk’а.

Для очистки совести проведём те же тесты с raid10.
Создание raid10:

mdadm -v —create /dev/md0 —level=raid10 —raid-devices=4 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1

Но тут придётся подождать какое-то время. Пару-тройку часов.
В результате имеем следующее:

# hdparm -t /dev/md0

/dev/md0:
Timing buffered disk reads: 1080 MB in 3.01 seconds = 359.07 MB/sec

Мягко говоря разочаровывает. Точно такие же результаты были на raid0 с двумя дисками. Теоретическая возможность чтения с 4х винтов в данном случае не проявляется.
Но линейная скорость хоть и показательна, но не так важна для нас. Важнее произвольный доступ к файлам.
И он составил 190MB/sec на чтение и 125MB/sec на запись.
Полное разочарование с записью. Скорость чтения же сравнима с raid0. Напомню, что при этом мы еще и половину объёма дисков потеряем.

Есть еще один вариант программной реализации raid0, но уже средствами самой btrfs. С документации есть два параметра, которые могут повлиять на быстродействие и надёжность. data type — способ хранения данных. Влияет и на скорость доступа и на надёжность сохранения данных. Есть варианты: raid0, raid1, raid10 и single. И metadata profile — способ хранения метаданных. Он в большей степени влияет на возможность восстановления данных в случае мелких сбоев. Есть варианты: raid0, raid1, raid10, single и dup. Собственно, наблюдаем уже знакомые raid0 и raid10. Третий параметр, который скромно заявляет о возможном росте производительности при работе с файлами до 1GB — mixed. Для нас его влияние не очевидно.
Параметры задаются при создании файловой системы.

# mkfs.btrfs -d raid0 -m raid1 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

adding device /dev/sdd1 id 2
adding device /dev/sde1 id 3
adding device /dev/sdf1 id 4
fs created label (null) on /dev/sdc1
        nodesize 4096 leafsize 4096 sectorsize 4096 size 3.64TB
Btrfs Btrfs v0.19

Если надумаете использовать mixed, то учтите, что типы хранения данных и метаданных должны быть одинаковыми.
Обратите внимание, что единого устройства как при использовании raid здесь не получается. Монтировать можно любой раздел из использованных для файловой системы. Например, mount /dev/sdc1 /mnt/raid0

В общем-то, цифры получились весьма похожие с raid0 в исполнении md. Чтение 198MB/sec и запись 216MB/sec. Пики чтения чуть меньше 700MB/sec. Средняя скорость только чтения или только записи 660MB/sec, что очень приятно удивило.

При создании раздела с -m raid0 скорости совместного доступа немного возрастают. Чтение 203MB/sec и запись 219MB/sec. А вот раздельные чтение/запись немного уменьшились 654MB/sec.

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

Еще существует возможность хранения данных в lvm в режиме striping. Это очень близкий аналог raid0. Однако, у автора с lvm не складываются отношения уже не первый год. Поэтому такой вариант повышения производительности не рассматривался чисто по субъективным причинам.

Ну и напоследок неудачный эксперимент с raid10 в btrfs:

# mkfs.btrfs -L raid10 -d raid10 -m raid10 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/
sdf1

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

adding device /dev/sdd1 id 2
adding device /dev/sde1 id 3
adding device /dev/sdf1 id 4
fs created label raid10 on /dev/sdc1
        nodesize 4096 leafsize 4096 sectorsize 4096 size 3.64TB
Btrfs Btrfs v0.19

Порадовало то, что создание заняло пару секунд. Это вызывает скорее вопросы, нежели радость.
Чтение 122MB/sec и запись 127MB/sec. Раздельные чтение/запись 657MB/sec. Т.е. не годится для нашей задачи, хотя скорость раздельных операций и удивляет и радует.

Для душевного успокоения коллег был проведён тест с ext4 поверх raid0. Результаты ожидаемы.

# mkfs.ext4 /dev/md0 -L raid0
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=raid0
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=256 blocks, Stripe width=1024 blocks
244195328 inodes, 976760832 blocks
48838041 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
29809 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848, 512000000, 550731776, 644972544

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

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

tune2fs -O extents,uninit_bg,dir_index /dev/md0
tune2fs -o journal_data_writeback
tune2fs -m 0 /dev/md0
mount /dev/md0 raid0 -o acl,user_xattr,noatime,nodiratime,barrier=0,commit=0

Результаты плачевные для нашей задачи. Чтение и запись: 60MB/sec и 86MB/sec. Только чтение/запись 535MB/sec.

Выводы очевидны. Btrfs намного выгоднее для нашей задачи чем ext4, а raid0 быстрее raid10.

Осталось только добавить, что кроме рабочих обработчиков данных использовались и сторонние утилиты.
Для синтетических тестов использовались stress и bonnie++
Фактические данные о чтении/записи собирались при помощи sysstat.

Нифга себе воруют…

Купил сегодня винт WD Scorpio Black WD7500BPKT, 750Гб, HDD, SATA II:

Disk /dev/sdc: 750.2 GB, 750156374016 bytes
255 heads, 63 sectors/track, 91201 cylinders, всего 1465149168 секторов
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xf8326998

Создадим раздельчик:

Команда (m для справки): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Номер раздела (1-4, по умолчанию 1): 
Используется значение по умолчанию 1
Первый sector (2048-1465149167, по умолчанию 2048): 
Используется значение по умолчанию 2048
Last sector, +sectors or +size{K,M,G} (2048-1465149167, по умолчанию 1465149167): +700G
Значение за пределами диапазона.
Last sector, +sectors or +size{K,M,G} (2048-1465149167, по умолчанию 1465149167): 680G
Значение за пределами диапазона.
Last sector, +sectors or +size{K,M,G} (2048-1465149167, по умолчанию 1465149167): +650G
Partition 1 of type Linux and of size 650 GiB is set

Сабж!
Заявлено 1465149168 секторов, причём первые 2048 нельзя заюзать.
Итого (1465149168 — 2048) / 2 = 732573560 килобайт. Уже на глазок нет 750Gb. Делим на 1024 и еще раз на 1024 и получаем 698,636Gb.
-7% Неслабо…

DNSSEC на практике у регистратора доменов

Историческая справка

Система доменных имён (DNS) является одним из важнейших и основных интернет-сервисов, однако на момент её разработки безопасность не была главной целью. С развитием Интернет, однако, обнаружились и уязвимости в системе DNS. Достоверность ответа DNS сервера не проверяется, что позволяет подменить ответ сервера, перенаправив запрос пользователя на произвольный IP адрес. Уязвимы оказались и кэширующие DNS серверы интернет-провайдеров из-за возможности заполнения кэша DNS сервера данными, не исходящими от авторитетного DNS источника (атака Каминского).

Нельзя, впрочем, сказать, что о безопасности DNS вообще не задумывались до текущего времени. Серьёзные недостатки в безопасности этой системы были выявлены ещё в 1990 году Стивом Белловином (Steve Bellovin). Исследования в этой области начались со времён публикации доклада в 1995 году, что вызвало публикацию IETF первых спецификаций на эту тему (RFC 2065) в 1997 году. Первые попытки реализации этой спецификации привели к появлению новой спецификации (RFC 2535) в 1999 году. Именно на спецификации IETF RFC 2535 и была запланирована реализация DNSSEC, однако у этой спецификации были очень серьёзные проблемы с масштабированием на весь интернет. К 2001 году стало окончательно ясно, что эта спецификация была непригодна для крупных сетей. Это, в свою очередь, вызвало возникновение новых спецификаций (RFC 4033, 4034 4035) с принципиальными изменениями DNSSEC (DNSSEC-bis), новая версия которой устраняет основную проблему предыдущей реализации и, хотя в новой спецификации клиентам и необходимо совершать дополнительные действия для проверки ключей, тем не менее вполне пригодна для практического применения.

К сожалению, как это обычно и случается, недостатки DNSSEC являются продолжением её достоинств. Подписание и проверка данных DNS создают дополнительные накладные расходы, что отрицательно сказывается на производительности сети и серверов. К примеру, в среднем зона DNSSEC в 7-10 больше по размеру своего DNS эквивалента. Генерация и проверка подписей отнимает значительное время ЦПУ. Подписи и ключи занимают на порядок больше места на диске и в оперативной памяти, чем сами данные.

Впрочем, работа над DNSSEC еще не завершена, однако любая организация, активно использующая Internet, уже должна рассматривать DNSSEC в качестве важнейшего компонента своей инфраструктуры защиты. Протокол DNS по-прежнему уязвим для злоупотреблений.

Наши дни

Теперь нужно понять ненужность данной технологии в рунете. Вспомним, что в зону .SU DNSSEC внедрили в октябре 2011 года, в зону .РФ — в ноябре 2012, .RU — в декабре 2012. Теперь попробуйте вспомнить хоть один домен подписанный DNSEC. Не можете? 😉 Это ожидаемо. На момент написания этой статьи из трёх регистраторов заявивших о внедрении у себя DNSSEC только один (и это Регтайм) подписал свой основной домен. К этому можно добавить, что за всё время существования DNSSEC количество вопросов от пользователей о внедрении этой технологии можно пересчитать по пальцам одного человека. Прямо скажем — не густо.

Тогда возникает логичный вопрос: Зачем внедрять? Затем, что Регтайм всегда был и остаётся пионером и первооткрывателем во многим вопросах DNS. Внедрение DNSSEC, как штатной фишки, очередной шаг. Причём не только для отечественных зон, но и для многих других.

На этом предлагаю закончить с теорией и философией. Теперь рассмотрим собственно использование DNSSEC на собственных name серверах.

Практические работы

Для того чтобы DNSSEC начал использоваться как задумано авторами нужны следующие компоненты:

— подписанная зона первого уровня (у нас есть отечественные .RU .SU и .РФ)
— домен в этой зоне (у нас есть webnames.ru)
— авторитарные DNS серверы для нашего домена (имеются)
— рисолвер (кеширующий DNS сервер)

Текущей стабильной версией Debian является Squeeze уже 6.0.7. Его и продолжим использоваться в качестве базы. В качестве собственно DNS сервера у нас bind9.

Опустим подробности установки и настройки собственно bind9. Ставится он просто:

aptitude install bind9

Компоненты для работы с DNSSEC:

aptitude install dnssec-tools libcrypt-openssl-random-perl

Все конфиги по умолчанию находятся в /etc/bind/
Здесь нас интересуют опции в named.conf.options. В них нужно добавить:


dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

После этого нужно перечитать конфиги или перезагрузить bind. Тут кому как нравится: rndc reconfig или /etc/init.d/bind9 restart

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

Забегая вперёд скажу, что в процессе своей работы zonesigner создаёт десяток файлов и рациональнее складывать их отдельно, а не в общий каталог с зонами. Да и зоны лучше не складывать в один каталог. Это не вызывает проблем есть у вас всего несколько доменов. Но если у нас более 150 тысяч зон на каждом сервере, то надо как-то оптимизировать их хранение, иначе возникают адские накладные расходы.

В процессе эволюции мы имеем следующую иерархию зон: auto/ru/w/e/b/n/webnames.ru. Для zonesigner была создана аналогичная параллельная ветвь: dnssec/ru/w/e/b/n/webnames.ru/

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


mkdir -p /var/named/dnssec/ru/w/e/b/n/webnames.ru/
cd /var/named/dnssec/ru/w/e/b/n/webnames.ru/
zonesigner -genkeys -usensec3 -zone webnames.ru /var/named/auto/ru/w/e/b/n/webnames.ru

На выходе получим что-то типа:

        if zonesigner appears hung, strike keys until the program completes
        (see the "Entropy" section in the man page for details)

Generating key pair.....++++++ .........................................................................++++++ 
Generating key pair..++++++ ...++++++ 
Generating key pair....+++ .........+++ 
Verifying the zone using the following algorithms: RSASHA256.
Zone signing complete:
Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked
                      ZSKs: 1 active, 1 stand-by, 0 revoked

zone signed successfully

webnames.ru:
        KSK (cur) 02110  -b 2048  02/22/13      (webnames.ru-signset-00003)
        ZSK (cur) 21834  -b 1024  02/22/13      (webnames.ru-signset-00001)
        ZSK (pub) 51069  -b 1024  02/22/13      (webnames.ru-signset-00002)

zone will expire in 4 weeks, 2 days, 0 seconds
DO NOT delete the keys until this time has passed.

А теперь убедимся, что файлов создано много:


$ls -1
dsset-webnames.ru.
Kwebnames.ru.+008+02110.key
Kwebnames.ru.+008+02110.private
Kwebnames.ru.+008+21834.key
Kwebnames.ru.+008+21834.private
Kwebnames.ru.+008+51069.key
Kwebnames.ru.+008+51069.private
webnames.ru.krf

А рядом с файлом обычной зоны появился второй файл webnames.ru.signed и он более чем в 20 раз больше оригинала — 32669 байт против 1369. И еще 7520 байт на служебные файлы указанные выше. Т.е. мы получили в 30 раз больше информации. Правда зона webnames.ru совсем маленькая и такой прирост не сильно тяготит.

На всякий случай проверим новый файл зоны на ошибки:


$ donuts --level 8 webnames.ru.signed webnames.ru
0 errors found in webnames.ru.signed

«—level» — это уровень выдачи ошибок. Когда ошибок нет, то в нём особого смысла нет. Кстати, есть очень простой способ напороться на эти ошибки. Например, добавив NS запись со сторонним DNS сервером.
Добавим в зону запись bad NS ns1.gde-to-tam-daleko.ru и обновимся:

zonesigner -zone webnames.ru /var/named/auto/ru/w/e/b/n/webnames.ru

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

Теперь проверим на ошибки:

$ donuts --level 8 webnames.ru.signed webnames.ru 
bad.webnames.ru:
  Warning:     Only 1 NS record(s) for bad.webnames.ru found, but at least
               2 are suggested/required

bad.webnames.ru:
  Error:       sub-domain bad.webnames.ru is not securely delegated.  It is
               missing a DS record.

2 errors found in webnames.ru.signed

Вот так. 🙂 Это усложнение структуры стоит учитывать в своей практике. Если вдумчиво читать, то становится понятно, что именно нужно делать. Во-первых, добавить вторую NS запись, а во-вторых, добавить DS запись для поддомена.

Но откуда же у нас эти DS берутся? Выше у нас показан файл dsset-webnames.ru. Его содержимое таково:

webnames.ru.            IN DS 2110 8 1 4F38DB26A26DDFFB0A84052472D1AF70DAA595D7
webnames.ru.            IN DS 2110 8 2 0CC3937FE64FD4BF3B8282748F93C566870F4FCD254BCF0D91DBCF50 23D6D28C

Именно эти записи нужно передать регистратору домена, чтобы он их отправил в реестр зоны. И они же нужны для того чтобы donuts перестал выдавать ошибки для NS записей.
Процедура передачи у разных регистраторов разная. На Webnames.Ru, например, в разделе «Управления доменом» «Личного кабинета» есть специальный пункт «DNSSEC» где можно включить и выключить собственно поддержку DNSSEC, а также увидеть имеющиеся DS записи и при необходимости внести новые.

Теперь вспомним о том, что все криптографические ключи имеют срок годности. Неплохо бы автоматизировать и их замену… Радует, то что есть специальный демон rollerd. В то же время печалит, то что для этого демона нет init-скрипта. Поэтому придётся его написать самостоятельно. Можно, конечно, и не писать, а обойтись колхозными методами, но это уже каждый решает сам. Еще чуть больше печалит то, что rollerd хоть и следит за ключами и заменяет их, но не может заменить их в реестре.

Сначала определимся за чем будем следить. Для этих целей есть rollinit. Он готовит для rollerd список зон за ключами которых мы собираемся следить. Давайте определимся, что список мы будем хранить в dnssec/. Соответственно, добавим туда нашу подписанную зону:


rollinit -zonefile /var/named/auto/ru/w/e/b/n/webnames.ru.signed -keyrec /var/named/dnssec/ru/w/e/b/n/webnames.ru/webnames.ru.krf -admin support@webnames.ru webnames.ru >> /var/named/dnssec/rollrec

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

После этого нужно запустить rollerd. Вот обещанный init-скрипт: /etc/init.d/rollerd

#!/bin/bash

### BEGIN INIT INFO
# Provides:          rollerd
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

PATH=/bin:/usr/bin:/sbin:/usr/sbin
DESC="DNSSEC-Tools daemon to manage DNSSEC key rollover"
NAME=rollerd
DAEMON=/usr/sbin/$NAME
SCRIPTNAME=/etc/init.d/$NAME
CONF=/var/named/dnssec/rollrec
PIDFILE=/var/run/rollerd.pid

[ -x "$DAEMON" ] || exit 0
. /lib/init/vars.sh
. /lib/lsb/init-functions
[ -f $CONF ] || exit 0

start_rollerd () {
        [ -f $PIDFILE ] && return 1
        $DAEMON -rrfile $CONF -directory /etc/bind -pidfile $PIDFILE
}

stop_rollerd () {
        if [ -s $PIDFILE ]; then
                PID=`cat $PIDFILE`
                kill $PID && rm -f $PIDFILE
                sleep 3
                [ -d "/proc/$PID" ] && return 1
                return 0
        fi
        PID=`ps xa | grep -v grep | grep $DAEMON | awk '{print $1}'`
        [ -z "$PID" ] && return 0
        kill $PID
        sleep 3
        [ -d "/proc/$PID" ] && return 1
        return 0
}

case "$1" in
        start)
                log_daemon_msg "Starting $DESC" "$NAME";
                start_rollerd;
                log_end_msg $?;
                ;;
        stop|force-stop)
                log_daemon_msg "Stopping $DESC" "$NAME";
                stop_rollerd;
                log_end_msg $?;
                ;;
        restart)
                log_daemon_msg "Restarting $DESC" "$NAME";
                stop_rollerd;
                start_rollerd;
                log_end_msg $?;
                ;;
        *)
                echo "Usage: $0 ";
                exit 1;
                ;;
        esac;

exit 0;

Готовим его к запуску, автозапуску и запускаем.


chmod 755 /etc/init.d/rollerd
update-rc.d rollerd defaults
/etc/init.d/rollerd start

Если кто-то совсем расстроился, что полную ротацию ключей автоматизировать невозможно, то это зря. Можно, но уже при помощи почтового демона. У нас используется sendmail. Поэтому при помощи smrsh можно сделать почти всё что угодно. Делается это довольно просто. В /etc/mail/sendmail.mc добавляем следующие строки перед первым MAILER’ом:


FEATURE(`virtusertable', `hash /etc/mail/virtusertable')dnl
VIRTUSER_DOMAIN_FILE(`/etc/mail/local-host-names')dnl

В /etc/mail/virtusertable добавляем:
dnssec@localhost dnssec
Этим мы создали виртуальный почтовый ящик dnssec@localhost и отправили всю входящую почту на системного юзера dnssec.

В /etc/aliases добавляем:
dnssec: "|/etc/mail/smrsh/dnssec"
Этим мы всю входящую почту юзеру dnssec отправили через пайп (т.е. в его STDIN) в скрипт /etc/mail/smrsh/dnssec

А уж в скрипте /etc/mail/smrsh/dnssec мы можем делать всё что хотим.
Стоит отметить, что скриптом это называется условно. Это может быть и бинарник.

Теперь перезапустим sendmail и все изменения вступят в силу:
/etc/init.d/sendmail restart

При этом всём не забудьте, что при использовании smrsh нужно переинициировать /var/named/dnssec/rollrec с адресом dnssec@localhost. Т.е. примерно так:


rollinit -zonefile /var/named/auto/ru/w/e/b/n/webnames.ru.signed -keyrec /var/named/dnssec/ru/w/e/b/n/webnames.ru/webnames.ru.krf -admin dnssec@localhost webnames.ru >> /var/named/dnssec/rollrec

Сам скрипт /etc/mail/smrsh/dnssec приводить не имеет смысла, поэтому ограничимся обёрткой на bash без функционала.
Само письмо выглядит примерно так:

From: root
To: dnssec@localhost
Subject: assistance needed with KSK rollover of zone webnames.ru

The zone "webnames.ru" is in the middle of KSK rollover. In order for rollover
to continue, its keyset must be transferred to its parent.

Парсить его можно, например, так:

#!/bin/bash

while read L; do
    if [ "${L:0:9}" == "Subject: " ]; then
        for W in $L ; do echo -n '' ; done
        echo "Domain $W"
    fi
done

Т.е. после разбора поля Subject по словам получим в результате имя домена (в переменной W) для которого нужно послать обновлённые DS записи в реестр.

Теперь настроим последний компонент DNSSEC — рисолвер, он же кеширующий DNS сервер. И здесь всё тоже очень просто. Если взять тот же самый bind9, то в тот же самый файл /etc/bind/named.conf.options нужно добавить те же опции и перезагрузить bind:


dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

/etc/init.d/bind9 restart

Теперь на рабочем компе нужно прописать в качестве DNS сервера наш рисолвер и наслаждаться DNSSEC’ом.

Вот и всё.

Программирование сейчас и 15 лет назад

Раньше когда я садился кодить, то я кодил. Долго и без перерывов. А теперь… Одна из причин — повсеместная многозадачность. Чтобы отвлечься достаточно кликнуть один раз или нажать две кнопки… и ты уже смотришь киношку скаченную с торрентов в фоне. Раньше надо было выйти из ассемблера, иногда даже перезагрузиться и это отнимало время и ломало настроенное окружение. Иногда на компе неделями был запущен XAS с открытыми исходниками. Сейчас это не удивляет никого (alt+tab и ты там), а 15+ лет назад это было странно. В результате мощно кодят только самые дисциплинированные или уж очень увлечённые.
Теряю хватку… Грущу…

Сканер на тележке

С первого и по тринадцатое с песнями, шутками, танцами…
Чем же еще заниматься-то с первого и по тринадцатое?

—Несчастный случай

 

Отгремели корпоративы и неумолимо приближался Новый Год. Для нас не сделали исключения и устроили корпоратив с традиционным возлиянием в Максимилианс.
После него технари компании решили, что в праздновании не хватает IT и был проведён второй — IT — корпоратив с применением X-Box 360, Kinect и метрового телевизора. В процессе оного в голову пришло множество весёлых и главное реализуемых мыслей. Те кто никогда не использовал Kinect врядли поймут…

Одной из мыслей было соорудить некий необычный и полезный агрегат с возможностью ежедневного использования. Вспомнились недавние приключения со сканированием чего-то с бегатнёй по кабинетам.

А почему бы не сделать наш сканер более мобильным?

Под это дело была произведена ревизия заскладированных по всему офису «железок».

Нашлось:

Intel DN2800MT

2 x SO-DIMM DDR3 4Gb Patriot

OCZ mSATA SSD 60Gb

блок питания от ноута ASUS 19V (сейчас заменён на менее мощный FPS)

D-Link DWA-125

Сканер HP ScanJet G2410

Офисный стул на колёсиках с отломленной саппортерами спинкой.

Из подручных необходимых средств были использованы Zalman VE200, Debian 6.0.5 amd64 netinst вариант в виде iso, usb клавиатура, ethernet патч корды, Olympus FE-115.

Десятого вроде заняться нечем…
Отлично! Десятого лечим печень

—Несчастный случай 

Собираем всё это в кучку и получаем нечто такое:

Конструкция абсолютно бесшумная после установки Debian на SSD и отключения VE200.

Debian ставим в минимальном варианте + ssh (он понадобится для второго/запасного/прямого варианта доступа к сканеру).

Теперь подготовим Debian для работы с ssd в режиме read-only. Поскольку «тележка» — агрегат мобильный, то восстанавливать fs будет совершенно неинтересно.

Для работы os потребуется запись в /tmp, /var/tmp, /run и всякие /var/* (типа lock и log). Перенесём их в память.


cd /var
rm -rf tmp run lock log
ln -s /dev/shm
ln -s /dev/shm lock
ln -s /dev/shm run
ln -s /dev/shm log


cd /etc/network
rm -rf run
ln -s /dev/shm run


cd /var/lib
rm -rf urandom
ln -s /dev/shm urandom

Отключаем ненужные нам, но включенные по умолчанию сервисы:

update-rc.d cron remove
update-rc.d exim4 remove
update-rc.d nfs-common remove
update-rc.d portmap remove

Для того чтобы можно было использовать перенесённые в память каталоги нужно при каждой загрузке создавать там структуры каталогов. Сделаем это через initd скрипт /etc/init.d/tmpfs в т.ч. и для не особо нужных каталогов.

#!/bin/bash

### BEGIN INIT INFO
# Provides:          tmpfs
# Required-Start:
# Required-Stop:
# X-Stop-After:      sendsigs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO

mount tmpfs -t tmpfs /tmp
cd /tmp
mkdir exim4 sshd log
chmod 750 exim4
chown Debian-exim:Debian-exim exim4
touch utmp
chmod 660 utmp
chgrp utmp utmp

cd log
mkdir apt exim4 fsck installer news
chmod 2750 exim4
chown Debian-exim:adm exim4
touch dmesg wtmp lastlog
chmod 660 wtmp lastlog
chgrp utmp wtmp lastlog

exit 0

И подключим его к загрузке:

chmod 755 /etc/init.d/tmpfs
update-rc.d tmpfs defaults

Теперь надо добавить /tmp в /etc/fstab.

echo "tmpfs /tmp tmpfs defaults 0 0" >> /etc/fstab

Поскольку логов в случае чего не будет, то можно на всякий случай настроить удалённое логирование:


echo "*.*;auth,authpriv.none @10.0.0.21" >> /etc/rsyslog.conf
/etc/init.d/rsyslog restart

Здесь 10.0.0.21 — IP адрес сервера, который принимает нашил логи.

Перезагружаемся…
Редактируем параметры монтирования / на noatime,ro.


sed -ir 's/\/\s+ext4\s+defaults/\/ ext4 noatime,ro/' /etc/fstab

И мы получили девайс, который не боится внезапного отключения питания и загружается за 20 секунд. А нам быстрее и не надо.

Теперь займёмся собственно сканером. Установим нужный пакет, включим автозапуск и добавим сеть для которой он будет работать:


aptitude install -y sane
sed -i 's/RUN=no/RUN=yes/' /etc/default/saned
echo "10.0.0.0/24" >> /etc/sane.d/saned.conf

HP 2400 не поддерживается в sane и в Debian нет ничего для него. Но зато есть такой репозитарий для Ubuntu. Подключим его к нашей тележке:


echo "deb http://ppa.launchpad.net/lion-simba/hp2400/ubuntu karmic main" >> /etc/apt/sources.list
aptitude update

Установим найденные hp2400 пакеты:

aptitude install -y libsane-hp2400x64 xsane

Сканер готов. Проверим:

# scanimage -L
device `net:10.0.0.3:genesys:libusb:004:002' is a Hewlett Packard ScanJet 2400c flatbed scanner

Здесь 10.0.0.3 — это IP тележки по проводной сети.

Теперь сделаем тележку чуть более мобильной. Для этого подключимся к сети по wifi, тем более, что у нас есть DWA-125.


aptitude install -y wireless-tools firmware-ralink wpasupplicant

В /etc/network/interfaces вписываем следующее для назначения статичного IP адреса.

auto wlan0
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
address 10.0.0.241
netmask 255.255.255.0
gateway 10.0.0.1
dns-nameservers 10.0.0.1 10.0.0.2

Шлюз и DNS, конечно, можно не указывать, но вдруг что-то понадобится обновить или доставить?

При этом не забываем удалить allow-hotplug eth0 или auto eth0 из того же конфига:


sed -ir 's/allow-hotplug eth0//' /etc/network/interfaces
sed -ir 's/auto eth0//' /etc/network/interfaces

Поскольку wifi сеть с WPA, то нам понадобится еще и конфиг для wpasupplicant на который мы уже сослались /etc/wpa_supplicant/wpa_supplicant.conf:


ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=root
network={
ssid="наша точка"
key_mgmt=WPA-PSK
psk="наш ключ"
}

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

—Несчастный случай

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

Места более чем достаточно для размещения mATX платы, блока питания, пары шнуров и wifi usb карты. Но контакты с платы не должны касаться металлических частей стула. Для этого после рытья в шкафах находим нечто, что можно использовать для крепежа к стулу и в качестве стоек для платы.

И неплохо получилось:

В сборе стул выглядит вполне естественно:

Но если заглянуть снизу, то становятся заметны высокие технологии. 😉

Сканер потом поставим сверху, но сначала надо решить вопрос с питанием. Лишнего UPS’а под рукой не оказалось, поэтому решили задействовать обычный электрический удлинитель на 3 посадочных места. Длина шнура более 10 метров, что опять же даёт ощутимую мобильность. К стула удлинитель прикреплён пластиковыми стяжками.

Вот так выглядит законченный вариант «сканирующей тележки».

В качестве окончательного хулиганства водрузили на эту же конструкцию еще и шредер. Отсканировал документ и тут же уничтожил не отходя. 😀

 

Как же хочется на работу!
К станку, к прилавку, куда угодно!

—Несчастный случай

С Новым Годом! Надеюсь, Вы улыбнулись читая это. 😉

Порядок и чистота

В детстве взрослые окружавшие меня часто подменяли понятие «порядка» «чистотой». Заставляя меня «навести порядок в комнате» они хотели получить убранную/чистую комнату. Подметённая пыль, чистые, вымытые полы, спрятанные игрушки — вот непременные атрибуты «порядка». И только много лет спустя у меня появилось «право» иметь тот порядок, который действительно удобен для жизни, учёбы, работы.

Странные эти взрослые. 😉

SAMSUNG Ultrabook 5 серии

В прошлом месяце был куплен сей агрегат: SAMSUNG NP530U3C-A02RU

Агитировали за него очень правильно, в смысле, профессионально. 🙂 Дескать железо у него такое же как у MacBook Air, да и клепаются они на одном заводе. Вообще, я не фанат Apple и не вижу смысла переплачивать за брэнд или за кукую-то ненужную мне фишку. Тем более, что начинка теперь там x86, а макось мне не интересна. Внешне они действительно очень похожи. Но всё же не близнецы.

В общем купил. Не дорого. За 20 т.р.

Ничего особенно пакостного замечено не было. Вроде нормальный ноут по нормальной цене. Но подвох таки был, да еще и не один.

Клавиатура. Оказалась всё-таки довольно специфическая после ASUS и BTC. Нет кнопок Home, PgUp, PgDn и End. Они совмещены с курсорными. Сами же курсорные клавиши половинной высоты. Смысл этого не пойму никак… На MacBook Air тоже самое. На 9″ ASUS EEE 901 это еще можно понять, но на 13″… Нет эмуляции num pad! Вот это оказалось чуть ли не катастрофой. * + —  на num pad просто обязательны для работы во всех известных мне коммандерах.

 

HDD. Установленный Hitachi на 500Gb, заявленный SAMSUNG’ом как высокопроизводительный, имеет 8Mb кэша и 5400 оборотов! В общем-то на@#$лово. Немного грело наличие 24Gb ssd. Но и тут оказалась засада, но о ней тоже позже.

Крышка. Много где написано, что он имеет алюминиевый корпус. не нашел где там металл. А еще на крышке нет защелок для надежного закрытия. У кого есть дети — поймёт.

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

Апгрейд

Уже давно я крепко подсел на SSD. И на старом ASUS и на десктопе и в EEE901 стоят SSD. Это даже не обсуждается. Первым делом я купил к ноуту OCZ 128Gb и планку 4Gb памяти.

Номер раз. Чтобы вскрыть корпус пришлось рыться в инете на предмет правильного разбора. Оказалось, что после откручивания единственного винтика на нижней крышке её надо просто сильно тянуть. Реально сильно. А защелки там пластиковые. Таки вскрыл и не сломал.

Номер два. Слот памяти заклеен чем-то, что очень плотно приклеено. Причём не только к слоту, но и рядом живущим микросхемам. Даже осторожное отклеивание ЭТОГО привело к отклеиванию пары подлежащих наклеек  со штрих-кодами. Последние удалось вернуть на место без повреждений.

Номер три. Винт крепится на специальной металлической планке, прикрученной к корпусу. Надо очень осторожно её откручивать, потом снимать шлейф sata и только потом уже откручивать винт. Но самой большой подвох в том, что винт там нужен 7мм толщины. А SSD я купил 9,5мм, ибо других и нет в широкой продаже. Разумеется он не встал на нужное место! Пришлось раскрутить свежекупленный SSD, вытащить собственно SSD и положить его внутрь на уплотнитель без корпуса. Получилось даже красиво. Работает отлично. Перегрева нет. И вроде даже свободного места стало больше.

Больше апгрейдить в этом девайсе просто нечего. %) Ультра же.

В процессе установки Fedora 17 64bit была масса странных и непонятных моментов.

Достоверно выяснилось, что загрузка со встроенного SSD 24Gb невозможна совершенно официально. В БИОСе выбрать нельзя ибо такого пункта просто нет. А экспериментальным путём выяснилось, что ни одни раздел который нужно монтировать при загрузке нельзя располагать на этом SSD. Иначе ноут просто зависает при загрузке. Эту загадку разгадать не смог.

Также включая всякие энергосберегающие функции в БИОСе можно лишиться загрузки с USB совершенно незаметно и не очевидно. При этом зарядка устройств с этих самых USB продолжает идти преотлично.

Встроенный модуль WiFi не поддерживается полностью в Fedora 17. Нужно отдельно скачивать прошивку и складывать в нужное место. Иначе устройство есть, а связи нет. А еще wifi приёмник-передатчик очень слабый. Там где старый ASUS показывает 60-70%, SAMSUNG пишет о 50%.

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

P.S. успел съездить с ним в командировку. В общем, не разочарован. Но и удовлетворения нет. Надеюсь прослужит долго, иначе этот будет первый последний мой «не ASUS». В результате пока не рекомендую.

lan0: локальная сеть глобального масштаба

Предыстория

У нас есть группы серверов, расположенные в разных датацентрах и даже городах. На текущий момент используются 6 датацентров. Между бОльшей частью этих серверов идёт интенсивный обмен трафиком и не всегда по безопасным протоколам. В связи с этим было решено создать общую «локальную» сеть между всеми имеющимися серверами. Имеющийся опыт построения сетей при помощи OpenVPN с использованием маршрутизации подсказывал, что это далеко не самое лучшее решение. Идеальной была бы одноранговая сеть. Решение оказалось не таким уж и сложным и далеко не новым. Будем использовать OpenVPN и Bridge-utils.

Классическая сеть на OpenVPN предполагает наличие одного (или нескольких) собственно серверов с OpenVPN и клиентов, которые к нему подключаются. Не секрет, что OpenVPN поддерживает tcp и udp соединения. Поскольку у нас выделенные серверы без какой-либо неконтролируемой фильтрации трафика, то выбираем udp вариант, тем более, что он имеет меньшие задержки в передаче данных.

Первый сервер

Первый сервер (фактически это наша точка обмена трафиком) настраиваем по классической схеме. На большинстве серверов установлен Debian, поэтому всё описание имеет лёгкий уклон в сторону его особенностей.

aptitude install openvpn openvpn-blacklist
cd /etc/openvpn/
cp -R /usr/share/openvpn/easy-rsa/2.0 /etc/openvpn/easy-rsa
mkdir /etc/openvpn/keys
chmod 750 /etc/openvpn/keys

Правим /etc/openvpn/easy-rsa/vars следующим образом:

export EASY_RSA="/etc/openvpn/easy-rsa"

export KEY_DIR="/etc/openvpn/keys"

export KEY_SIZE=2048

export KEY_COUNTRY="RU"
export KEY_PROVINCE="MSK"
export KEY_CITY="Samara"
export KEY_ORG="Regtime Ltd."
export KEY_EMAIL="support@regtime.net"

Далее по той же классической схеме готовим ключи:

cd /etc/openvpn/easy-rsa
. ./vars
./clean-all
./build-ca
./build-key-server servername
./build-dh

Создаём минимальный конфиг для сервера в /etc/openvpn/udp-server. Параметров может быть намного больше и простор для оптимизации огромный.

dev tap0
proto udp
port 1194

ca keys/ca.crt
cert keys/servername.crt
key keys/servername.key
dh keys/dh2048.pem

user nobody
group nogroup
server 172.18.5.208 255.255.255.240

persist-key
persist-tun

status /dev/shm/openvpn-status-udp
verb 3
client-to-client
client-config-dir ccd-udp

log-append /var/log/openvpn-udp.log
comp-lzo

script-security 2
up "/etc/init.d/lan0 start"
down "/etc/init.d/lan0 stop"

Подключаем его и запускаем сервер:

ln -s udp-server udp-server.conf
/etc/init.d/openvpn start

Обратите внимание на последний три строки конфига. Именно они сделают этот сервер пригодным для использования в одноранговой сети. Стоит отметить, что сделать это можно только для udp сервера. Сам скрипт выглядит так — /etc/init.d/lan0:

#!/bin/bash

### BEGIN INIT INFO
# Provides:          lan0
# Required-Start:    $network $remote_fs $syslog openvpn
# Required-Stop:     $network $remote_fs $syslog openvpn
# Should-Start:      
# Should-Stop:       
# X-Start-Before:    $x-display-manager gdm kdm xdm wdm ldm sdm nodm
# X-Interactive:     true
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: lan0 service
### END INIT INFO

. /lib/lsb/init-functions

PATH=/bin:/sbin:/usr/bin:/usr/sbin

br="lan0"
tap="tap0"
eth="eth1"
eth_ip="172.18.5.2"
eth_netmask="255.255.255.0"
eth_broadcast="172.18.5.255"

case "$1" in
    start)
        brctl addbr $br
        brctl addif $br $eth

        for t in $tap; do
            brctl addif $br $t
        done

        for t in $tap; do
            ifconfig $t 0.0.0.0 promisc up
        done

        ifconfig $eth 0.0.0.0 promisc up

        ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
    ;;

    stop)
        ifconfig $br down
        brctl delbr $br

        ifconfig $eth $eth_ip netmask $eth_netmask broadcast $eth_broadcast
    ;;
    *)
        echo "usage lan0 {start|stop}"

        exit 1
    ;;
esac
exit 0

Этот же скрипт можно использовать для rc.d.

update-rc.d lan0 defaults

Последовательность при ручном запуске такая:

/etc/init.d/openvpn start
/etc/init.d/lan0 start

При ручной остановке:

/etc/init.d/lan0 stop
/etc/init.d/openvpn stop

Следует учесть, что при перезапуске OpenVPN lan0 будет подниматься заново. В некоторых случаях это нужно делать вручную. Например, через cron задача выглядит так:

[ -n "`/sbin/ifconfig tap0`" ] && [ -z "`/usr/sbin/brctl show|grep tap0`" ] && /etc/init.d/lan0 start

Собственно сервер готов. Теперь надо создать ключи и сертификаты для клиентов.

Клиенты

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

cd /etc/openvpn/easy-rsa
. ./vars
./build-key client

Разумеется, имя каждого клиента (здесь client) должно быть уникальным.

После ввода/подтверждения данных для сертификата появятся следующие файлы:

client.crt
client.csr
client.key

На стороне клиента нам понадобятся следующий файлы из каталога /etc/openvpn/keys на сервере:

ca.crt
client.key
client.crt

На клиенте тоже устанавливаем OpenVPN:

aptitude install openvpn openvpn-blacklist
mkdir /etc/openvpn/keys
chmod 750 /etc/openvpn/keys

Копируем ключ и сертификаты в /etc/openvpn/keys:

Создаём простейший конфиг /etc/openvpn/client.conf:

dev tap0
proto udp
client

remote server 1194
resolv-retry infinite
nobind

persist-key
persist-tun

ca keys/ca.crt
cert keys/client.crt
key keys/client.key

comp-lzo
verb 3
status /dev/shm/client-status-udp
log /var/log/openvpn-client.log

ping 10
ping-restart 1800

script-security 2
up "/etc/init.d/lan0 start"
down "/etc/init.d/lan0 stop"

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

Множество серверов

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

1. Каждый сервер должен выдавать отдельные уникальные IP адреса.

Хотя для lan0 это зачастую и не важно. Это достигается заменой одной строки в конфигах:

server 172.18.5.208 255.255.255.240

2. Нужно синхронизировать сертификаты между серверами OpenVPN.

Это уже чуть сложнее, но решаемо.

Самое простое решение — это конечно же скопировать каталог /etc/openvpn/keys по ssh. Но есть способ лучше — rsync.

Для двухстороннего обмена нам потребуется два скрипта — загрузки обновлений и скачивания оных.

Загрузка — push

#!/bin/bash

export RSYNC_RSH="ssh -c arcfour -o Compression=no -x -l root"

rsync \
    -zu --modify-window=10 -aHAX --numeric-ids --sparse \
    /etc/openvpn/keys remotehost:/etc/openvpn/keys

Обновление — pop

#!/bin/bash

export RSYNC_RSH="ssh -c arcfour -o Compression=no -x -l root"

rsync --delete-after \
    -zu --modify-window=10 -aHAX --numeric-ids --sparse \
    remotehost:/etc/openvpn/keys /etc/openvpn/keys

Обратите внимание на ключ —delete-after. Он используется для того чтобы после синхронизации удалить файлы которых нет на стороне назначения. Т.е. pop удалит локально всё то чего нет на remotehost.

Обратите внимание на порядок обновления ключей. В нормальных условиях новые ключи и сертификаты нужно создавать на первом (основном) сервере OpenVPN, а все последующие должны с него получать обновления через pop. Т.о. push нам не нужен вообще. Но в общем случае можно добавлять новых пользователей на любом сервере и вот тогда надо сначала нужно сделать push для загрузки, а затем pop на всех остальных OpenVPN серверах.

Поскольку взаимодействие идёт по ssh, то всем серверам нужно обменяться ключами ssh для root’а. Ключ можно сгенерить при помощи команды

ssh-keygen -t rsa -b 2048

а скопировать при помощи

ssh-copy-id remotehost

Учтите, что на всех этих серверах должен быть разрешен вход для root. Для безопасности можно отключить авторизацию по паролю. /etc/ssh/sshd_config

PermitRootLogin yes
PasswordAuthentication no

Теперь после добавления нового клиента нужно сделать push на сервере, где собственно ключ был добавлен и pop на всех остальных OpenVPN серверах.

Люди

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

Конфиг /etc/openvpn/tcp-server:

dev tun0
proto tcp
port 1194

ca keys/ca.crt
cert keys/server.crt
key keys/server.key
dh keys/dh2048.pem

user nobody
group nogroup
server 172.18.5.248 255.255.255.240

persist-key
persist-tun

status /dev/shm/openvpn-status-tcp
verb 3
client-to-client
client-config-dir ccd-tcp

push "route 172.18.5.0 255.255.255.0"

log-append /var/log/openvpn-tcp.log
comp-lzo

Ключ и сертификат подготавливаются также как и для udp. Конфиг для такого подключения будет даже несколько проще — client.ovpn:

client
proto tcp
remote server 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
comp-lzo

Клиенты под разные операционки лучше качать с официального сайта: http://openvpn.net/