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

доступ к веб-странице через URL-адрес в контейнере lxc

Я установил веб-сервер в контейнере lxc. К этому веб-серверу можно получить доступ из внешнего мира через его URL-адрес благодаря следующему правилу iptable:

sudo iptables -t nat -A PREROUTING -i eno1 -p tcp --dport 80 -j DNAT --to 10.42.XXX.XXX:80

Моя проблема в том, что когда я пытаюсь получить доступ к своему веб-серверу из контейнера lxc самого веб-сервера, он не работает.

curl http://my.url.com
curl: (7) Failed to connect to my.url.com port 80: Connection refused

Обратите внимание, что с другого компьютера он работает нормально.

Я попытался добавить еще одно правило iptable:

sudo iptables -t nat -A PREROUTING -i lxcbr0 -p tcp --dport 80 -j DNAT --to 10.42.XXX.XXX:80

и я получаю:

curl http://my.url.com
curl: (7) Failed to connect to my.url.com port 80: Connection timed out

Что происходит с добавленным вторым правилом PREROUTING, так это то, что контейнер получает свой собственный запрос, зеркально отображаемый сам с его собственным исходным IP-адресом в качестве источника (а также пункта назначения). Это невозможно по разным причинам: срабатывает rp_filter, сетевой стек не знает эту попытку подключения (он отправил ее на my.url.com, а не сам) и т.д. Если в той же локальной сети был второй контейнер, выполняющий запрос , по-прежнему будет проблема с асимметричной маршрутизацией + NAT, которая также помешает ей работать правильно.

Это не сработает без изменения также исходный адрес. Таким образом, в конце концов, необходимо сделать двойной NAT.

Этим правилом завершаем то, что уже было сделано:

sudo iptables -t nat -A POSTROUTING -o lxcbr0 -s 10.42.XXX.XXX -j SNAT 10.43.XXX.XXX

он будет работать правильно, потому что единственный случай IP 10.42.XXX.XXX - собирается lxcbr0 вместо из это когда сработало предыдущее правило PREROUTING DNAT. Обратите внимание, что это 43, а не 42 больше с 10.43.XXX.XXX. В журналах по-прежнему легко узнать, откуда поступил запрос, потому что это будет зарезервировано для этого случая. Любой IP может быть публичным, частным, существующим или нет, даже принадлежащим хосту LXC (например: my.url.com), если это не та же LAN и маршрутизируется хостом LXC.

В качестве варианта можно выполнить NAT для всей подсети с помощью NETMAP, позволяя другим контейнерам за lxcbr0 выполнять тот же запрос без проблем с маршрутизацией и по-прежнему иметь полезные журналы. Поэтому вместо предыдущего правила, которое было бы для / 24 (информация OP недостаточно точна, чтобы угадать, какая сетевая маска LAN. Замените ниже на 10.42.0.0/16 и 10.43.0.0/16 для / 16):

sudo iptables -t nat -A POSTROUTING -o lxcbr0 -s 10.42.XXX.0/24 -j NETMAP 10.43.XXX.0/24

По-прежнему существует проблема: с помощью второго правила OP в качестве теста контейнер (-ы) больше не может выполнять HTTP-запросы в Интернете, поскольку каждый запрос будет возвращаться к 10.42.XXX.XXX. Так что, в конце концов, было бы более полезно переписать и разложить на множители всего 3 таких правила, используя только эти 2 правила:

sudo iptables -t nat -A PREROUTING -d my.url.com -p tcp --dport 80 -j DNAT --to 10.42.XXX.XXX
sudo iptables -t nat -A POSTROUTING -o lxcbr0 -s 10.42.XXX.0/24 -j NETMAP --to 10.43.XXX.0/24

Завершите с этим, чтобы тот же запрос также работал с LXC хозяин сам:

sudo iptables -t nat -A OUTPUT -d my.url.com -p tcp --dport 80 -j DNAT --to 10.42.XXX.XXX

Более сложные случаи потребуют маркировки пакетов в PREROUTING и сопоставления с меткой в ​​POSTROUTING, но здесь это не требуется.