我目前在 Docker 容器中运行 HAProxy。Docker 仅在启用了 IPv4 和 IPv6 的一台主机上运行。HAProxy 是唯一共享主机端口的容器,并且只有 80/443 通过外部/公共接口上的防火墙。
目前,网络流量正常。我已forwardfor
在 HAProxy 中设置,我的后端获取了用于日志记录和分析的真实 ClientIP……IPv6 除外。尽管端口 80/443 已由 docker 映射/转换,以便 HAProxy 获取 IPv4 上的真实客户端 IP,但 IPv6 上的任何内容都会以某种方式转换为 IPv4!HAProxy 获取私有 172.17.0.1 地址作为所有 IPv6 连接的客户端 IP。
我的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://"]
}
我已经从我的 IPv6 子网中分配了 Docker /80
。我使用 Vultr 作为提供商,他们2001:19f0:6001:1c12::
为我分配了我的 IPv6 子网和2001:19f0:6001:1c12:5400:01ff:fe49:876e
主机 IP 地址(运行 docker 的机器)。我的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 的子网,就会遇到问题。
记住,最初的问题是我无法在我的 Web 服务器日志中获取 IPv6 连接的客户端 IP。如果有更简单的方法可以解决这个问题,我很乐意接受。如果没有,我需要对我的用户定义网络使用什么设置?我希望我可以删除默认网桥并使用其范围,但这似乎不是一个选择。我是否可以阻止默认网桥获取在中定义的 IPv6 子网,daemon.json
而是将该范围用于我的用户定义网络(然后静态分配 HAProxy 容器,以便我可以在 DNS/AAAA 记录中使用该容器的 IP?)或者是否有更简单的方法让 IPv6 主机端口直接连接到容器而无需像 IPv4 那样进行转换?
答案1
我最终不得不创建一个用户定义的网络。在我重构了所有内容之后,我发现了一个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
,并在使用 Docker Engine API 创建容器时使用了该 IP:
...
"NetworkingConfig"=>
{"EndpointsConfig"=>
{"my-custom-network"=>
{"IPAMConfig"=>{"IPv6Address"=>"2001:19f0:6001:1c12::2:0:1000"}}}},
...
然后我将AAAA
DNS 中的记录设置为该自定义 IPv6 地址。最后,我确保 HAProxy 使用配置选项bind :::80 v4v6
监听IPv4 和 IPv6。bind :::443 v4v6 <insert cert stuff>