На работе мы используем определенную операционную систему, которую мы (разработчики) запускаем в виртуальном боксе. Виртуализированная ОС работает под управлением сервера Samba и rsh, который мы используем для доступа к ОС. Кроме того, виртуализированной ОС требуется доступ к нескольким серверам в нашей сети.
Я хотел бы получить способ быстро запускать виртуальные машины как часть установки Docker. Идея состоит в том, чтобы иметь контейнер докеров, который будет предоставлять доступ к виртуальной машине, контейнер, который запускает тесты на виртуальной машине, и в будущем некоторые другие контейнеры, которые будут предоставлять, например. анализ системы.
У меня есть контейнер докеров, который настраивает машину VirtualBox с мостовой сетью. Я могу без проблем получить доступ к виртуальной машине с помощью rsh из контейнера, который ее запустил. Однако я не могу получить доступ к виртуальной машине с помощью rsh из других контейнеров (ну, я нашел решение, которое опишу ниже, но я не думаю, что оно хорошее). Что интересно, ping работает нормально.
Сейчас настройка выглядит так:
Виртуальный контейнер
VirtualBox машина
Рабочий контейнер
Пока что я нашел только одно решение о том, как подключиться с помощью rsh к машине VirtualBox, и это добавить маршрут:
ip route add 172.18.1.5 via 172.18.0.5
И затем rsh на 172.18.1.5. Однако здесь есть одна серьезная проблема. Поскольку мне нужно знать адрес, назначенный виртуальной машине, я должен установить адрес виртуального ящика на адрес, который можно легко угадать по адресу контейнера, в котором он работает. Изменение маршрута в контейнере также означает, что контейнер должен быть привилегированный, и я хотел бы свести количество привилегированных контейнеров к минимуму.
Чего бы я хотел больше, так это иметь возможность rsh в Виртуальный контейнер (172.18.0.5) напрямую. Таким образом, мне не пришлось бы угадывать IP-адрес виртуальной машины, но я мог бы использовать имя хоста Виртуальный благодаря docker-compose.
Я думал, что могу использовать NAT для этого. Я сделал следующее:
iptables -t nat -A PREROUTING --destination 172.18.0.5 -j DNAT --to-destination 172.18.1.5 iptables -t nat -A POSTROUTING --source 172.18.1.5 -j SNAT --to-source 172.18.0.5
Однако, похоже, это совсем не работает. Примечание: меня не волнует, являются ли все порты пересылкой или нет. Очевидно, что было бы лучше или пересылать только rsh и Samba, но rsh проблематично из-за того, что сервер выбирает порт для связи, аналогично пассивному FTP.
Есть идеи, что я делаю неправильно или как еще я могу достичь своей цели?
Содержимое таблицы iptables nat:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- anywhere 4f04152f8562 to:172.18.1.5
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER_OUTPUT all -- anywhere 127.0.0.11
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
DOCKER_POSTROUTING all -- anywhere 127.0.0.11
SNAT all -- anywhere anywhere to:172.18.0.5
Chain DOCKER_OUTPUT (1 references)
target prot opt source destination
DNAT tcp -- anywhere 127.0.0.11 tcp dpt:domain to:127.0.0.11:43467
DNAT udp -- anywhere 127.0.0.11 udp dpt:domain to:127.0.0.11:39285
Chain DOCKER_POSTROUTING (1 references)
target prot opt source destination
SNAT tcp -- 127.0.0.11 anywhere tcp spt:43467 to::53
SNAT udp -- 127.0.0.11 anywhere udp spt:39285 to::53A
Кроме того, я установил в контейнер wirehark и думаю, проблема в том, что существует цикл, вызванный правилами iptables.
Я вижу, что пакеты с 172.18.0.6 по 172.18.0.5 отправляются на 172.18.1.5, так что это правильно. Кроме того, в ответах от 172.18.1.5 адрес источника переведен на 172.18.0.5, а затем они отправляются на 172.18.0.6, что тоже правильно. Однако тогда есть соединение с 172.18.1.5 на 172.18.0.5. Думаю, в этом проблема, так как подключение должно быть на 172.18.0.6. Однако я не знаю, как убедиться, что виртуальный компьютер знает правильный адрес для подключения.
Теперь, когда я думаю об этом - разве DNAT не должен оставлять исходный адрес неизменным? Согласно wirehark он изменен на адрес Виртуальный. Поэтому неудивительно, что виртуальная машина подключается к Виртуальный вместо того Рабочий.
Итак, решение невероятно простое:
Переместите Виртуальный в другую подсеть и установите его шлюз на IP-адрес Контейнер
Вот и все. Правила NAT, упомянутые в вопросе, верны.
Поскольку Рабочий и Виртуальный находились в одной подсети, Виртуальный подключен к Рабочий непосредственно при создании подключения к Рабочий который использует RSH, таким образом обходя NAT.
К сожалению, при отладке этой проблемы с помощью wirehark я сделал еще одну ошибку. Будучи настолько безнадежным, я изменил правила iptables на:
-t nat -A PREROUTING -j DNAT --to-destination 172.18.1.5
-t nat -A POSTROUTING -j SNAT --to-source 172.18.0.5
С такими правилами вроде бы частично работало, потому что внезапно Контейнер стал источником, благодаря которому начальное рукопожатие сработало. Однако он прервал соединение RSH с Виртуальный поскольку информация о том, что исходное соединение исходило от Рабочий было уже потеряно.