diff --git a/cmd/remoteva/main.go b/cmd/remoteva/main.go index e8364247752..9ea068fc086 100644 --- a/cmd/remoteva/main.go +++ b/cmd/remoteva/main.go @@ -2,6 +2,7 @@ package notmain import ( "context" + "crypto/tls" "flag" "os" "time" @@ -18,6 +19,24 @@ import ( type Config struct { RVA struct { vaConfig.Common + + // SkipGRPCClientCertVerification, when disabled as it should typically + // be, will cause the remoteva server (which receives gRPCs from a + // boulder-va client) to use our default RequireAndVerifyClientCert + // policy. When enabled, the remoteva server will instead use the less + // secure VerifyClientCertIfGiven policy. It should typically be used in + // conjunction with the boulder-va "RVATLSClient" configuration object. + // + // An operator may choose to enable this if the remoteva server is + // logically behind an OSI layer-7 loadbalancer/reverse proxy which + // decrypts traffic and does not/cannot re-encrypt it's own client + // connection to the remoteva server. + // + // Use with caution. + // + // For more information, see: https://pkg.go.dev/crypto/tls#ClientAuthType + SkipGRPCClientCertVerification bool + Features features.Config } @@ -65,6 +84,10 @@ func main() { tlsConfig, err := c.RVA.TLS.Load(scope) cmd.FailOnError(err, "tlsConfig config") + if c.RVA.SkipGRPCClientCertVerification { + tlsConfig.ClientAuth = tls.VerifyClientCertIfGiven + } + var resolver bdns.Client if !c.RVA.DNSAllowLoopbackAddresses { resolver = bdns.New( diff --git a/docs/multi-va.md b/docs/multi-va.md index bf0f6fd3cf2..3e05f41ef8c 100644 --- a/docs/multi-va.md +++ b/docs/multi-va.md @@ -15,17 +15,15 @@ primary VA will ask both remote VAs to perform matching validations for each primary validation). Of course this is a development environment so both the primary and remote VAs are all running on one host. -The primary and remote VAs are both the same piece of software, the `boulder-va` -service ([cmd here](https://github.com/letsencrypt/boulder/tree/main/cmd/boulder-va), -[package here](https://github.com/letsencrypt/boulder/tree/main/va)). +The `boulder-va` service ([here](https://github.com/letsencrypt/boulder/tree/main/cmd/boulder-va) and `remoteva` service ([here](https://github.com/letsencrypt/boulder/tree/main/cmd/remoteva)) are distinct pieces of software that utilize the same package ([here](https://github.com/letsencrypt/boulder/tree/main/va)). The boulder-ra uses [the same RPC interface](https://github.com/letsencrypt/boulder/blob/ea231adc36746cce97f860e818c2cdf92f060543/va/proto/va.proto#L8-L10) to ask for a primary validation as the primary VA uses to ask a remote VA for a confirmation validation. -Primary VA instances know they are a primary based on the presence of the -`"remoteVAs"` configuration element. If present it specifies gRPC service -addresses for other VA instances to use as remotes. There's also a handful of -feature flags that control how the primary VAs handle the remote VAs. +Primary VA instances contain a `"remoteVAs"` configuration element. If present +it specifies gRPC service addresses for `remoteva` instances to use as remote +VAs. There's also a handful of feature flags that control how the primary VAs +handle the remote VAs. In the development environment with `config-next` the two primary VAs are `va1.service.consul:9092` and `va2.service.consul:9092` and use @@ -34,9 +32,9 @@ as their configuration. This config file specifies two `"remoteVA"s`, `rva1.service.consul:9097` and `va2.service.consul:9098` and enforces [that a maximum of 1 of the 2 remote VAs disagree](https://github.com/letsencrypt/boulder/blob/ea231adc36746cce97f860e818c2cdf92f060543/test/config-next/va.json#L44) with the primary VA for all validations. The remote VA instances use -[`test/config-next/va-remote-a.json`](https://github.com/letsencrypt/boulder/blob/ea231adc36746cce97f860e818c2cdf92f060543/test/config-next/va-remote-a.json) +[`test/config-next/remoteva-a.json`](https://github.com/letsencrypt/boulder/blob/5c27eadb1db0605f380e41c8bd444a7f4ffe3c08/test/config-next/remoteva-a.json) and -[`test/config-next/va-remote-b.json`](https://github.com/letsencrypt/boulder/blob/ea231adc36746cce97f860e818c2cdf92f060543/test/config-next/va-remote-b.json) +[`test/config-next/remoteva-b.json`](https://github.com/letsencrypt/boulder/blob/5c27eadb1db0605f380e41c8bd444a7f4ffe3c08/test/config-next/remoteva-b.json) as their config files. There are two feature flags that control whether multi-VA takes effect: diff --git a/test/config-next/remoteva-a.json b/test/config-next/remoteva-a.json index 14f7ef4de2a..1a2d3d5f08b 100644 --- a/test/config-next/remoteva-a.json +++ b/test/config-next/remoteva-a.json @@ -14,6 +14,7 @@ "certFile": "test/grpc-creds/rva.boulder/cert.pem", "keyFile": "test/grpc-creds/rva.boulder/key.pem" }, + "skipGRPCClientCertVerification": true, "grpc": { "maxConnectionAge": "30s", "services": { diff --git a/test/config-next/remoteva-b.json b/test/config-next/remoteva-b.json index 82423314446..6ab73ee7de0 100644 --- a/test/config-next/remoteva-b.json +++ b/test/config-next/remoteva-b.json @@ -14,6 +14,7 @@ "certFile": "test/grpc-creds/rva.boulder/cert.pem", "keyFile": "test/grpc-creds/rva.boulder/key.pem" }, + "skipGRPCClientCertVerification": true, "grpc": { "maxConnectionAge": "30s", "services": {