aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2023-07-17 13:00:53 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2023-07-19 14:11:18 +0200
commit246a8599a9ed581f46fcd7a7924a6c1793cec626 (patch)
tree8e7af84e54f5f241f22a5c1c88ef7923dcd65f25 /config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java
parent3415a8a8065ee25cf9a644281a67eda777cbcdeb (diff)
Use builder pattern to make connector configuration more readable
Prepare for serving token endpoint on separate port
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/HostedSslConnectorFactory.java112
1 files changed, 44 insertions, 68 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 5bf348e5bb5..76014181558 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
@@ -3,7 +3,6 @@ package com.yahoo.vespa.model.container.http.ssl;
import com.yahoo.config.model.api.EndpointCertificateSecrets;
import com.yahoo.jdisc.http.ConnectorConfig;
-import com.yahoo.jdisc.http.ConnectorConfig.Ssl.ClientAuth;
import com.yahoo.security.tls.TlsContext;
import com.yahoo.vespa.model.container.http.ConnectorFactory;
@@ -18,96 +17,73 @@ import java.util.List;
*/
public class HostedSslConnectorFactory extends ConnectorFactory {
- private static final List<String> INSECURE_WHITELISTED_PATHS = List.of("/status.html");
- private static final String DEFAULT_HOSTED_TRUSTSTORE = "/opt/yahoo/share/ssl/certs/athenz_certificate_bundle.pem";
-
- private final boolean enforceClientAuth;
- private final boolean enforceHandshakeClientAuth;
- private final Collection<String> tlsCiphersOverride;
+ boolean requireTlsClientAuthDuringTlsHandshake;
+ private final List<String> tlsCiphersOverride;
private final boolean enableProxyProtocolMixedMode;
private final Duration endpointConnectionTtl;
- /**
- * Create connector factory that uses a certificate provided by the config-model / configserver and default hosted Vespa truststore.
- */
- public static HostedSslConnectorFactory withProvidedCertificate(
- String serverName, EndpointCertificateSecrets endpointCertificateSecrets, boolean enforceHandshakeClientAuth,
- Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode, int port,
- Duration endpointConnectionTtl, boolean enableTokenSupport) {
- CloudSslProvider sslProvider = createConfiguredDirectSslProvider(
- serverName, endpointCertificateSecrets, DEFAULT_HOSTED_TRUSTSTORE, /*tlsCaCertificates*/null, enforceHandshakeClientAuth, enableTokenSupport);
- return new HostedSslConnectorFactory(sslProvider, false, enforceHandshakeClientAuth, tlsCiphersOverride,
- enableProxyProtocolMixedMode, port, endpointConnectionTtl);
- }
-
- /**
- * Create connector factory that uses a certificate provided by the config-model / configserver and a truststore configured by the application.
- */
- public static HostedSslConnectorFactory withProvidedCertificateAndTruststore(
- String serverName, EndpointCertificateSecrets endpointCertificateSecrets, String tlsCaCertificates,
- Collection<String> tlsCiphersOverride, boolean enableProxyProtocolMixedMode, int port,
- Duration endpointConnectionTtl, boolean enableTokenSupport) {
- CloudSslProvider sslProvider = createConfiguredDirectSslProvider(
- serverName, endpointCertificateSecrets, /*tlsCaCertificatesPath*/null, tlsCaCertificates, false, enableTokenSupport);
- return new HostedSslConnectorFactory(sslProvider, true, false, tlsCiphersOverride, enableProxyProtocolMixedMode,
- port, endpointConnectionTtl);
- }
-
- /**
- * Create connector factory that uses the default certificate and truststore provided by Vespa (through Vespa-global TLS configuration).
- */
- public static HostedSslConnectorFactory withDefaultCertificateAndTruststore(String serverName, Collection<String> tlsCiphersOverride,
- boolean enableProxyProtocolMixedMode, int port,
- Duration endpointConnectionTtl) {
- return new HostedSslConnectorFactory(new DefaultSslProvider(serverName), true, false, tlsCiphersOverride,
- enableProxyProtocolMixedMode, port, endpointConnectionTtl);
- }
+ public static Builder builder(String name, int listenPort) { return new Builder(name, listenPort); }
- private HostedSslConnectorFactory(SslProvider sslProvider, boolean enforceClientAuth,
- boolean enforceHandshakeClientAuth, Collection<String> tlsCiphersOverride,
- boolean enableProxyProtocolMixedMode, int port, Duration endpointConnectionTtl) {
- super(new Builder("tls"+port, port).sslProvider(sslProvider));
- this.enforceClientAuth = enforceClientAuth;
- this.enforceHandshakeClientAuth = enforceHandshakeClientAuth;
- this.tlsCiphersOverride = tlsCiphersOverride;
- this.enableProxyProtocolMixedMode = enableProxyProtocolMixedMode;
- this.endpointConnectionTtl = endpointConnectionTtl;
+ private HostedSslConnectorFactory(Builder builder) {
+ super(new ConnectorFactory.Builder("tls"+builder.port, builder.port).sslProvider(createSslProvider(builder)));
+ this.requireTlsClientAuthDuringTlsHandshake = builder.requireTlsClientAuthDuringTlsHandshake;
+ this.tlsCiphersOverride = List.copyOf(builder.tlsCiphersOverride);
+ this.enableProxyProtocolMixedMode = builder.enableProxyProtocolMixedMode;
+ this.endpointConnectionTtl = builder.endpointConnectionTtl;
}
- private static CloudSslProvider createConfiguredDirectSslProvider(
- String serverName, EndpointCertificateSecrets endpointCertificateSecrets, String tlsCaCertificatesPath, String tlsCaCertificates, boolean enforceHandshakeClientAuth, boolean enableTokenSupport) {
- var clientAuthentication = enforceHandshakeClientAuth ? ClientAuth.Enum.NEED_AUTH : ClientAuth.Enum.WANT_AUTH;
+ private static SslProvider createSslProvider(Builder builder) {
+ if (builder.endpointCertificate == null) return new DefaultSslProvider(builder.name);
+ var clientAuthentication = builder.requireTlsClientAuthDuringTlsHandshake
+ ? ConnectorConfig.Ssl.ClientAuth.Enum.NEED_AUTH : ConnectorConfig.Ssl.ClientAuth.Enum.WANT_AUTH;
return new CloudSslProvider(
- serverName,
- endpointCertificateSecrets.key(),
- endpointCertificateSecrets.certificate(),
- tlsCaCertificatesPath,
- tlsCaCertificates,
- clientAuthentication,
- enableTokenSupport);
+ builder.name, builder.endpointCertificate.key(), builder.endpointCertificate.certificate(),
+ builder.tlsCaCertificatesPath, builder.tlsCaCertificatesPem, clientAuthentication, builder.tokenEndpoint);
}
@Override
public void getConfig(ConnectorConfig.Builder connectorBuilder) {
super.getConfig(connectorBuilder);
- if (! enforceHandshakeClientAuth) {
- connectorBuilder
- .tlsClientAuthEnforcer(new ConnectorConfig.TlsClientAuthEnforcer.Builder()
- .pathWhitelist(INSECURE_WHITELISTED_PATHS)
- .enable(enforceClientAuth));
+ if (! requireTlsClientAuthDuringTlsHandshake) {
+ connectorBuilder.tlsClientAuthEnforcer(
+ new ConnectorConfig.TlsClientAuthEnforcer.Builder()
+ .pathWhitelist(List.of("/status.html")).enable(true));
}
// Disables TLSv1.3 as it causes some browsers to prompt user for client certificate (when connector has 'want' auth)
connectorBuilder.ssl.enabledProtocols(List.of("TLSv1.2"));
-
if (!tlsCiphersOverride.isEmpty()) {
connectorBuilder.ssl.enabledCipherSuites(tlsCiphersOverride.stream().sorted().toList());
} else {
connectorBuilder.ssl.enabledCipherSuites(TlsContext.ALLOWED_CIPHER_SUITES.stream().sorted().toList());
}
-
connectorBuilder
.proxyProtocol(new ConnectorConfig.ProxyProtocol.Builder().enabled(true).mixedMode(enableProxyProtocolMixedMode))
.idleTimeout(Duration.ofSeconds(30).toSeconds())
.maxConnectionLife(endpointConnectionTtl != null ? endpointConnectionTtl.toSeconds() : 0);
}
+
+ public static class Builder {
+ final String name;
+ final int port;
+ boolean requireTlsClientAuthDuringTlsHandshake;
+ List<String> tlsCiphersOverride;
+ boolean enableProxyProtocolMixedMode;
+ Duration endpointConnectionTtl;
+ EndpointCertificateSecrets endpointCertificate;
+ String tlsCaCertificatesPem;
+ String tlsCaCertificatesPath;
+ boolean tokenEndpoint;
+
+ private Builder(String name, int port) { this.name = name; this.port = port; }
+ public Builder requireTlsClientAuthDuringTlsHandshake(boolean enable) {this.requireTlsClientAuthDuringTlsHandshake = enable; return this; }
+ public Builder endpointConnectionTtl(Duration ttl) { endpointConnectionTtl = ttl; return this; }
+ public Builder tlsCiphersOverride(Collection<String> ciphers) { tlsCiphersOverride = List.copyOf(ciphers); return this; }
+ public Builder proxyProtocolMixedMode(boolean enable) { enableProxyProtocolMixedMode = enable; return this; }
+ public Builder endpointCertificate(EndpointCertificateSecrets cert) { this.endpointCertificate = cert; return this; }
+ public Builder tlsCaCertificatesPath(String path) { this.tlsCaCertificatesPath = path; return this; }
+ public Builder tlsCaCertificatesPem(String pem) { this.tlsCaCertificatesPem = pem; return this; }
+ public Builder tokenEndpoint(boolean enable) { this.tokenEndpoint = enable; return this; }
+
+ public HostedSslConnectorFactory build() { return new HostedSslConnectorFactory(this); }
+ }
}