diff options
author | Harald Musum <musum@oath.com> | 2018-02-28 20:59:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-28 20:59:15 +0100 |
commit | d04a2219802988db5759dbc11fa5c74eb02f9581 (patch) | |
tree | 54aabf7b7c0480c4e2d382b44187f49e773cf59b /athenz-identity-provider-service/src | |
parent | a331136d15b76f4b81b4c5b778b2e090a784fbe8 (diff) |
Revert "Rewrite server TLS init to use bootstrap identity and allow AWS"
Diffstat (limited to 'athenz-identity-provider-service/src')
5 files changed, 52 insertions, 32 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java index d2ed3336c9a..beff50b52c6 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/AthenzSslKeyStoreConfigurator.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.athenz.instanceproviderservice; import com.google.inject.Inject; import com.yahoo.component.AbstractComponent; import com.yahoo.config.provision.Zone; -import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider; import com.yahoo.jdisc.http.ssl.SslKeyStoreConfigurator; import com.yahoo.jdisc.http.ssl.SslKeyStoreContext; import com.yahoo.log.LogLevel; @@ -36,6 +35,9 @@ import static com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.Utils.g @SuppressWarnings("unused") // Component injected into Jetty connector factory public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements SslKeyStoreConfigurator { private static final Logger log = Logger.getLogger(AthenzSslKeyStoreConfigurator.class.getName()); + // TODO Make expiry and update frequency configurable parameters + private static final Duration CERTIFICATE_EXPIRY_TIME = Duration.ofDays(30); + private static final Duration CERTIFICATE_UPDATE_PERIOD = Duration.ofDays(7); private static final String CERTIFICATE_ALIAS = "athenz"; private static final String CERTIFICATE_PASSWORD = "athenz"; @@ -44,20 +46,17 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements private final KeyProvider keyProvider; private final AthenzProviderServiceConfig.Zones zoneConfig; private final AtomicBoolean alreadyConfigured = new AtomicBoolean(); - private final Duration updatePeriod; private volatile KeyStore currentKeyStore; @Inject - public AthenzSslKeyStoreConfigurator(AthenzIdentityProvider bootstrapIdentity, - KeyProvider keyProvider, + public AthenzSslKeyStoreConfigurator(KeyProvider keyProvider, AthenzProviderServiceConfig config, Zone zone) { AthenzProviderServiceConfig.Zones zoneConfig = getZoneConfig(config, zone); - this.certificateClient = new AthenzCertificateClient(bootstrapIdentity, config, zoneConfig); + this.certificateClient = new AthenzCertificateClient(config, zoneConfig); this.keyProvider = keyProvider; this.zoneConfig = zoneConfig; this.currentKeyStore = downloadCertificate(keyProvider, certificateClient, zoneConfig); - this.updatePeriod = Duration.ofDays(config.updatePeriodDays()); } @Override @@ -67,9 +66,9 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements } sslKeyStoreContext.updateKeyStore(currentKeyStore, CERTIFICATE_PASSWORD); scheduler.scheduleAtFixedRate(new AthenzCertificateUpdater(sslKeyStoreContext), - updatePeriod.toDays()/*initial delay*/, - updatePeriod.toDays(), - TimeUnit.DAYS); + CERTIFICATE_UPDATE_PERIOD.toMinutes()/*initial delay*/, + CERTIFICATE_UPDATE_PERIOD.toMinutes(), + TimeUnit.MINUTES); } @Override @@ -93,10 +92,9 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements AthenzProviderServiceConfig.Zones zoneConfig) { try { PrivateKey privateKey = keyProvider.getPrivateKey(zoneConfig.secretVersion()); - X509Certificate certificate = certificateClient.updateCertificate(privateKey); - Instant expirationTime = certificate.getNotAfter().toInstant(); - Duration expiry = Duration.between(certificate.getNotBefore().toInstant(), expirationTime); - log.log(LogLevel.INFO, String.format("Got Athenz x509 certificate with expiry %s (expires %s)", expiry, expirationTime)); + X509Certificate certificate = certificateClient.updateCertificate(privateKey, CERTIFICATE_EXPIRY_TIME); + verifyActualExpiry(certificate); + KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(null); keyStore.setKeyEntry( @@ -107,6 +105,15 @@ public class AthenzSslKeyStoreConfigurator extends AbstractComponent implements } } + private static void verifyActualExpiry(X509Certificate certificate) { + Duration actualExpiry = + Duration.between(certificate.getNotBefore().toInstant(), certificate.getNotAfter().toInstant()); + if (CERTIFICATE_EXPIRY_TIME.compareTo(actualExpiry) > 0) { + log.log(LogLevel.WARNING, + String.format("Expected expiry %s, got %s", CERTIFICATE_EXPIRY_TIME, actualExpiry)); + } + } + private class AthenzCertificateUpdater implements Runnable { private final SslKeyStoreContext sslKeyStoreContext; diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java index eb1c6b09f0f..4dd6881c07e 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGenerator.java @@ -38,7 +38,7 @@ public class IdentityDocumentGenerator { this.nodeRepository = nodeRepository; this.zone = zone; this.keyProvider = keyProvider; - this.dnsSuffix = zoneConfig.certDnsSuffix(); + this.dnsSuffix = config.certDnsSuffix(); this.providerService = zoneConfig.serviceName(); this.ztsUrl = config.ztsUrl(); this.providerDomain = zoneConfig.domain(); diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/AthenzCertificateClient.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/AthenzCertificateClient.java index 381a8d236d1..c6aee673f9c 100644 --- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/AthenzCertificateClient.java +++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/AthenzCertificateClient.java @@ -6,10 +6,8 @@ import com.yahoo.athenz.auth.impl.SimpleServiceIdentityProvider; import com.yahoo.athenz.auth.util.Crypto; import com.yahoo.athenz.zts.InstanceRefreshRequest; import com.yahoo.athenz.zts.ZTSClient; -import com.yahoo.container.jdisc.athenz.AthenzIdentityProvider; import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig; -import javax.net.ssl.SSLContext; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.time.temporal.ChronoUnit; @@ -22,27 +20,41 @@ import java.util.concurrent.TimeUnit; public class AthenzCertificateClient { private final AthenzProviderServiceConfig config; + private final AthenzPrincipalAuthority authority; private final AthenzProviderServiceConfig.Zones zoneConfig; - private final AthenzIdentityProvider bootstrapIdentity; - public AthenzCertificateClient(AthenzIdentityProvider bootstrapIdentity, - AthenzProviderServiceConfig config, - AthenzProviderServiceConfig.Zones zoneConfig) { - this.bootstrapIdentity = bootstrapIdentity; + public AthenzCertificateClient(AthenzProviderServiceConfig config, AthenzProviderServiceConfig.Zones zoneConfig) { this.config = config; + this.authority = new AthenzPrincipalAuthority(config.athenzPrincipalHeaderName()); this.zoneConfig = zoneConfig; } - public X509Certificate updateCertificate(PrivateKey privateKey) { - SSLContext bootstrapSslContext = bootstrapIdentity.getIdentitySslContext(); - ZTSClient ztsClient = new ZTSClient(config.ztsUrl(), bootstrapSslContext); + public X509Certificate updateCertificate(PrivateKey privateKey, TemporalAmount expiryTime) { + SimpleServiceIdentityProvider identityProvider = new SimpleServiceIdentityProvider( + authority, zoneConfig.domain(), zoneConfig.serviceName(), + privateKey, Integer.toString(zoneConfig.secretVersion()), TimeUnit.MINUTES.toSeconds(10)); + ZTSClient ztsClient = new ZTSClient( + config.ztsUrl(), zoneConfig.domain(), zoneConfig.serviceName(), identityProvider); InstanceRefreshRequest req = ZTSClient.generateInstanceRefreshRequest( - zoneConfig.domain(), zoneConfig.serviceName(), privateKey, zoneConfig.certDnsSuffix(), /*expiryTime*/0); - req.setKeyId(Integer.toString(zoneConfig.secretVersion())); + zoneConfig.domain(), zoneConfig.serviceName(), privateKey, + config.certDnsSuffix(), (int)expiryTime.get(ChronoUnit.SECONDS)); String pemEncoded = ztsClient.postInstanceRefreshRequest(zoneConfig.domain(), zoneConfig.serviceName(), req) .getCertificate(); return Crypto.loadX509Certificate(pemEncoded); } + private static class AthenzPrincipalAuthority extends PrincipalAuthority { + private final String headerName; + + public AthenzPrincipalAuthority(String headerName) { + this.headerName = headerName; + } + + @Override + public String getHeader() { + return headerName; + } + } + } diff --git a/athenz-identity-provider-service/src/main/resources/configdefinitions/athenz-provider-service.def b/athenz-identity-provider-service/src/main/resources/configdefinitions/athenz-provider-service.def index 2cdbdf2c628..21f2aea6ab0 100644 --- a/athenz-identity-provider-service/src/main/resources/configdefinitions/athenz-provider-service.def +++ b/athenz-identity-provider-service/src/main/resources/configdefinitions/athenz-provider-service.def @@ -13,14 +13,14 @@ zones{}.secretName string # Secret version zones{}.secretVersion int -# Certificate DNS suffix -zones{}.certDnsSuffix string +# Athenz principal authority header name +athenzPrincipalHeaderName string default="Athenz-Principal-Auth" # Athenz ZTS server url ztsUrl string +# Certificate DNS suffix +certDnsSuffix string + # Path to Athenz CA JKS trust store athenzCaTrustStore string - -# Period between certificate updates -updatePeriodDays int default=5 diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/TestUtils.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/TestUtils.java index 5ae4b9f9bc5..da2bf929e82 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/TestUtils.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/TestUtils.java @@ -19,12 +19,13 @@ public class TestUtils { .serviceName(service) .secretVersion(0) .domain(domain) - .certDnsSuffix(dnsSuffix) .secretName("s3cr3t"); return new AthenzProviderServiceConfig( new AthenzProviderServiceConfig.Builder() .zones(ImmutableMap.of(zone.environment().value() + "." + zone.region().value(), zoneConfig)) + .certDnsSuffix(dnsSuffix) .ztsUrl("localhost/zts") + .athenzPrincipalHeaderName("Athenz-Principal-Auth") .athenzCaTrustStore("/dummy/path/to/athenz-ca.jks")); } |