В моем распоряжении довольно мощная машина с Ubuntu 16.04 Server. Он запускает несколько контейнеров докеров и виртуальных машин (с использованием VirtualBox), которые в дальнейшем называются виртуальными машинами. На данный момент хост назначил один IP-адрес (скажем, 192.168.1.10), а доступ к службам виртуальных машин осуществляется посредством NAT (например, 192.168.1.10:80 -> 172.17.0.2:80), что неудовлетворительно.
Вместо этого я хотел бы привязать несколько IP-адресов (скажем, 192.168.1.100-110) к интерфейсу хостов и перенаправить трафик, попадающий на дополнительные IP-адреса, в виртуальные машины. Что приводит к отображению <public IP> <--> <private IP>
.
Я смог выполнить эту первую часть, добавив
[...]
up ip addr add 192.168.1.1xx/24 dev ens3 label ens3:0
down ip addr del 192.168.1.1xx/24 dev ens3 label ens3:0
[...]
записи в мои /etc/network/interfaces
файл (где ens3
очевидно, это имя сетевого интерфейса хоста). Это означает, что дополнительные IP-адреса работают.
Но вторая часть вызывает у меня головные боли. Пока я только рассматривал iptables
на основе решений, поскольку это кажется наиболее подходящим, и все руководства, которые я читал до сих пор, также использовали его.
Я активировал переадресацию IP, добавив net.ipv4.ip_forward=1
к /etc/sysctl.conf
.
Затем я выполнил следующие команды для пересылки:
iptables -t nat -A POSTROUTING -d 172.17.0.2 -j SNAT --to-source 192.168.1.100
iptables -t nat -A PREROUTING -d 192.168.1.100 -j DNAT --to-destination 172.17.0.2
172.17.0.2
- частный IP-адрес одной из виртуальных машин. Он запускает веб-сервер на порту 8000. telnet 172.17.0.2 8000
устанавливает соединение, которое говорит мне, что веб-сервер запущен. Но telnet 192.168.1.100 8000
не работает.
Практически все руководства по iptables
имеют дело с пересылкой одного порта или диапазона портов, но лишь немногие из них обрабатывают весь трафик на интерфейсе.
Кто-нибудь может заметить мою ошибку? Или у кого-нибудь есть хороший совет по поводу альтернативных инструментов, которые сделают работу?
По крайней мере, на стороне докера вы сможете сделать это с помощью --publish
переключатель, который может принимать, как вариант, ip хоста.
например
docker run -p 192.168.1.105:80:80 -d image
Ваше правило NAT должно работать:
iptables -t nat -A PREROUTING -d 192.168.1.100 -j DNAT --to-destination 172.17.0.2
Однако вам нужно добавить еще одно правило, если вы запрашиваете какую-либо услугу с того же компьютера (локально):
iptables -t nat -A OUTPUT -d 192.168.1.100 -j DNAT --to-destination 172.17.0.2
Правило NAT может применяться к определенным портам определенного протокола или ко всем протоколам и портам (как здесь).