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

от автора

У нашей компании есть группы серверов, расположенные в разных датацентрах и даже городах. На данный момент мы используем 6 датацентров. Между большей частью серверов идёт интенсивный обмен трафиком, а протоколы обмена данными не всегда обеспечивают необходимый уровень защиты. Поэтому мы решили создать общую локальную сеть между всеми имеющимися серверами. Мы отказались от создания сети при помощи OpenVPN с использованием маршрутизации из-за чрезмерной громоздкости архитектуры подобных сетей. На наш взгляд, самый простой и удобный вариант — это одноранговая сеть. Далее мы расскажем подробнее о том, как создать и настроить одноранговую сеть.

Для ее создания мы используем OpenVPN и Bridge-utils.
Стандартная сеть на OpenVPN состоит из одного или нескольких серверов с OpenVPN и клиентов, которые к ним подключаются. OpenVPN поддерживает соеднинения по протоколам TCP и UDP. Поскольку на наших выделенных серверах нет какой-либо контролируемой фильтрации трафика, лучше выбрать протокол 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 адреса.
Это достигается заменой одной строки в конфигах:

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 —delete-after \
-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 remote host

Учтите, что на всех этих серверах должен быть разрешен вход для 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

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

ссылка на оригинал статьи http://habrahabr.ru/company/webnames/blog/162193/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *