Pull to refresh

Роутим IPv4 и IPv6 в KVM на примере Hetzner

Reading time4 min
Views15K


Данная статья посвящена вопросам правильной настройки IPv4 и IPv6 в сетевых конфигурациях, аналогичных тем, что применяются в Hetzner на базе KVM (так же потенциально подходит для любых других HVM, и для Xen).

Примеры конфигурации интерфейсов основаны на ifup, так как на хосте и большинстве виртуалок у меня Ubuntu. Гайд по IPv4 местами основан на статье из Hetzner Wiki, вопросы IPv6 я, в основном, гуглил.


Стартовые условия



У данного хостера вы сходу получаете один IPv4 адрес. Дополнительно к нему вы можете попросить/приобрести до трех IPv4-адресов и блоки подсетей. В данном примере будет рассматриваться следующую конфигураця:

IP хоста: 123.45.12.48
Шлюз: 123.45.12.1
Дополнительные IP: 123.45.53.11, 123.45.53.12, 123.45.53.13
Дополнительная подсеть: 123.45.90.112/29

Hetzner шлет все пакеты на MAC-адрес первого (и, обычно, единственного) интерфейса eth0, и ожидает, что все исходящие пакеты будут уходить с этого же MAC-адреса. Через саппорт можно попросить поставить другие MAC-адреса для дополнительных «поштучных» IP-адресов, что позволяет закинуть vnet* интерфейсы KVM-ок в один мост с eth0, но эту конфигурацию я рассматривать не буду.

Итак, что необходимо получить в итоговой конфигурации:
  • отсутствие NAT, каждая VM получает минимум один публичный IP-адрес;
  • хост занимается всем роутингом:
    • трафик между разными VM;
    • трифик между VM и интернетом;
    • централизовано фильтрует пакеты в iptables (можно ограничивать взаимодействие VM друг с другом и интернетом)
  • IP-адреса из выделенных подсетей не теряются (в демонстрационной подсети адреса 123.45.90.112 и 123.45.90.119 обычным методом использовать нельзя – это адреса сети и броадкаста)


Для настройки сети понадобятся следующие пакеты: bridge-utils, dhcp3-server, iptables, iproute2.

Настраиваем основной интерфейс хоста


В /etc/network/interfaces необходимо описать eth0 следующим образом:
auto eth0
iface eth0 inet static
  address 123.45.12.48
  netmask 255.255.255.255
  gateway 123.45.12.1
  pointopoint 123.45.12.1

Маска 255.255.255.255 означает, что все исходящие пакеты будут уходить на шлюз, через опцию pointopoint ifup определяет, что гейтвей технически находится на этом же интерфейсе (куда он, естественно, иначе не попадает из-за ограниченной маски). Это эквивалентно следующим правилам роутинга:
123.45.12.1 dev eth0 proto kernel scope link src 123.45.12.48
default via 123.45.12.1 dev eth0 metric 100


Настраиваем по мосту для VM



Поскольку в задачу входит ограничение трафика между VM, их нельзя засунуть в один мост. Для каждого дополнительного IP-адреса и каждого адреса из подсети /29 необходимо описать отдельный мост:
auto br112
br112 iface inet static
  address 172.30.112.1
  netmask 255.255.255.0
  pre-up brctl addbr br112
  post-up route add -host 123.45.90.112 br112
  post-down brctl delbr br112

Каждый мост будет называться br<xxx>, где xxx – последний байт IPv4 адреса. На нем поднимается приватный IPv4 адрес из 172.30.xx.0/24 (зачем это надо – описано далее), тут же в описании интерфейса привязан brctl (создание моста в pre-up, уничтожение в post-down), и настраивается роутинг (публичный IP-адрес определяется на этом мосту).

Абсолютно идентично описываются br11, br12, br13, и br113–br119.

Настраиваем DHCP



Так как pointopoint конфигурация затруднена в процессе инсталляции некоторых OS, на каждом мосту для VM будет работать DHCP-сервер, который даст базовую конфигурацию IPv4, достаточную для завершения установки.

Модифицируем конфиг dhcp3 в /etc/dhcp3/dhcpd.conf следующим образом:
authoritative;
default-lease-time 3600;
max-lease-time 3600;
ddns-update-style ad-hoc;
log-facility local7;
use-host-decl-names on;

option subnet-mask 255.255.255.0;
option domain-name "lan";
option domain-name-servers xx.yy.100.100, xx.yy.99.99, xx.yy.98.98; <-- заменяем на актуальные DNS–серверы

subnet 172.30.11.0 netmask 255.255.255.0 {
    option routers 172.30.11.1;
    range 172.30.11.10 172.30.11.200;
}

subnet 172.30.12.0 netmask 255.255.255.0 {
    option routers 172.30.12.1;
    range 172.30.12.10 172.30.12.200;
}

subnet 172.30.13.0 netmask 255.255.255.0 {
    option routers 172.30.13.1;
    range 172.30.13.10 172.30.13.200;
}

subnet 172.30.112.0 netmask 255.255.255.0 {
    option routers 172.30.112.1;
    range 172.30.112.10 172.30.112.200;
}

...

subnet 172.30.119.0 netmask 255.255.255.0 {
    option routers 172.30.119.1;
    range 172.30.119.10 172.30.119.200;
}


Также объясняем, на каких интерфейсах dhcp3 должен работать: в файле /etc/default/dhcp3-server изменяем INTERFACES:
INTERFACES="br11 br12 br13 br112 br113 br114 br115 br116 br117 br118 br119"

После чего перезапускаем dhcp3:
/etc/init.d/dhcp3-server restart

Настройка iptables



#!/bin/sh
it="/sbin/iptables"

MY_NET="123.45.90.112/29 123.45.53.11/32 123.45.53.12/32 123.45.53.13/32"
MY_NET_DHCP="172.30.0.0/16"
HOST_IP="123.45.12.48"
MAIN_IF="eth0"

# INPUT
$it -F INPUT

$it -A INPUT -p udp --dport 67 -i br+ -j ACCEPT
# настраиваем другие политики INPUT
#$it -A INPUT -j DROP

# FORWARD
$it -F FORWARD

$it -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

for NET in $MY_NET; do
$it -A FORWARD -i br+ -o $MAIN_IF -s $NET -j ACCEPT # VM[fixed_ip] --> net
done

for NET in $MY_NET_DHCP; do
$it -A FORWARD -i br+ -o $MAIN_IF -s $NET -j ACCEPT # VM[dhcp] --> net
done

for SOURCE_NET in $MY_NET $MY_NET_DHCP; do
for DEST_NET in $MY_NET; do
$it -A FORWARD -i br+ -o br+ -s $SOURCE_NET -d $DEST_NET -j ACCEPT # VM <--> VM
done
done

for NET in $MY_NET; do
$it -A FORWARD -i $MAIN_IF -o br+ -d $NET -j ACCEPT # net --> VM
done
$it -A FORWARD -i $MAIN_IF -o gbr1 -d $MY_NET_PVT -j ACCEPT # net --> PVT

$it -P FORWARD DROP

# POSTROUTING
$it -t nat -F POSTROUTING
for NET in $MY_NET_DHCP; do
$it -t nat -A POSTROUTING -o $MAIN_IF -s $NET -j SNAT --to-source $HOST_IP # nat the dhcp
# NAT для приватных IP-адресов от DHCP
done

echo 1 > / proc/sys/net/ipv4/ip_forward


Настройка VM



Ну и последний этап – непосредственно настроить VM. Для libvirt/KVM описываем сеть через мост:
<interface type='bridge'>
  <source bridge='brXX'/>
  <model type='virtio'/>
</interface>


При этом, на первичной загрузке виртуалка получит приватный адрес от DHCP, а уже после установки необходимо зафиксировать на ней публичный IP:
auto eth0
iface eth0 inet static
  address 123.45.90.116
  netmask 255.255.255.255
  gateway 123.45.12.48
  pointopoint 123.45.12.48


Объем статьи вышел достаточно большой, так что про IPv6 напишу отдельно.
Tags:
Hubs:
Total votes 25: ↑21 and ↓4+17
Comments29

Articles