У меня есть сервер с единым физическим интерфейсом 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». Я не уверен, что это за термин.