diff --git a/pkg/config/configmap.go b/pkg/config/configmap.go index 7a8ca62f5..7d2b581db 100644 --- a/pkg/config/configmap.go +++ b/pkg/config/configmap.go @@ -50,6 +50,9 @@ const ( // enableCryptoMB is the config map for enabling CryptoMB private key provider. enableCryptoMB = "enable-cryptomb" + // enableIPv6Listeners is the config map for enabling listeners on IPv6. + enableIPv6Listeners = "enable-ipv6-listeners" + // TracingCollectorFullEndpoint is the config map key to configure tracing at kourier gateway level TracingCollectorFullEndpoint = "tracing-collector-full-endpoint" ) @@ -63,6 +66,7 @@ func DefaultConfig() *Kourier { TrustedHopsCount: 0, CipherSuites: nil, EnableCryptoMB: false, + EnableIPv6Listeners: false, UseRemoteAddress: false, } } @@ -80,6 +84,7 @@ func NewConfigFromMap(configMap map[string]string) (*Kourier, error) { cm.AsBool(useRemoteAddress, &nc.UseRemoteAddress), cm.AsStringSet(cipherSuites, &nc.CipherSuites), cm.AsBool(enableCryptoMB, &nc.EnableCryptoMB), + cm.AsBool(enableIPv6Listeners, &nc.EnableIPv6Listeners), asTracing(TracingCollectorFullEndpoint, &nc.Tracing), ); err != nil { return nil, err @@ -157,6 +162,8 @@ type Kourier struct { // EnableCryptoMB specifies whether Kourier enable CryptoMB private provider to accelerate // TLS handshake. The default value is "false". EnableCryptoMB bool + // Create Listeners on ipv6. + EnableIPv6Listeners bool // CipherSuites specifies the cipher suites for TLS external listener. CipherSuites sets.Set[string] // Tracing specifies the configuration for gateway tracing diff --git a/pkg/envoy/api/listener.go b/pkg/envoy/api/listener.go index 06373fc13..61c04c313 100644 --- a/pkg/envoy/api/listener.go +++ b/pkg/envoy/api/listener.go @@ -48,7 +48,7 @@ type SNIMatch struct { } // NewHTTPListener creates a new Listener at the given port, backed by the given manager. -func NewHTTPListener(manager *hcm.HttpConnectionManager, port uint32, enableProxyProtocol bool) (*listener.Listener, error) { +func NewHTTPListener(manager *hcm.HttpConnectionManager, port uint32, enableProxyProtocol bool, enableIPv6Listeners bool) (*listener.Listener, error) { filters, err := createFilters(manager) if err != nil { return nil, err @@ -65,7 +65,7 @@ func NewHTTPListener(manager *hcm.HttpConnectionManager, port uint32, enableProx return &listener.Listener{ Name: CreateListenerName(port), - Address: createAddress(port), + Address: createAddress(port, enableIPv6Listeners), ListenerFilters: listenerFilter, FilterChains: []*listener.FilterChain{{ Filters: filters, @@ -74,7 +74,7 @@ func NewHTTPListener(manager *hcm.HttpConnectionManager, port uint32, enableProx } // NewHTTPSListener creates a new Listener at the given port with a given filter chain -func NewHTTPSListener(port uint32, filterChain []*listener.FilterChain, enableProxyProtocol bool) (*listener.Listener, error) { +func NewHTTPSListener(port uint32, filterChain []*listener.FilterChain, enableProxyProtocol bool, enableIPv6Listeners bool) (*listener.Listener, error) { var listenerFilter []*listener.ListenerFilter if enableProxyProtocol { proxyProtocolListenerFilter, err := createProxyProtocolListenerFilter() @@ -86,7 +86,7 @@ func NewHTTPSListener(port uint32, filterChain []*listener.FilterChain, enablePr return &listener.Listener{ Name: CreateListenerName(port), - Address: createAddress(port), + Address: createAddress(port, enableIPv6Listeners), ListenerFilters: listenerFilter, FilterChains: filterChain, }, nil @@ -159,7 +159,7 @@ func NewHTTPSListenerWithSNI(manager *hcm.HttpConnectionManager, port uint32, sn return &listener.Listener{ Name: CreateListenerName(port), - Address: createAddress(port), + Address: createAddress(port, kourierConfig.EnableIPv6Listeners), FilterChains: filterChains, ListenerFilters: listenerFilter, }, nil @@ -170,12 +170,18 @@ func CreateListenerName(port uint32) string { return fmt.Sprintf("listener_%d", port) } -func createAddress(port uint32) *core.Address { +func createAddress(port uint32, ipv6 bool) *core.Address { + var address string + if ipv6 { + address = "::" + } else { + address = "0.0.0.0" + } return &core.Address{ Address: &core.Address_SocketAddress{ SocketAddress: &core.SocketAddress{ Protocol: core.SocketAddress_TCP, - Address: "0.0.0.0", + Address: address, PortSpecifier: &core.SocketAddress_PortValue{ PortValue: port, }, diff --git a/pkg/envoy/api/listener_test.go b/pkg/envoy/api/listener_test.go index a086d3e45..157af030c 100644 --- a/pkg/envoy/api/listener_test.go +++ b/pkg/envoy/api/listener_test.go @@ -46,7 +46,7 @@ func TestNewHTTPListener(t *testing.T) { } manager := NewHTTPConnectionManager("test", &kourierConfig) - l, err := NewHTTPListener(manager, 8080, false) + l, err := NewHTTPListener(manager, 8080, false, false) assert.NilError(t, err) assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) @@ -66,7 +66,7 @@ func TestNewHTTPListenerWithProxyProtocol(t *testing.T) { } manager := NewHTTPConnectionManager("test", &kourierConfig) - l, err := NewHTTPListener(manager, 8080, true) + l, err := NewHTTPListener(manager, 8080, true, false) assert.NilError(t, err) assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) @@ -78,6 +78,24 @@ func TestNewHTTPListenerWithProxyProtocol(t *testing.T) { assertListenerHasProxyProtocolConfigured(t, l.ListenerFilters[0]) } +func TestNewHTTPListenerWithIPv6(t *testing.T) { + kourierConfig := config.Kourier{ + EnableIPv6Listeners: true, + IdleTimeout: 0 * time.Second, + } + manager := NewHTTPConnectionManager("test", &kourierConfig) + + l, err := NewHTTPListener(manager, 8080, false, true) + assert.NilError(t, err) + + assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) + assert.Equal(t, uint32(8080), l.Address.GetSocketAddress().GetPortValue()) + assert.Assert(t, is.Nil(l.FilterChains[0].TransportSocket)) // TLS not configured + + // Check if listening on ipv6 + assert.Equal(t, "::", l.Address.GetSocketAddress().Address) +} + var c = Certificate{ Certificate: []byte("some_certificate_chain"), PrivateKey: []byte("some_private_key"), @@ -101,7 +119,7 @@ func TestNewHTTPSListener(t *testing.T) { filterChain, err := CreateFilterChainFromCertificateAndPrivateKey(manager, &c) assert.NilError(t, err) - l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, false) + l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, false, false) assert.NilError(t, err) assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) @@ -141,7 +159,7 @@ func TestNewHTTPSListenerWithPrivatekeyProvider(t *testing.T) { filterChain, err := CreateFilterChainFromCertificateAndPrivateKey(manager, &crypto) assert.NilError(t, err) - l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, false) + l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, false, false) assert.NilError(t, err) assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) @@ -205,7 +223,7 @@ func TestNewHTTPSListenerWithProxyProtocol(t *testing.T) { filterChain, err := CreateFilterChainFromCertificateAndPrivateKey(manager, &c) assert.NilError(t, err) - l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, true) + l, err := NewHTTPSListener(8081, []*envoy_api_v3.FilterChain{filterChain}, true, false) assert.NilError(t, err) assert.Equal(t, core.SocketAddress_TCP, l.Address.GetSocketAddress().Protocol) diff --git a/pkg/generator/caches.go b/pkg/generator/caches.go index 787e68f8c..143217029 100644 --- a/pkg/generator/caches.go +++ b/pkg/generator/caches.go @@ -240,11 +240,11 @@ func generateListenersAndRouteConfigsAndClusters( externalTLSManager := envoy.NewHTTPConnectionManager(externalTLSRouteConfig.Name, cfg.Kourier) localManager := envoy.NewHTTPConnectionManager(localRouteConfig.Name, cfg.Kourier) - externalHTTPEnvoyListener, err := envoy.NewHTTPListener(externalManager, config.HTTPPortExternal, cfg.Kourier.EnableProxyProtocol) + externalHTTPEnvoyListener, err := envoy.NewHTTPListener(externalManager, config.HTTPPortExternal, cfg.Kourier.EnableProxyProtocol, cfg.Kourier.EnableIPv6Listeners) if err != nil { return nil, nil, nil, err } - localEnvoyListener, err := envoy.NewHTTPListener(localManager, config.HTTPPortLocal, false) + localEnvoyListener, err := envoy.NewHTTPListener(localManager, config.HTTPPortLocal, false, cfg.Kourier.EnableIPv6Listeners) if err != nil { return nil, nil, nil, err } @@ -254,7 +254,7 @@ func generateListenersAndRouteConfigsAndClusters( clusters := make([]cachetypes.Resource, 0, 1) // create probe listeners - probHTTPListener, err := envoy.NewHTTPListener(externalManager, config.HTTPPortProb, false) + probHTTPListener, err := envoy.NewHTTPListener(externalManager, config.HTTPPortProb, false, cfg.Kourier.EnableIPv6Listeners) if err != nil { return nil, nil, nil, err } @@ -372,7 +372,7 @@ func generateListenersAndRouteConfigsAndClusters( } // create https prob listener - probHTTPSListener, err := envoy.NewHTTPSListener(config.HTTPSPortProb, externalHTTPSEnvoyListener.FilterChains, false) + probHTTPSListener, err := envoy.NewHTTPSListener(config.HTTPSPortProb, externalHTTPSEnvoyListener.FilterChains, false, cfg.Kourier.EnableIPv6Listeners) if err != nil { return nil, nil, nil, err } @@ -454,7 +454,7 @@ func newExternalEnvoyListenerWithOneCert(ctx context.Context, manager *httpconnm return nil, err } - return envoy.NewHTTPSListener(config.HTTPSPortExternal, []*v3.FilterChain{filterChain}, cfg.EnableProxyProtocol) + return envoy.NewHTTPSListener(config.HTTPSPortExternal, []*v3.FilterChain{filterChain}, cfg.EnableProxyProtocol, cfg.EnableIPv6Listeners) } func newLocalEnvoyListenerWithOneCertFilterChain(ctx context.Context, manager *httpconnmanagerv3.HttpConnectionManager, kubeClient kubeclient.Interface, cfg *config.Kourier) (*v3.FilterChain, error) { @@ -475,7 +475,7 @@ func newLocalEnvoyListenerWithOneCert(ctx context.Context, manager *httpconnmana if err != nil { return nil, err } - return envoy.NewHTTPSListener(config.HTTPSPortLocal, []*v3.FilterChain{filterChain}, cfg.EnableProxyProtocol) + return envoy.NewHTTPSListener(config.HTTPSPortLocal, []*v3.FilterChain{filterChain}, cfg.EnableProxyProtocol, cfg.EnableIPv6Listeners) } func privateKeyProvider(mbEnabled bool) string {