Допустим, есть задача присутствия удаленных сервисов в каком-то локальном сегменте Internet. Или наоборот — задача присутствия локальных сервисов в удаленном сегменте Internet — как кому нравится.
Блоками IP мы не рулим, с BGP заморачиваться не охота.
То есть нам надо предоставить IP адрес IP1_2 сервера SERVER1 как один из действующих IP адресов сервера SERVER2. Ну и тоже самое — для IP1_3 и SERVER3.
Сами сервера могут быть расположены где угодно по отношению друг к другу. Локальные айпишники IP1_1, IP2_1, IP2_2, IP3_1, IP3_2 должны работать и отвечать как ни в чем ни бывало.
Мы просто добавим на сервера SERVER2 и SERVER3 по одному айпишнику с сервера SERVER1. В добавок еще и тоннель зашифруем.
Вооружение
Все опыты производятся на OS CentOS 5.x/6.x
Для туннелирования воспользуемся openvpn из одноименного пакета.
Для конфигурации моста на SERVER1 воспользуемся утилитой brctl из пакета bridge-utils.
Для настройки продвинутого роутинга на серверах SERVER2/SERVER3 воспользуемся утилитой ip из пакета iproute.
Конфигурация SERVER1
Конфигурируем сервер-донор. Нам понадобится поднять сетевой мост на действующем интерфейсе и выпилить из сетевой конфигурации все IP, которые подлежат трансплантации на SERVER2/SERVER3.
Для начала поставим пакеты bridge-utils и openvpn.
Далее, правим /etc/sysconfig/network-scripts/ifcfg-eth0 и объявляем его частью сетевого моста br0:
DEVICE=eth0 ONBOOT=yes BOOTPROTO=none TYPE=Ethernet BRIDGE=br0
Создаем конфигурацию моста br0 в /etc/sysconfig/network-scripts/ifcfg-br0:
DEVICE=br0 TYPE=Bridge BOOTPROTO=static ONBOOT=yes IPADDR=X.X.X.X NETMASK=Y.Y.Y.Y
Здесь X.X.X.X/Y.Y.Y.Y — предыдущая конфигурация eth0.
Если существуют какие то локальные дополнительные IP, объявляем их традиционным способом в файлах br0:0, br0:1 и т.д.
Настраиваем openvpn-сервер. Конфигурация /etc/openvpn/server.conf:
dev tap0 proto udp lport 3389 local X.X.X.X ca /etc/openvpn/server/ca.crt cert /etc/openvpn/server/server.crt key /etc/openvpn/server/server.key dh /etc/openvpn/server/dh1024.pem tls-server tls-auth /etc/openvpn/server/ta.key 0 mode server tls-server topology subnet persist-key persist-tun client-config-dir /etc/openvpn/ccd client-to-client tcp-nodelay script-security 3 reneg-sec 36000 keepalive 10 60 ping-timer-rem user nobody group nobody verb 4 mute 10 log /var/log/openvpn/openvpn.log status /var/log/openvpn/openvpn-status.log 1 up /etc/openvpn/up down /etc/openvpn/down
Касаться вопроса генерации ключей и сертификатов я не буду — этой инфы в гугле хватает. Главное здесь вот что.
- Используется Ethernet-Bridging через dev tap0
- Используется клиентская директория /etc/openvpn/ccd, в которую кладутся файлы с именами, соответствущими Common Name (SSL) клиентов (например файл server3). Каждый файл содержит одну строчку — инструкцию по настройке туннелированного IP адреса и маски. Например, /etc/openvpn/ccd/server3: ifconfig-push 1.1.1.1 255.255.255.0
- Используются скрипты поднятия и опускания tap-интерфейса /etc/openvpn/up и /etc/openvpn/down
Касательно двух последних пунктов. При подъеме интерфейса, openvpn почему то не делает ему «ifconfig up». Ну ничего, сделаем сами. Заодно добавим интерфейс в мост.
/etc/openvpn/up:
#!/bin/bash /sbin/ifconfig $1 up /usr/sbin/brctl addif br0 $1
При остановке интерфейса, очевидно его надо удалить из моста.
/etc/openvpn/down:
#!/bin/bash /usr/sbin/brctl delif br0 $1
Допустим, нам надо трансплантировать локальные айпишки этого сервера 1.1.1.1 и 2.2.2.2 на сервера SERVER2 и SERVER3 соответственно, которые имеют Common Name сертификатов server2 и server3 соответственно. Тогда создаем файлы:
/etc/openvpn/ccd/server2
ifconfig-push 1.1.1.1 255.255.255.255
/etc/openvpn/ccd/server3
ifconfig-push 2.2.2.2 255.255.255.255
Конфигурация SERVER2/SERVER3
Пробросить туннель для айпишника это в общем-то не сложно. А вот заставить сервер корректно с ним работать — задача Linux Advanced Routing.
Для этого нам потребуется создать дополнительную таблицу роутинга в /etc/iproute2/rt_tables:
# echo "2 peering" >>/etc/iproute2/rt_tables
И научить openvpn корректно прописывать роуты. Для начала конфиг openvpn:
client user root dev tap proto udp remote X.X.X.X 3389 nobind ca /etc/openvpn/server3/ca.crt cert /etc/openvpn/server3/server3.crt key /etc/openvpn/server3/server3.key dh /etc/openvpn/server3/dh1024.pem tls-client tls-auth /etc/openvpn/server3/ta.key 1 resolv-retry infinite reneg-sec 36000 persist-key persist-tun ping 30 ping-restart 60 verb 4 mute 10 script-security 3 up /etc/openvpn/up down /etc/openvpn/down log /var/log/openvpn/openvpn.log
Да, нам потребуется работа openvpn от root, чтобы down-скрипт имел достаточные полномочия для работы.
Скрипт /etc/openvpn/up будет:
- Инструктировать ядро о том, что удаленный роутер сервера SERVER1 с IP 1.2.3.4 находится где-то в стороне tap-интерфейса
- Добавлять дефолтную роуту в дополнительную таблицу peering
- Инструктировать ядро использовать эту дефолтную роуту, если пакет инициируется с tap-интерфейса
#!/bin/bash table=peering router=1.2.3.4 d=$1 lip=$4 /sbin/ip route add $router/32 dev $dev /sbin/ip route add default via $router dev $dev table $table /sbin/ip rule add from $lip lookup $table prio 1000
Скрипт /etc/openvpn/down будет производить отмену всех этих инструкций. В принципе все роуты при опускании интерфейса удаляются автоматически. Нам надо подчистить только таблицу правил ip.
#!/bin/bash table=peering lip=$4 /sbin/ip rule del from $lip lookup $table prio 1000
Заключение
Таким образом, на серверах SERVER2 и SERVER3 будут подняты интерфейсы tap0 с IP-адресами SERVER1. Любые сервисы могут слушать на этих IP адресах и обслуживать их. Наряду с этим, локальные IP адреса всех участников остаются так же рабочими.
Какое применение можно найти данному извращению? Ну тут фантазии хватает. Это может быть и ситуация, когда какой то удаленный сервис должен по какой то причине работать на локальной машине. Или когда требуется замаскировать локальные сервисы за удаленными IP адресами. Или просто, банально не хватает IP адресов, а у датацентра строгая политика выделения оных.
Автор: pentarh