Трансплантация IP адресов с сервера на сервер

Допустим, есть задача присутствия удаленных сервисов в каком-то локальном сегменте 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 адресов, а у датацентра строгая политика выделения оных.

 

 

Пост с //habrahabr.ru/post/140057/