Назад | Перейти на главную страницу

Назначение нескольких IP-адресов одной машине с одним интерфейсом

У меня есть сервер с единым физическим интерфейсом eth0. Я собираюсь запускать виртуальные машины на этом сервере. Для этого у меня есть блок IPv4, который направляется на указанный сервер. Я пытаюсь развернуть виртуальные машины в локальную подсеть. 10.0.0.0/8 а затем 1-к-1 NAT - внешний IP-адрес на внутренний IP-адрес, тем самым эффективно предоставляя этим виртуальным машинам внешние IP-адреса и доступ в Интернет.

NAT 1-к-1 не проблема, но у меня проблемы с тем, чтобы гипервизор принимал и обрабатывал трафик для всех внешних IP-адресов (даже без какой-либо формы NAT). Я тестирую все с одной / 30 сетью со следующими IP

xxx.xxx.xxx.0/30
xxx.xxx.xxx.1/30
xxx.xxx.xxx.2/30
xxx.xxx.xxx.3/30

Предположим, что у eth0 есть IP yyy.yyy.yyy.yyy. Пересылка пакетов IPv4 включена.

Я могу заставить свои гипервизоры (или виртуальные машины) отвечать на самый низкий адрес в блоке, похоже, все остальные адреса игнорируются.

Я попытался добавить все IP-адреса в качестве псевдонима к eth0:

ip addr add xxx.xxx.xxx.0/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.1/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.2/30 dev eth0 label eth0:1
ip addr add xxx.xxx.xxx.3/30 dev eth0 label eth0:1

Я также пробовал использовать / 32 вместо / 30 и использовать разные ярлыки и комбинацию всего вышеперечисленного. Это не сработало. Затем я решил создать мост, к которому будет подключена вся подсеть.

br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    link/ether ea:5a:59:06:8a:7a brd ff:ff:ff:ff:ff:ff
    inet xxx.xxx.xxx.0/30 brd 5.39.22.163 scope global br0
       valid_lft forever preferred_lft forever
    inet xxx.xxx.xxx.1/30 brd 5.39.22.163 scope global secondary br0
       valid_lft forever preferred_lft forever
    inet xxx.xxx.xxx.2/30 brd 5.39.22.163 scope global secondary br0
       valid_lft forever preferred_lft forever
    inet xxx.xxx.xxx.3/30 brd 5.39.22.163 scope global secondary br0
       valid_lft forever preferred_lft forever

Опять безуспешно. Затем я создал мост, но без привязки к нему IP. Я просто добавил маршрут к подсети на этом мосту. Мне не нужно, чтобы мой гипервизор действительно отвечал на трафик, мне просто нужно, чтобы он принимал его, поэтому iptables обрабатывает его и применяет NAT.

ip route add xxx.xxx.xxx.0/30 dev br0

Это тоже не увенчалось успехом.

Во всех случаях, которые я пробовал, гипервизор (или виртуальная машина, если я включил NAT 1-к-1) мог бы отвечать на трафик для xxx.xxx.xxx.0, любые другие IP-адреса в блоке являются игнорируется.

Основная проблема оказалась проблемой маршрутизации в центре обработки данных. Не весь трафик направлялся на мой сервер правильно.

Моя окончательная установка выглядит так:

6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether <MAC ADDRESS> brd ff:ff:ff:ff:ff:ff
    inet <hypervisor IP/netmask> brd <broadcast addr> scope global eth0
       valid_lft forever preferred_lft forever
11: local_net: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether fe:00:05:27:16:a0 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/8 brd 10.255.255.255 scope global local_net
       valid_lft forever preferred_lft forever

Поэтому я назначаю только IP гипервизора физическому интерфейсу. Затем создаю локальный мост. Этот мост имеет DHCP-сервер, который прослушивает его и предоставляет статическую аренду заранее определенным MAC-адресам виртуальной машины, поэтому каждая виртуальная машина получает один и тот же локальный IP-адрес при каждой загрузке.

Затем, чтобы запустить NAT 1-к-1, я просто добавляю такие правила:

iptables -t nat -A PREROUTING -d <public VM IP>/32 -i eth0 -j DNAT --to-destination <local VM IP>
iptables -t nat -A POSTROUTING -s <local VM IP>/32 -o eth0 -j SNAT --to-source <public VM IP>

Это переведет весь трафик, прибывающий на eth0 для одного из IP-адресов виртуальной машины к виртуальной машине и всего трафика, поступающего с виртуальной машины на общедоступный IP-адрес.

В IPv4 самый низкий адрес в сети, за двумя исключениями, является сетевым адресом, и его нельзя использовать для назначения хосту.

Если у тебя есть /32, это единственный адрес хоста, который должен быть маршрутизирован. Такой адрес обычно используется как адрес обратной связи маршрутизатора.

Если у тебя есть /31, то есть сеть, используемая для соединений точка-точка, поскольку она имеет только два используемых адреса. Первоначально /31 сети были непригодны, но RFC 3021, Использование 31-битных префиксов в двухточечных каналах IPv4 изменил это.

Чтобы использовать четыре адреса в одной сети, самая длинная маска, которую вы можете иметь, - /29, что дает вам шесть доступных адресов.

В каждой подсети первый адрес предназначен для сети, а последний - обычно для широковещательной рассылки. поэтому xxx.xxx.xxx.0 и xxx.xxx.xxx.3 не будут работать для сети класса / 30, и все IP-адреса в сети / 32 являются сетевыми адресами. сетевые адреса используются для маршрутизации и не могут быть назначены устройству

Если вы хотите использовать сети класса / 30, вы можете использовать xxx.xxx.xxx.1 и xxx.xxx.xxx.2 в одном сегменте сети (сеть xxx.xxx.xxx.0) и xxx.xxx.xxx. 5 и xxx.xxx.xxx.6 в другом сегменте сети (сеть xxx.xxx.xxx.4)

Возможно, попробуйте другую сеть класса / 24.

Кроме того, похоже, что вы пытаетесь назначить все IP-адреса для eth0: 1, попробуйте использовать eth0: 2, eth0: 3 и eth0: 4

Еще одна команда, которую стоит попробовать: «ifconfig eth0 add x.x.x.1 netmask 255.255.255.0» или с «netmask 255.255.255.252» для сети класса / 32. эта команда автоматически назначит вам номера подынтерфейсов, начиная с eth0: 0, используя затем eth0: 1.

Кроме того, я не уверен, можно ли назвать эти сети «классом / 30» или «классом / 24». Я не уверен, что это за термин.