diff options
author | Morten Tokle <mortent@yahooinc.com> | 2023-10-23 15:22:17 +0200 |
---|---|---|
committer | Morten Tokle <mortent@yahooinc.com> | 2023-10-23 15:22:17 +0200 |
commit | ca2087c3711ff4514d44a272b2a1798877e9873a (patch) | |
tree | bdd1ef83d4adc35836ccbfb1fac0319e575f85f7 | |
parent | f70f96660c1cfc53fda1a69efa7e8d61a2402373 (diff) |
Only report known dimension values
7 files changed, 61 insertions, 6 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java index c75aca7a5fa..20c3826721b 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java @@ -10,6 +10,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; /** * Component specification for {@link com.yahoo.jdisc.http.server.jetty.ConnectorFactory} with hosted specific configuration. @@ -25,6 +26,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { private final Duration endpointConnectionTtl; private final List<String> remoteAddressHeaders; private final List<String> remotePortHeaders; + private final Set<String> knownServerNames; public static Builder builder(String name, int listenPort) { return new Builder(name, listenPort); } @@ -37,6 +39,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { this.endpointConnectionTtl = builder.endpointConnectionTtl; this.remoteAddressHeaders = List.copyOf(builder.remoteAddressHeaders); this.remotePortHeaders = List.copyOf(builder.remotePortHeaders); + this.knownServerNames = Set.copyOf(builder.knownServerNames); } private static SslProvider createSslProvider(Builder builder) { @@ -70,7 +73,8 @@ public class HostedSslConnectorFactory extends ConnectorFactory { .maxConnectionLife(endpointConnectionTtl != null ? endpointConnectionTtl.toSeconds() : 0) .accessLog(new ConnectorConfig.AccessLog.Builder() .remoteAddressHeaders(remoteAddressHeaders) - .remotePortHeaders(remotePortHeaders)); + .remotePortHeaders(remotePortHeaders)) + .serverName.known(knownServerNames); } @@ -89,6 +93,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { String tlsCaCertificatesPem; String tlsCaCertificatesPath; boolean tokenEndpoint; + Set<String> knownServerNames = Set.of(); private Builder(String name, int port) { this.name = name; this.port = port; } public Builder clientAuth(SslClientAuth auth) { clientAuth = auth; return this; } @@ -101,7 +106,7 @@ public class HostedSslConnectorFactory extends ConnectorFactory { public Builder tokenEndpoint(boolean enable) { this.tokenEndpoint = enable; return this; } public Builder remoteAddressHeader(String header) { this.remoteAddressHeaders.add(header); return this; } public Builder remotePortHeader(String header) { this.remotePortHeaders.add(header); return this; } - + public Builder knownServerNames(Set<String> knownServerNames) { this.knownServerNames = Set.copyOf(knownServerNames); return this; } public HostedSslConnectorFactory build() { return new HostedSslConnectorFactory(this); } } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 2093d0cfbe3..18020f5df5d 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -606,6 +606,11 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { var endpointCert = state.endpointCertificateSecrets().orElse(null); if (endpointCert != null) { builder.endpointCertificate(endpointCert); + Set<String> mtlsEndpointNames = state.getEndpoints().stream() + .filter(endpoint -> endpoint.authMethod() == ApplicationClusterEndpoint.AuthMethod.mtls) + .flatMap(endpoint -> endpoint.names().stream()) + .collect(Collectors.toSet()); + builder.knownServerNames(mtlsEndpointNames); boolean isPublic = state.zone().system().isPublic(); List<X509Certificate> clientCertificates = getClientCertificates(cluster); if (isPublic) { @@ -659,6 +664,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { .remoteAddressHeader("X-Forwarded-For") .remotePortHeader("X-Forwarded-Port") .clientAuth(SslClientAuth.NEED) + .knownServerNames(tokenEndpoints) .build(); server.addConnector(connector); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java index 937052df122..49ed1972afe 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudDataPlaneFilterTest.java @@ -1,6 +1,8 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container.xml; +import com.yahoo.config.model.api.ApplicationClusterEndpoint; +import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.EndpointCertificateSecrets; import com.yahoo.config.model.builder.xml.test.DomBuilderTest; import com.yahoo.config.model.deploy.DeployState; @@ -38,6 +40,7 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Optional; +import java.util.Set; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -91,6 +94,7 @@ public class CloudDataPlaneFilterTest extends ContainerModelBuilderTestBase { var caCerts = X509CertificateUtils.certificateListFromPem(connectorConfig.ssl().caCertificate()); assertEquals(1, caCerts.size()); assertEquals(List.of(certificate), caCerts); + assertEquals(List.of("foo.bar"), connectorConfig.serverName().known()); var srvCfg = root.getConfig(ServerConfig.class, "container/http"); assertEquals("cloud-data-plane-insecure", srvCfg.defaultFilters().get(0).filterId()); assertEquals(8080, srvCfg.defaultFilters().get(0).localPort()); @@ -191,6 +195,7 @@ public class CloudDataPlaneFilterTest extends ContainerModelBuilderTestBase { .setEndpointCertificateSecrets(Optional.of(new EndpointCertificateSecrets("CERT", "KEY"))) .setHostedVespa(true)) .zone(new Zone(SystemName.PublicCd, Environment.dev, RegionName.defaultName())) + .endpoints(Set.of(new ContainerEndpoint("foo", ApplicationClusterEndpoint.Scope.zone, List.of("foo.bar")))) .build(); return createModel(root, state, null, clusterElem); } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudTokenDataPlaneFilterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudTokenDataPlaneFilterTest.java index 1642e0ff8f2..c89ea421b39 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudTokenDataPlaneFilterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/CloudTokenDataPlaneFilterTest.java @@ -14,9 +14,12 @@ import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; import com.yahoo.config.provision.Zone; +import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.filter.security.cloud.config.CloudTokenDataPlaneFilterConfig; import com.yahoo.processing.response.Data; +import com.yahoo.vespa.model.container.ApplicationContainer; import com.yahoo.vespa.model.container.ContainerModel; +import com.yahoo.vespa.model.container.http.ConnectorFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -127,6 +130,21 @@ public class CloudTokenDataPlaneFilterTest extends ContainerModelBuilderTestBase assertFalse(root.getConfigIds().stream().anyMatch(id -> id.contains("DataplaneProxyConfigurator"))); } + @Test + void configuresCorrectConnectors() throws IOException { + var certFile = securityFolder.resolve("foo.pem"); + var clusterElem = DomBuilderTest.parse(servicesXmlTemplate.formatted(applicationFolder.toPath().relativize(certFile).toString())); + createCertificate(certFile); + buildModel(Set.of(tokenEndpoint, mtlsEndpoint), defaultTokens, clusterElem); + + ConnectorConfig connectorConfig8443 = connectorConfig(8443); + assertEquals(List.of("mtls"),connectorConfig8443.serverName().known()); + + ConnectorConfig connectorConfig8444 = connectorConfig(8444); + assertEquals(List.of("token"),connectorConfig8444.serverName().known()); + + } + private static CloudTokenDataPlaneFilterConfig.Clients.Tokens tokenConfig( String id, Collection<String> fingerprints, Collection<String> accessCheckHashes, Collection<String> expirations) { return new CloudTokenDataPlaneFilterConfig.Clients.Tokens.Builder() @@ -150,4 +168,15 @@ public class CloudTokenDataPlaneFilterTest extends ContainerModelBuilderTestBase .build(); return createModel(root, state, null, clusterElem); } + + private ConnectorConfig connectorConfig(int port) { + ApplicationContainer container = (ApplicationContainer) root.getProducer("container/container.0"); + List<ConnectorFactory> connectorFactories = container.getHttp().getHttpServer().get().getConnectorFactories(); + ConnectorFactory tlsPort = connectorFactories.stream().filter(connectorFactory -> connectorFactory.getListenPort() == port).findFirst().orElseThrow(); + + ConnectorConfig.Builder builder = new ConnectorConfig.Builder(); + tlsPort.getConfig(builder); + + return new ConnectorConfig(builder); + } } diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 2b5e4386e94..f29c4c2a8f7 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -1261,10 +1261,13 @@ "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder fallback(java.lang.String)", "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder allowed(java.lang.String)", "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder allowed(java.util.Collection)", + "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder known(java.lang.String)", + "public com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder known(java.util.Collection)", "public com.yahoo.jdisc.http.ConnectorConfig$ServerName build()" ], "fields" : [ - "public java.util.List allowed" + "public java.util.List allowed", + "public java.util.List known" ] }, "com.yahoo.jdisc.http.ConnectorConfig$ServerName" : { @@ -1278,7 +1281,9 @@ "public void <init>(com.yahoo.jdisc.http.ConnectorConfig$ServerName$Builder)", "public java.lang.String fallback()", "public java.util.List allowed()", - "public java.lang.String allowed(int)" + "public java.lang.String allowed(int)", + "public java.util.List known()", + "public java.lang.String known(int)" ], "fields" : [ ] }, diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java index e699b9f200c..983adec034d 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/JDiscServerConnector.java @@ -11,8 +11,8 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Optional; /** * @author bjorncs @@ -26,6 +26,7 @@ class JDiscServerConnector extends ServerConnector { private final Metric metric; private final String connectorName; private final int listenPort; + private final List<String> knownServerNames; JDiscServerConnector(ConnectorConfig config, Metric metric, Server server, JettyConnectionLogger connectionLogger, ConnectionMetricAggregator connectionMetricAggregator, ConnectionFactory... factories) { @@ -35,6 +36,7 @@ class JDiscServerConnector extends ServerConnector { this.connectorName = config.name(); this.listenPort = config.listenPort(); this.metricCtx = metric.createContext(createConnectorDimensions(listenPort, connectorName, 0)); + this.knownServerNames = List.copyOf(config.serverName().known()); this.statistics = new ConnectionStatistics(); setAcceptedTcpNoDelay(config.tcpNoDelay()); @@ -69,7 +71,7 @@ class JDiscServerConnector extends ServerConnector { dimensions.put(MetricDefinitions.SCHEME_DIMENSION, scheme); dimensions.put(MetricDefinitions.CLIENT_AUTHENTICATED_DIMENSION, Boolean.toString(clientAuthenticated)); dimensions.put(MetricDefinitions.PROTOCOL_DIMENSION, request.getProtocol()); - String serverName = Optional.ofNullable(request.getServerName()).orElse("unknown"); + String serverName = knownServerNames.stream().filter(name -> name.equalsIgnoreCase(request.getServerName())).findFirst().orElse("unknown"); dimensions.put(MetricDefinitions.REQUEST_SERVER_NAME_DIMENSION, serverName); dimensions.putAll(extraDimensions); return metric.createContext(dimensions); diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def index c1c0944d7eb..b4a513e0de8 100644 --- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def +++ b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.connector.def @@ -139,6 +139,9 @@ serverName.fallback string default="" # The list of accepted server names. Empty list to accept any. Elements follows format of 'serverName.default'. serverName.allowed[] string +# The list of known server names. Used for e.g matching metric dimensions. +serverName.known[] string + # HTTP request headers that contain remote address accessLog.remoteAddressHeaders[] string |