aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/main')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java19
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java19
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java11
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/ConfiguredDirectSslProvider.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java18
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerServiceBuilder.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/Content.java2
7 files changed, 72 insertions, 11 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index 86c20bf96af..e8e12888768 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -24,6 +24,7 @@ import com.yahoo.config.model.provision.SingleNodeProvisioner;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.provision.Rotation;
import com.yahoo.config.provision.Zone;
+import com.yahoo.io.IOUtils;
import com.yahoo.io.reader.NamedReader;
import com.yahoo.searchdefinition.RankProfileRegistry;
import com.yahoo.searchdefinition.SearchBuilder;
@@ -39,8 +40,10 @@ import com.yahoo.vespa.model.container.search.SemanticRules;
import com.yahoo.vespa.model.search.SearchDefinition;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
+import java.io.UncheckedIOException;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
@@ -263,6 +266,22 @@ public class DeployState implements ConfigDefinitionStore {
public Optional<TlsSecrets> tlsSecrets() { return properties.tlsSecrets(); }
+ public Optional<String> tlsClientAuthority() {
+ var caFile = applicationPackage.getClientSecurityFile();
+ if (caFile.exists()) {
+ try {
+ var caPem = IOUtils.readAll(caFile.createReader());
+ return Optional.of(caPem);
+ } catch (FileNotFoundException e) {
+ return Optional.empty();
+ } catch (IOException e) {
+ throw new UncheckedIOException("Failed reading certificate from application: " + caFile.getPath(), e);
+ }
+ } else {
+ return Optional.empty();
+ }
+ }
+
public static class Builder {
private ApplicationPackage applicationPackage = MockApplicationPackage.createEmpty();
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
index d27812a80dd..82f0c87d074 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainer.java
@@ -26,11 +26,11 @@ public final class ApplicationContainer extends Container {
private final boolean isHostedVespa;
- public ApplicationContainer(AbstractConfigProducer parent, String name, int index, boolean isHostedVespa, Optional<TlsSecrets> tlsSecrets) {
- this(parent, name, false, index, isHostedVespa, tlsSecrets);
+ public ApplicationContainer(AbstractConfigProducer parent, String name, int index, boolean isHostedVespa, Optional<TlsSecrets> tlsSecrets, Optional<String> tlsCa) {
+ this(parent, name, false, index, isHostedVespa, tlsSecrets, tlsCa);
}
- public ApplicationContainer(AbstractConfigProducer parent, String name, boolean retired, int index, boolean isHostedVespa, Optional<TlsSecrets> tlsSecrets) {
+ public ApplicationContainer(AbstractConfigProducer parent, String name, boolean retired, int index, boolean isHostedVespa, Optional<TlsSecrets> tlsSecrets, Optional<String> tlsCa) {
super(parent, name, retired, index);
this.isHostedVespa = isHostedVespa;
@@ -40,8 +40,17 @@ public final class ApplicationContainer extends Container {
JettyHttpServer server = Optional.ofNullable(getHttp())
.map(Http::getHttpServer)
.orElse(getDefaultHttpServer());
- server.addConnector(new ConnectorFactory(connectorName, 4443,
- new ConfiguredDirectSslProvider(server.getComponentId().getName(), tlsSecrets.get().key(), tlsSecrets.get().certificate(), null, null)));
+
+ var sslProvider = new ConfiguredDirectSslProvider(
+ server.getComponentId().getName(),
+ tlsSecrets.get().key(),
+ tlsSecrets.get().certificate(),
+ null,
+ tlsCa.orElse(null),
+ null
+ );
+
+ server.addConnector(new ConnectorFactory(connectorName, 4443, sslProvider));
}
addComponent(getFS4ResourcePool()); // TODO Remove when FS4 based search protocol is gone
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index 473971c5e7a..2b9cd18d64b 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -56,6 +56,8 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
private ContainerModelEvaluation modelEvaluation;
private Optional<TlsSecrets> tlsSecrets;
+ private Optional<String> tlsClientAuthority;
+ private boolean useTlsClientAuthority = false;
private final boolean enableGroupingSessionCache;
private MbusParams mbusParams;
@@ -65,6 +67,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
super(parent, subId, name, deployState);
this.tlsSecrets = deployState.tlsSecrets();
+ this.tlsClientAuthority = deployState.tlsClientAuthority();
this.enableGroupingSessionCache = deployState.getProperties().enableGroupingSessionCache();
restApiGroup = new ConfigProducerGroup<>(this, "rest-api");
servletGroup = new ConfigProducerGroup<>(this, "servlet");
@@ -183,6 +186,10 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
return tlsSecrets;
}
+ public Optional<String> getTlsClientAuthority() {
+ return tlsClientAuthority;
+ }
+
public boolean enableGroupingSessionCache() {
return enableGroupingSessionCache;
}
@@ -205,6 +212,10 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
null))));
}
+ public void useTlsClientAuthority(boolean value) {
+ this.useTlsClientAuthority = value;
+ }
+
public static class MbusParams {
// the amount of the maxpendingbytes to process concurrently, typically 0.2 (20%)
final Double maxConcurrentFactor;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/ConfiguredDirectSslProvider.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/ConfiguredDirectSslProvider.java
index 28dba3331d3..b47aa501ece 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/ConfiguredDirectSslProvider.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/ssl/ConfiguredDirectSslProvider.java
@@ -26,9 +26,10 @@ public class ConfiguredDirectSslProvider extends SimpleComponent implements Conn
private final String privateKey;
private final String certificate;
private final String caCertificatePath;
+ private final String caCertificate;
private final ConnectorConfig.Ssl.ClientAuth.Enum clientAuthentication;
- public ConfiguredDirectSslProvider(String servername, String privateKey, String certificate, String caCertificatePath, String clientAuthentication) {
+ public ConfiguredDirectSslProvider(String servername, String privateKey, String certificate, String caCertificatePath, String caCertificate, String clientAuthentication) {
super(new ComponentModel(
new BundleInstantiationSpecification(new ComponentId(COMPONENT_ID_PREFIX+servername),
fromString(COMPONENT_CLASS),
@@ -36,6 +37,7 @@ public class ConfiguredDirectSslProvider extends SimpleComponent implements Conn
this.privateKey = privateKey;
this.certificate = certificate;
this.caCertificatePath = caCertificatePath;
+ this.caCertificate = caCertificate;
this.clientAuthentication = mapToConfigEnum(clientAuthentication);
}
@@ -45,6 +47,7 @@ public class ConfiguredDirectSslProvider extends SimpleComponent implements Conn
builder.ssl.privateKey(privateKey);
builder.ssl.certificate(certificate);
builder.ssl.caCertificateFile(Optional.ofNullable(caCertificatePath).orElse(""));
+ builder.ssl.caCertificate(Optional.ofNullable(caCertificate).orElse(""));
builder.ssl.clientAuth(clientAuthentication);
}
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 2bfb1da9dcb..00aa5423087 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
@@ -192,9 +192,21 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
addClientProviders(deployState, spec, cluster);
addServerProviders(deployState, spec, cluster);
+ addTlsClientAuthority(deployState, spec, cluster);
+
addAthensCopperArgos(cluster, context); // Must be added after nodes.
}
+ private void addTlsClientAuthority(DeployState deployState, Element spec, ApplicationContainerCluster cluster) {
+ var clientAuthorized = XML.getChild(spec, "client-authorize");
+ if (clientAuthorized != null) {
+ if (deployState.tlsClientAuthority().isEmpty()) {
+ throw new RuntimeException("client-authorize set, but security/clients.pem is missing");
+ }
+ cluster.useTlsClientAuthority(true);
+ }
+ }
+
private void addSecretStore(ApplicationContainerCluster cluster, Element spec) {
Element secretStoreElement = XML.getChild(spec, "secret-store");
if (secretStoreElement != null) {
@@ -440,7 +452,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
private void addStandaloneNode(ApplicationContainerCluster cluster) {
- ApplicationContainer container = new ApplicationContainer(cluster, "standalone", cluster.getContainers().size(), cluster.isHostedVespa(), cluster.getTlsSecrets());
+ ApplicationContainer container = new ApplicationContainer(cluster, "standalone", cluster.getContainers().size(), cluster.isHostedVespa(), cluster.getTlsSecrets(), cluster.getTlsClientAuthority());
cluster.addContainers(Collections.singleton(container));
}
@@ -506,7 +518,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
Element nodesElement = XML.getChild(containerElement, "nodes");
Element rotationsElement = XML.getChild(containerElement, "rotations");
if (nodesElement == null) { // default single node on localhost
- ApplicationContainer node = new ApplicationContainer(cluster, "container.0", 0, cluster.isHostedVespa(), cluster.getTlsSecrets());
+ ApplicationContainer node = new ApplicationContainer(cluster, "container.0", 0, cluster.isHostedVespa(), cluster.getTlsSecrets(), cluster.getTlsClientAuthority());
HostResource host = allocateSingleNodeHost(cluster, log, containerElement, context);
node.setHostResource(host);
node.initService(context.getDeployLogger());
@@ -695,7 +707,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
List<ApplicationContainer> nodes = new ArrayList<>();
for (Map.Entry<HostResource, ClusterMembership> entry : hosts.entrySet()) {
String id = "container." + entry.getValue().index();
- ApplicationContainer container = new ApplicationContainer(cluster, id, entry.getValue().retired(), entry.getValue().index(), cluster.isHostedVespa(), cluster.getTlsSecrets());
+ ApplicationContainer container = new ApplicationContainer(cluster, id, entry.getValue().retired(), entry.getValue().index(), cluster.isHostedVespa(), cluster.getTlsSecrets(), cluster.getTlsClientAuthority());
container.setHostResource(entry.getKey());
container.initService(deployLogger);
nodes.add(container);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerServiceBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerServiceBuilder.java
index 46271d3c0a2..c976a7fb153 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerServiceBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerServiceBuilder.java
@@ -22,7 +22,14 @@ public class ContainerServiceBuilder extends VespaDomBuilder.DomConfigProducerBu
@Override
protected ApplicationContainer doBuild(DeployState deployState, AbstractConfigProducer parent, Element nodeElem) {
- return new ApplicationContainer(parent, id, index, deployState.isHosted(), deployState.tlsSecrets());
+ return new ApplicationContainer(
+ parent,
+ id,
+ index,
+ deployState.isHosted(),
+ deployState.tlsSecrets(),
+ deployState.tlsClientAuthority()
+ );
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java
index 8eda707be99..f028f0ac0cc 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java
@@ -324,7 +324,7 @@ public class Content extends ConfigModel {
if (!processedHosts.contains(host)) {
String containerName = String.valueOf(searchNode.getDistributionKey());
ApplicationContainer docprocService = new ApplicationContainer(indexingCluster, containerName, index,
- modelContext.getDeployState().isHosted(), modelContext.getDeployState().tlsSecrets());
+ modelContext.getDeployState().isHosted(), modelContext.getDeployState().tlsSecrets(), Optional.empty());
index++;
docprocService.useDynamicPorts();
docprocService.setHostResource(host);