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

Получение реальных клиентских IP-адресов через IPv6 с HAProxy внутри Docker

В настоящее время у меня работает HAProxy в контейнере Docker. Докер просто работает на одном хосте с включенными IPv4 и IPv6. HAProxy - единственный контейнер с общими портами хоста, и только 80/443 проходят через брандмауэр на внешний / общедоступный интерфейс.

В настоящее время веб-трафик идет нормально. у меня есть forwardfor установлен в HAProxy, и мои серверы получат настоящий ClientIP для ведения журналов и аналитики .. за исключением IPv6. Хотя порт 80/443 отображается / транслируется докером таким образом, чтобы HAProxy получал реальный IP-адрес клиента на IPv4, все, что происходит через IPv6, каким-то образом переводится в IPv4! HAProxy получает частный адрес 172.17.0.1 в качестве IP-адреса клиента для всех подключений IPv6.

Мой daemon.json для Docker выглядит так:

{
    "tls": true,
    "tlsverify": true,
    "tlscacert": "/etc/docker/ca.pem",
    "tlscert": "/etc/docker/server.crt",
    "tlskey": "/etc/docker/server-key.pem",
    "ipv6": true,
    "fixed-cidr-v6": "2001:19f0:6001:1c12::/80",
    "hosts": ["127.0.0.1:2376", "10.10.6.10:2376", "fd://"]
}

Я назначил Докеру /80 из моей подсети IPv6. Я использую Vultr в качестве провайдера, и они назначают мне 2001:19f0:6001:1c12:: для моей подсети IPv6 и 2001:19f0:6001:1c12:5400:01ff:fe49:876e для моего IP-адреса хоста (машина с докером). Я также мой DEFAULT_FORWARD политика как ACCEPT в ufwи установите ndppd со следующей конфигурацией:

proxy ens3 {
  timeout 500
  ttl 30000
  rule 2001:19f0:6001:1c12::/80 {
    static
  }
}

Итак, с включенным IPv6 я понимаю, что все мои контейнеры получают свои собственные адреса IPv6. Итак, чтобы мой экземпляр HAProxy получил реальный IP-адрес клиента, мне нужно указать DNS на IPv6-адрес контейнера и открыть для него правило брандмауэра. Но проблема в том, что мне нужно, чтобы этот адрес был статическим. Конечно, это означает, что я не могу использовать мостовую сеть по умолчанию, и мне нужна сеть, определяемая пользователем.

Я понимаю, что должен был поступить именно так, но потом вспомнил, в чем была моя проблема. Я получаю следующее:

.gem/ruby/2.2.0/gems/docker-api-1.33.6/lib/docker/connection.rb:50:in `rescue in request': could not find an available, non-overlapping IPv6 address pool among the defaults to assign to the network (Docker::Error::ServerError)

Это из библиотеки Ruby Docker-API, но я получаю ту же ошибку с инструментом командной строки. Я пробовал различные части подсетей IPv6, но, похоже, ни одна из них не работает, и люди сказали мне, что у меня возникнут проблемы, если я буду использовать менее / 64.

Помните, исходная проблема заключается в том, что я не могу получить client-ip в журналах моего веб-сервера для соединений IPv6. Если есть более простой способ решить эту проблему, я открыт для этого. Если нет, то какие настройки мне нужно использовать для моей пользовательской сети? Хотел бы я просто удалить мост по умолчанию и использовать его диапазоны, но это не вариант. Могу ли я запретить мосту по умолчанию получать ту подсеть IPv6, которая определена в daemon.json и вместо этого использовать этот диапазон для моей пользовательской сети (а затем статически назначить только контейнер HAProxy, чтобы я мог использовать IP этого контейнера в записи DNS / AAAA?) Или есть более простой способ заставить порты хоста IPv6 подключаться напрямую к контейнер без трансляции точно так же, как делается IPv4?

В итоге мне пришлось создать пользовательскую сеть. После того, как я все отредактировал, я обнаружил Контейнер IPv6 NAT это могло привести к тому же результату, но я рад, что сделал это правильно, вместо того, чтобы пытаться использовать IPv6 NAT для его взлома.

Сначала я разделил диапазон IPv6, чтобы daemon.json получил следующее:

"fixed-cidr-v6": "2001:19f0:6001:1c12::1:0:0/96",

и моя пользовательская сеть получила 2001:19f0:6001:1c12::2:0:0/96. Я определил статический IPv6-адрес в ::2:0:0/96 подсеть и использовал этот IP, когда я создал свой контейнер с помощью Docker Engine API:

 ...
 "NetworkingConfig"=>
  {"EndpointsConfig"=>
    {"my-custom-network"=>
      {"IPAMConfig"=>{"IPv6Address"=>"2001:19f0:6001:1c12::2:0:1000"}}}},
 ...

Затем я установил свой AAAA записи в DNS на этот настраиваемый IPv6-адрес. Наконец, я убедился, что HAProxy прослушивает IPv4 и IPv6, используя bind :::80 v4v6 и bind :::443 v4v6 <insert cert stuff> варианты конфигурации.