diff --git a/command/agent/consul/connect.go b/command/agent/consul/connect.go index e70e66af08a..79ae8668681 100644 --- a/command/agent/consul/connect.go +++ b/command/agent/consul/connect.go @@ -154,7 +154,7 @@ func connectSidecarProxy(info structs.AllocInfo, proxy *structs.ConsulProxy, cPo Mode: mode, LocalServiceAddress: proxy.LocalServiceAddress, LocalServicePort: proxy.LocalServicePort, - Config: connectProxyConfig(proxy.Config, cPort, info), + Config: connectProxyConfig(proxy.Config, cPort, info, networks), Upstreams: connectUpstreams(proxy.Upstreams), Expose: expose, }, nil @@ -243,11 +243,13 @@ func connectMeshGateway(in structs.ConsulMeshGateway) api.MeshGatewayConfig { return gw } -func connectProxyConfig(cfg map[string]interface{}, port int, info structs.AllocInfo) map[string]interface{} { +func connectProxyConfig(cfg map[string]interface{}, port int, info structs.AllocInfo, networks structs.Networks) map[string]interface{} { if cfg == nil { cfg = make(map[string]interface{}) } - cfg["bind_address"] = "0.0.0.0" + if _, ok := cfg["bind_address"]; !ok { + cfg["bind_address"] = connectProxyBindAddress(networks) + } cfg["bind_port"] = port tags := map[string]string{ @@ -260,6 +262,15 @@ func connectProxyConfig(cfg map[string]interface{}, port int, info structs.Alloc return cfg } +func connectProxyBindAddress(networks structs.Networks) string { + for _, n := range networks { + if n.Mode == "bridge" && n.IsIPv6() { + return "::" + } + } + return "0.0.0.0" +} + // injectNomadInfo merges nomad information into cfg=>envoy_stats_tags // // cfg must not be nil diff --git a/command/agent/consul/connect_test.go b/command/agent/consul/connect_test.go index 49b096bd093..72ef5436d4b 100644 --- a/command/agent/consul/connect_test.go +++ b/command/agent/consul/connect_test.go @@ -409,22 +409,44 @@ func TestConnect_connectProxyConfig(t *testing.T) { ci.Parallel(t) t.Run("nil map", func(t *testing.T) { - require.Equal(t, map[string]interface{}{ + must.Eq(t, map[string]any{ "bind_address": "0.0.0.0", "bind_port": 42, "envoy_stats_tags": []string{"nomad.alloc_id=test_alloc1"}, - }, connectProxyConfig(nil, 42, structs.AllocInfo{AllocID: "test_alloc1"})) + }, connectProxyConfig(nil, 42, structs.AllocInfo{AllocID: "test_alloc1"}, nil)) }) t.Run("pre-existing map", func(t *testing.T) { - require.Equal(t, map[string]interface{}{ + must.Eq(t, map[string]any{ "bind_address": "0.0.0.0", "bind_port": 42, "foo": "bar", "envoy_stats_tags": []string{"nomad.alloc_id=test_alloc2"}, - }, connectProxyConfig(map[string]interface{}{ + }, connectProxyConfig(map[string]any{ "foo": "bar", - }, 42, structs.AllocInfo{AllocID: "test_alloc2"})) + }, 42, structs.AllocInfo{AllocID: "test_alloc2"}, nil)) + }) + + t.Run("bind_address override", func(t *testing.T) { + must.Eq(t, map[string]any{ + "bind_address": "anything", + "bind_port": 42, + "envoy_stats_tags": []string{"nomad.alloc_id=custom_bind_alloc"}, + }, connectProxyConfig(map[string]any{ + "bind_address": "anything", + }, 42, structs.AllocInfo{AllocID: "custom_bind_alloc"}, nil)) + }) + + t.Run("bind_address ipv6", func(t *testing.T) { + must.Eq(t, map[string]any{ + "bind_address": "::", + "bind_port": 42, + "envoy_stats_tags": []string{"nomad.alloc_id=ipv6_alloc"}, + }, connectProxyConfig(map[string]any{ + "bind_address": "::", + }, 42, structs.AllocInfo{AllocID: "ipv6_alloc"}, []*structs.NetworkResource{ + {Mode: "bridge", IP: "fd00:a110:c8::1"}, + })) }) } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index d29a2ae7692..ee505b46049 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -3037,6 +3037,11 @@ func (n *NetworkResource) PortLabels() map[string]int { return labelValues } +func (n *NetworkResource) IsIPv6() bool { + ip := net.ParseIP(n.IP) + return ip != nil && ip.To4() == nil +} + // Networks defined for a task on the Resources struct. type Networks []*NetworkResource