Почему Google Computer Engine привязывает мою программу к портам IPv6?

Почему Google Computer Engine привязывает мою программу к портам IPv6?

Я пишу сервер, который привязывается к нескольким локальным портам (включая 80и 443). Всякий раз, когда я запускаю его на Google Computer Engine (GCE), используя их Container-Optimized OS (COS) и контейнер Docker, порты привязываются к IPv6, а не к IPv4.

$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 127.0.0.1:36265         0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::443                  :::*                    LISTEN
udp        0      0 10.128.0.33:68          0.0.0.0:*

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

Как указать экземпляру GCE использовать порт IPv4?

решение1

Редактировать

Следует отметить одну важную вещь (как указано в комментариях):- хотя маршрутизация IPv6 может быть привязана к интерфейсу, использующему как IPv4, так и IPv6, она не будет работать в Google Cloud (пока не поддерживается внутренне).


Итак, оказывается, что это сбивающая с толку «функция» того, как Docker работает в сети, и она по-прежнему должна разрешать соединения IPv4 наряду с IPv6.

Видетьэтот ответ StackOverflowдля более подробной информации. Я процитировал ответ ниже для потомков:

...github.com/docker/docker/issues/2174это о том, чтобы показать привязку только к IPv6 в netstat, но это не проблема. Как гласит этот github issues:

При настройке прокси Docker запрашивает адрес обратной связи '127.0.0.1', Linux понимает, что это адрес, который существует в IPv6 (как ::0) и открывается на обоих (но формально это сокет IPv6). Когда вы запускаете netstat, он видит это и сообщает вам, что это IPv6, но он все еще слушает на IPv4. Если вы немного поигрались с настройками, вы могли отключить этот трюк, который делает Linux, установив net.ipv6.bindv6only = 1.

Другими словами, просто потому, что вы видите его как IPv6 только, он все равно может общаться по IPv4, если только вы не настроили IPv6 только на привязку к IPv6 с помощью настройки net.ipv6.bindv6only. Для ясности, net.ipv6.bindv6only должен быть 0 — вы можете запустить sysctl net.ipv6.bindv6onlyдля проверки.

Связанный контент