Debian.pro/

Про Debian


Настройка сети на dom0-машине в debian/ubuntu для KVM, updated.

За более чем два года (а столько прошло с моей прошлой статьи на эту же тему) многое изменилось. Вышел wheezy, на полном скаку к нам приходит ipv6, немцы стали добрее, мои знания подтянулись, я перестал быть евангелистом и перестал бояться костылей. В общем, сеть на своих dom0-машинах я настраиваю уже по-другому =)

Почему я пишу вторую статью:
1) здесь будет работать ipv6 в виртуалках
2) меньшие накладные расходы на роутинг.
3) всё будет делаться через /etc/network/interfaces.
4) не нужно будет писать ip ro add на каждый адрес виртуалок.

Как и в прошлый раз пишу так, «чтобы заработало в hetzner». Во-первых, много кто у них серверы арендует, во-вторых у них, мягко говоря, недемократичный подход к настройкам сети на машинках. А вообще эта конструкция должна заработать где угодно с некоторыми оговорками.

Что нам дали:
1) 4 ip адреса из сети хостера (192.0.2.0/24 — 192.0.2.3, 192.0.2.10, 192.0.2.11, 192.0.2.12)
2) целиком подсети 198.51.100.0/28 и 198.51.100.96/28
3) ipv6 /64 подсеть 2001:DB8:1:1::/64

Всё это нам нужно взвести и использовать в виртуалках.
Сетевая карта, в которую воткнут кабель — eth0.
Начинаем писать /etc/network/interfaces :

auto lo
iface lo inet loopback


# поднимаем bridge, которым будут пользоваться виртуалки:
auto br0
iface br0 inet static

    address 192.0.2.3
    broadcast 192.0.2.255
    netmask 255.255.255.0
    bridge_ports eth0
    bridge_stp off

    # выставляем mtu на сетевой карте:
    pre-up ifconfig eth0 mtu 1450
    # прописываем маршрут по умолчанию для самой машинки:
    post-up /sbin/ip route replace default via 192.0.2.1 mtu 1450
    # включаем ipv6 на интерфейсе dom0-машины:
    post-up /sbin/ip -6 addr add 2001:DB8:1:1::2/64 dev br0
    # прописываем ipv6-шлюз по умолчанию. У немцев для новых сетей это fe80::1 (я так и не понял механику этого). У других хостеров это был бы, скорее всего, 2001:DB8:1:1:: или 2001:DB8:1:1::1
    post-up /sbin/ip -6 route replace default via fe80::1 dev br0
    # вешаем на br0 адреса из наших собственных подсетей. Эти адреса будут ipv4-шлюзами для виртуалок в соответствующих подсетях.
    # обратите внимание, что в выданных подсетях нельзя использовать первый и последний ip-адреса (первый - адрес сети, второй - broadcast-адрес). То есть, само собой, никто вам не запрещает (кроме RFC и винды), но это приведет к некоторым спецэффектам в подсети.
    post-up /sbin/ip addr add 198.51.100.1/28 dev br0
    post-up /sbin/ip addr add 198.51.100.97/28 dev br0


Пробуем попинговать все адреса, повешенные на br0. Если все пингуются, то продолжаем. Если не пингуются — пишите в комментариях диагностику (ip addr sh, ip -6 addr sh, ip ro sh, ip -6 ro sh).

Теперь можно создавать виртуалки. Для virt-install указываем опцию --network=bridge:br0, чтобы они выходили в сеть через br0.

Теперь про конфиги сети внутри виртуалок.
Для подсети 198.51.100.0/28 конфиг будет таким (lo не описан, но не забудьте про него ;) ):

auto eth0
iface eth0 inet static
  address 198.51.100.{2-14}
  netmask 255.255.255.240
  gateway 198.51.100.1

  # нужные нам DNS-серверы:
  dns-nameservers 8.8.8.8 8.8.4.4

Для подсети 198.51.100.96/28 всё аналогично:

auto eth0
iface eth0 inet static
  address 198.51.100.{98-110}
  netmask 255.255.255.240
  gateway 198.51.100.97

  # нужные нам DNS-серверы:
  dns-nameservers 8.8.8.8 8.8.4.4
  # домен машины.
  dns-search your-domain.tld

Для работы ipv6 добавляем:

iface eth0 inet6 static
  address 2001:DB8:1:1::3
  netmask 64
  gateway 2001:DB8:1:1::2
  dns-nameservers 2001:DB8:1:1::2

Если вам нужна ipv6-only машинку, то не забудьте про auto eth0.

С адресами 192.0.2.10, 192.0.2.11, 192.0.2.12 всё немного сложнее. Точнее, здесь возможны 3 случая:
1) у хостера ip-адреса из его подсетей не прибиты к mac-адресам (и тогда как раз всё легко)
2) у хостера ip-адреса прибиты к mac-адресам, но mac-адрес можно изменить
3) у хостера ip-адреса прибиты к mac-адресам, другой mac-адрес указать нельзя.

В первом случае в виртуалке нам подойдет такой /etc/network/interfaces :

auto eth0
iface eth0 inet static
  address 192.0.2.{10-12}
  netmask 255.255.255.240

  # обратите внимание, что шлюзом в данном случае выступает роутер хостера, а не наша dom0-машина.
  gateway 198.51.100.1
  # нужные нам DNS-серверы:
  dns-nameservers 8.8.8.8 8.8.4.4

Во втором случае нам подойдет тот же конфиг, но хостеру нужно сообщить mac-адрес виртуалки. mac-адрес в kvm+libvirtd мы можем узнать так:

root@vds:~# cat /etc/libvirt/qemu/${vm_name}.xml | grep 'mac address'

Где ${vm_name} — имя виртуалки внутри libvird (опция -n у virt-install).

У hetzner это делается в robot’e — рядом с каждым отдельное выданным ip-=адресом (кроме самого первого) есть кнопка «сменить mac-адрес».

В третьем случае всё намного хуже. Нам нужно сделать так, чтобы машинка выходила в сеть через нашу dom0-машину (т.е. 198.51.100.2), но при этом не потеряла доступ к соседям по подсети вне нашей машины (например, к машине 198.51.100.100).
Нам понадобится примерно такой /etc/networking/interfaces внутри виртуалки:

auto eth0
iface eth0 inet static
  address 192.0.2.{10-12}
  netmask 255.255.255.240

  # опцию gateway мы не указываем, на этапе установки можно использовать 192.0.2.2 в качестве шлюза.
  # нужные нам DNS-серверы:
  dns-nameservers 8.8.8.8 8.8.4.4
  # маршрут по умолчанию
  post-up ip ro replace default via 192.0.2.2 dev eth0
  # до шлюза по умолчанию ходим напрямую
  post-up ip ro replace 192.0.2.2/32 dev eth0
  # сносим маршрут до нашей подсети
  post-up ip ro del 192.0.2.0/24

ip ro sh в таком случае после старта виртуалки должен выглядеть примерно так:

root@vds:~# ip ro sh
default via 192.0.2.2 dev eth0
192.0.2.2 dev eth0 scope link

Все соединения будут ходить через default-gateway, которым будет выступать наша машинка. Соответственно, шлюз самого хостера ничего «не узнает» о том, что у нас виртуалка.

Остался последний штрих — привести sysctl к правильному виду. В файл /etc/sysctl.conf в конце добавляем такие строки:

net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.all.proxy_arp = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1

Так же для вменяемой работы ipv6 я советую добавить такие строки (честно содранные у hetzner’a, да):

net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.accept_dad=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_source_route=0
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.all.autoconf=0
net.ipv6.conf.all.accept_dad=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra_defrtr=0
net.ipv6.conf.all.accept_ra_rtr_pref=0
net.ipv6.conf.all.accept_ra_pinfo=0
net.ipv6.conf.all.accept_source_route=0
net.ipv6.conf.all.accept_redirects=0

Применяем их командой

root@vds:~# sysctl -p

или ребутаемся.

Ну и маленький совет напоследок — когда вы напишете конфиг interfaces для br0, а активным у вас будет ещё eth0 (то есть вы новый конфиг ещё не примените) — лучше ребутнуться, а не делать /etc/init.d/networking restart. net restart в данном случае в 80% случаев отработает криво и вы потеряете связь с машинкой по сети.

Вроде всё.


Комментарии (2):

  1. Valentin :

    Расскажи, как ты все свое счастье бэкапишь, поделись опытом.

  2. rdiff-backup + mysqldump + rsync внутри виртуалок.
    Эффективно бэкапить такие виртуалки из dom0 машины не получится — либо бэкап неконсистетный будет, либо по IO сильно проседать будет.

Написать комментарий