mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Read GCP proxy EPP SSL secret from GCS
This allows us to not ship the proxy with certificates/private keys. The secret is still encrypted by KMS. Reading the secret only happens once when the first EPP request comes in, which should not incur any tangible performance penalty. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=191771680
This commit is contained in:
parent
18a145eef1
commit
983bd27ee0
7 changed files with 55 additions and 12 deletions
|
@ -27,6 +27,7 @@ java_library(
|
||||||
"@com_google_api_client",
|
"@com_google_api_client",
|
||||||
"@com_google_apis_google_api_services_cloudkms",
|
"@com_google_apis_google_api_services_cloudkms",
|
||||||
"@com_google_apis_google_api_services_monitoring",
|
"@com_google_apis_google_api_services_monitoring",
|
||||||
|
"@com_google_apis_google_api_services_storage",
|
||||||
"@com_google_auto_value",
|
"@com_google_auto_value",
|
||||||
"@com_google_code_findbugs_jsr305",
|
"@com_google_code_findbugs_jsr305",
|
||||||
"@com_google_dagger",
|
"@com_google_dagger",
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class ProxyConfig {
|
||||||
public List<String> gcpScopes;
|
public List<String> gcpScopes;
|
||||||
public int accessTokenValidPeriodSeconds;
|
public int accessTokenValidPeriodSeconds;
|
||||||
public int accessTokenRefreshBeforeExpirySeconds;
|
public int accessTokenRefreshBeforeExpirySeconds;
|
||||||
public String sslPemFilename;
|
public Gcs gcs;
|
||||||
public Kms kms;
|
public Kms kms;
|
||||||
public Epp epp;
|
public Epp epp;
|
||||||
public Whois whois;
|
public Whois whois;
|
||||||
|
@ -45,6 +45,12 @@ public class ProxyConfig {
|
||||||
public HttpsRelay httpsRelay;
|
public HttpsRelay httpsRelay;
|
||||||
public Metrics metrics;
|
public Metrics metrics;
|
||||||
|
|
||||||
|
/** Configuration options that apply to GCS. */
|
||||||
|
public static class Gcs {
|
||||||
|
public String bucket;
|
||||||
|
public String sslPemFilename;
|
||||||
|
}
|
||||||
|
|
||||||
/** Configuration options that apply to Cloud KMS. */
|
/** Configuration options that apply to Cloud KMS. */
|
||||||
public static class Kms {
|
public static class Kms {
|
||||||
public String location;
|
public String location;
|
||||||
|
|
|
@ -16,7 +16,6 @@ package google.registry.proxy;
|
||||||
|
|
||||||
import static com.google.common.base.Suppliers.memoizeWithExpiration;
|
import static com.google.common.base.Suppliers.memoizeWithExpiration;
|
||||||
import static google.registry.proxy.ProxyConfig.getProxyConfig;
|
import static google.registry.proxy.ProxyConfig.getProxyConfig;
|
||||||
import static google.registry.util.ResourceUtils.readResourceBytes;
|
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
import com.beust.jcommander.JCommander;
|
import com.beust.jcommander.JCommander;
|
||||||
|
@ -26,6 +25,7 @@ import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||||
import com.google.api.client.googleapis.util.Utils;
|
import com.google.api.client.googleapis.util.Utils;
|
||||||
import com.google.api.services.cloudkms.v1.CloudKMS;
|
import com.google.api.services.cloudkms.v1.CloudKMS;
|
||||||
import com.google.api.services.cloudkms.v1.model.DecryptRequest;
|
import com.google.api.services.cloudkms.v1.model.DecryptRequest;
|
||||||
|
import com.google.api.services.storage.Storage;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.monitoring.metrics.MetricReporter;
|
import com.google.monitoring.metrics.MetricReporter;
|
||||||
|
@ -44,6 +44,7 @@ import io.netty.handler.logging.LogLevel;
|
||||||
import io.netty.handler.logging.LoggingHandler;
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
import io.netty.handler.ssl.OpenSsl;
|
import io.netty.handler.ssl.OpenSsl;
|
||||||
import io.netty.handler.ssl.SslProvider;
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -218,14 +219,32 @@ public class ProxyModule {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
static Storage provideStorage(GoogleCredential credential, ProxyConfig config) {
|
||||||
|
return new Storage.Builder(
|
||||||
|
Utils.getDefaultTransport(), Utils.getDefaultJsonFactory(), credential)
|
||||||
|
.setApplicationName(config.projectId)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
@Named("encryptedPemBytes")
|
@Named("encryptedPemBytes")
|
||||||
static byte[] provideEncryptedPemBytes(ProxyConfig config) {
|
static byte[] provideEncryptedPemBytes(Storage storage, ProxyConfig config) {
|
||||||
try {
|
try {
|
||||||
return readResourceBytes(ProxyModule.class, "resources/" + config.sslPemFilename).read();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
storage
|
||||||
|
.objects()
|
||||||
|
.get(config.gcs.bucket, config.gcs.sslPemFilename)
|
||||||
|
.executeMediaAndDownloadTo(outputStream);
|
||||||
|
return outputStream.toByteArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.severefmt(e, "Error reading encrypted PEM file: %s", config.sslPemFilename);
|
logger.severefmt(
|
||||||
|
e,
|
||||||
|
"Error reading encrypted PEM file %s from GCS bucket %s",
|
||||||
|
config.gcs.sslPemFilename,
|
||||||
|
config.gcs.bucket);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,11 @@ accessTokenValidPeriodSeconds: 1800
|
||||||
# com.google.api.client.auth.oauth2.Credential#intercept.
|
# com.google.api.client.auth.oauth2.Credential#intercept.
|
||||||
accessTokenRefreshBeforeExpirySeconds: 60
|
accessTokenRefreshBeforeExpirySeconds: 60
|
||||||
|
|
||||||
# Name of the encrypted PEM file.
|
gcs:
|
||||||
sslPemFilename: your-ssl.pem
|
# GCS bucket that stores the encrypted PEM file.
|
||||||
|
bucket: your-gcs-bucket
|
||||||
|
# Name of the encrypted PEM file.
|
||||||
|
sslPemFilename: your-pem-filename
|
||||||
|
|
||||||
# Strings used to construct the KMS crypto key URL.
|
# Strings used to construct the KMS crypto key URL.
|
||||||
# See: https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys
|
# See: https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys
|
||||||
|
|
|
@ -12,6 +12,7 @@ module "proxy" {
|
||||||
nomulus_project_name = "YOUR_NOMULUS_GPROJECT"
|
nomulus_project_name = "YOUR_NOMULUS_GPROJECT"
|
||||||
gcr_project_name = "YOUR_GCR_PROJECT"
|
gcr_project_name = "YOUR_GCR_PROJECT"
|
||||||
proxy_domain_name = "YOUR_PROXY_DOMAIN"
|
proxy_domain_name = "YOUR_PROXY_DOMAIN"
|
||||||
|
proxy_certificate_bucket = "YOU_CERTIFICATE_BUCKET"
|
||||||
}
|
}
|
||||||
|
|
||||||
output "proxy_service_account_client_id" {
|
output "proxy_service_account_client_id" {
|
||||||
|
|
10
java/google/registry/proxy/terraform/modules/gcs.tf
Normal file
10
java/google/registry/proxy/terraform/modules/gcs.tf
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
resource "google_storage_bucket" "proxy_certificate" {
|
||||||
|
name = "${var.proxy_certificate_bucket}"
|
||||||
|
storage_class = "MULTI_REGIONAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_storage_bucket_iam_member" "member" {
|
||||||
|
bucket = "${google_storage_bucket.proxy_certificate.name}"
|
||||||
|
role = "roles/storage.objectViewer"
|
||||||
|
member = "serviceAccount:${google_service_account.proxy_service_account.email}"
|
||||||
|
}
|
|
@ -10,6 +10,9 @@ variable "gcr_project_name" {}
|
||||||
# The base domain name of the proxy, without the whois. or epp. part.
|
# The base domain name of the proxy, without the whois. or epp. part.
|
||||||
variable "proxy_domain_name" {}
|
variable "proxy_domain_name" {}
|
||||||
|
|
||||||
|
# The GCS bucket that stores the encrypted SSL certificate.
|
||||||
|
variable "proxy_certificate_bucket" {}
|
||||||
|
|
||||||
# Cloud KMS keyring name
|
# Cloud KMS keyring name
|
||||||
variable "proxy_key_ring" {
|
variable "proxy_key_ring" {
|
||||||
default = "proxy-key-ring"
|
default = "proxy-key-ring"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue