Архивы за Ноябрь, 2012

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/

Внешние серверы в локальном облаке на Proxmox

Как несложно догадаться имеем облако на базе Proxmox.

Все узлы имеют по два интерфейса. Один из них (eth0) смотрит в локальную сеть, а второй (eth1) — в глобальный интернет. Однако, сами узлы не имеют внешних адресов. IPv4 нынче дороги, да и просто незачем.

В этом облаке нужно создать виртуальную машину — контейнер (CT) с внешним адресом.

Виртуальная сеть (aka venet) не подходит ибо маршрутизироваться не будет. Поэтому будем использовать veth. Чтобы это сделать на узле нужно сначала создать мост (bridge) в котором будет состоять eth1. Далее нужно создать CT с veth сетью. Ну или добавить veth интерфейс в существующую, но при этом эта машина должна быть выключена. Обычно получаем eth0, но уже в CT. 😉

Proxmox не даёт настроить IP адрес для veth для VM. Поэтому лезем в /var/lib/vz/private/CTID/etc/network/interfaces на узле и пишим конфиг вручную. Он стандартный:

auto eth0
iface eth0 inet static
        address IP
        netmask 255.255.255.0
        gateway GW

Теперь запускаем CT и подключаемся к нему по ssh.

 

Внезапно: Том и Джерри

Сейчас совершенно случайно на youtube наткнулся на мультики про Тома и Джерри. Взглянул под другим углом.

Мышь всегда задирает кота. Кот всегда предпринимает ответные меры. Причём всегда показывает великолепную изобретательность и находчивость. Пробует огромное количество инженерных решений. А мышь ничем кроме деструктивных действий не занимается. Причём ломая всё и вся всегда оказывается как бы победителем. Редкий мульт когда зло всегда побеждает.

Учитывая советское детство и буржуйское происхождение мультфильмов — внезапно видим победу эксплуататора над эксплуатируемым.

Командировки

Раньше я не любил командировки (дорога, чужой город, в датацентрах инженерам пофиг).

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

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

ASUS X51l

Начну с обзора своего ноута купленного 10.08.2008г. 😉

Им оказался ASUS X51l. Основные его характеристики:

  • 2х ядерный проц (T2390) 1.86GHz с изменяемой частотой (800MHz, 1.07MHz, 1.33MHz, 1.86MHz),
  • 2Gb памяти,
  • 160Gb HDD,
  • 15″ экран с разрешением 1280×800,
  • вес 3кг,
  • FreeDOS.

Есть два встроенных динамика, но ни камеры, ни микрофона нет.
В то время это был нормальный рабочий ноут. Правда он мне достался с некоторой скидкой (и это было дополнительным аргументом), т.к. привезли его на заказ, а заказчик отказался.

На данный момент некоторые его недостатки стали преимуществом:

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

Отсутствие камеры и микрофона не позволяет завестись паранойе о том, что за вами следят.

Отсутствие встроенного bluetooth модуля успокаивает при обнаружении очередной дыры в оном.

FreeDOS не дал переплатить ни копейки за винду. Правда сразу же была установлена Fedora.

В общем всё неплохо до сих пор.

Стоит отдельно отместить очень удобную клавиатура. На ней отсутствует num pad, что сейчас для 15″ ноута уже редкость. Клавиши Delete и Insert располагаются в правом верхнем углу. Home, PgUp, PgDn и End располагаются в столбик справа. Курсорные клавиши отделены достаточными прогалами. Причём расположение клавиш почти один в один совпадает с используемой уже много лет и на работе и дома клавиатурой BTC 6100c.

За время эксплуатации ноут подвергся трём адпгрейдами.

Сначала я заменил винт на SSD. Выбор в том же 2008 году пал на Kingston SSDNow V Series SSD 128 Gb.

Для этого ноута прекрасный экземпляр. Linux в лице Fedora тогда уже прекрасно справлялся с TRIM, поэтому сомнений не было никаких. До сих пор SSD работает прекрасно, хотя за последние полтора год ноут был выключен всего пару дней.

Второй апгрейд пришелся на крышку ноута. Туда была наклеена специально заказанная тематическая наклейка.

Третий апгрейд увеличил память с 2х до 3х Gb путём замены одной из установленных планок памяти с 1 на 2Gb.

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

На прошлый день рождения под этот ноут была подарена охлаждающая платформа. Она снизила рабочую температуру на 3 градуса. Сама при не шумит.

В общем, ноут стал для меня очень надёжным и удобным рабочем местом на несколько лет.

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