Add gRPC MaxConnectionAge config. (#5311)

This allows servers to tell clients to go away after some period of time, which triggers the clients to re-resolve DNS.

Per grpc/grpc#12295, this is the preferred way to do this.

Related: #5307.
This commit is contained in:
Jacob Hoffman-Andrews 2021-03-01 18:37:47 -08:00 committed by GitHub
parent 066ed3427e
commit b4e483d38b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 29 additions and 3 deletions

View File

@ -269,6 +269,12 @@ type GRPCServerConfig struct {
// (SANs). The server will reject clients that do not present a certificate // (SANs). The server will reject clients that do not present a certificate
// with a SAN present on the `ClientNames` list. // with a SAN present on the `ClientNames` list.
ClientNames []string `json:"clientNames"` ClientNames []string `json:"clientNames"`
// MaxConnectionAge specifies how long a connection may live before the server sends a GoAway to the
// client. Because gRPC connections re-resolve DNS after a connection close,
// this controls how long it takes before a client learns about changes to its
// backends.
// https://pkg.go.dev/google.golang.org/grpc/keepalive#ServerParameters
MaxConnectionAge ConfigDuration
} }
// PortConfig specifies what ports the VA should call to on the remote // PortConfig specifies what ports the VA should call to on the remote

View File

@ -5,12 +5,13 @@ import (
"errors" "errors"
"net" "net"
"github.com/grpc-ecosystem/go-grpc-prometheus" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/jmhodges/clock" "github.com/jmhodges/clock"
"github.com/letsencrypt/boulder/cmd" "github.com/letsencrypt/boulder/cmd"
bcreds "github.com/letsencrypt/boulder/grpc/creds" bcreds "github.com/letsencrypt/boulder/grpc/creds"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/keepalive"
) )
// CodedError is a alias required to appease go vet // CodedError is a alias required to appease go vet
@ -42,10 +43,17 @@ func NewServer(c *cmd.GRPCServerConfig, tlsConfig *tls.Config, metrics serverMet
} }
si := newServerInterceptor(metrics, clk) si := newServerInterceptor(metrics, clk)
return grpc.NewServer( options := []grpc.ServerOption{
grpc.Creds(creds), grpc.Creds(creds),
grpc.UnaryInterceptor(si.intercept), grpc.UnaryInterceptor(si.intercept),
), l, nil }
if c.MaxConnectionAge.Duration > 0 {
options = append(options,
grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionAge: c.MaxConnectionAge.Duration,
}))
}
return grpc.NewServer(options...), l, nil
} }
// serverMetrics is a struct type used to return a few registered metrics from // serverMetrics is a struct type used to return a few registered metrics from

View File

@ -14,6 +14,7 @@
}, },
"grpc": { "grpc": {
"address": ":9099", "address": ":9099",
"maxConnectionAge": "30s",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",
"ra.boulder" "ra.boulder"

View File

@ -8,6 +8,7 @@
}, },
"hostnamePolicyFile": "test/hostname-policy.yaml", "hostnamePolicyFile": "test/hostname-policy.yaml",
"grpcCA": { "grpcCA": {
"maxConnectionAge": "30s",
"address": ":9093", "address": ":9093",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",
@ -15,6 +16,7 @@
] ]
}, },
"grpcOCSPGenerator": { "grpcOCSPGenerator": {
"maxConnectionAge": "30s",
"address": ":9096", "address": ":9096",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -8,6 +8,7 @@
}, },
"hostnamePolicyFile": "test/hostname-policy.yaml", "hostnamePolicyFile": "test/hostname-policy.yaml",
"grpcCA": { "grpcCA": {
"maxConnectionAge": "30s",
"address": ":9093", "address": ":9093",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",
@ -15,6 +16,7 @@
] ]
}, },
"grpcOCSPGenerator": { "grpcOCSPGenerator": {
"maxConnectionAge": "30s",
"address": ":9096", "address": ":9096",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -8,6 +8,7 @@
}, },
"debugAddr": ":8111", "debugAddr": ":8111",
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9101", "address": ":9101",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -4,6 +4,7 @@
"blockProfileRate": 1000000000, "blockProfileRate": 1000000000,
"debugAddr": ":8009", "debugAddr": ":8009",
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9091", "address": ":9091",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -42,6 +42,7 @@
"timeout": "15s" "timeout": "15s"
}, },
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9094", "address": ":9094",
"clientNames": [ "clientNames": [
"admin-revoker.boulder", "admin-revoker.boulder",

View File

@ -12,6 +12,7 @@
"keyFile": "test/grpc-creds/sa.boulder/key.pem" "keyFile": "test/grpc-creds/sa.boulder/key.pem"
}, },
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9095", "address": ":9095",
"clientNames": [ "clientNames": [
"admin-revoker.boulder", "admin-revoker.boulder",

View File

@ -19,6 +19,7 @@
"keyFile": "test/grpc-creds/va.boulder/key.pem" "keyFile": "test/grpc-creds/va.boulder/key.pem"
}, },
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9097", "address": ":9097",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -19,6 +19,7 @@
"keyFile": "test/grpc-creds/va.boulder/key.pem" "keyFile": "test/grpc-creds/va.boulder/key.pem"
}, },
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9098", "address": ":9098",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",

View File

@ -19,6 +19,7 @@
"keyFile": "test/grpc-creds/va.boulder/key.pem" "keyFile": "test/grpc-creds/va.boulder/key.pem"
}, },
"grpc": { "grpc": {
"maxConnectionAge": "30s",
"address": ":9092", "address": ":9092",
"clientNames": [ "clientNames": [
"health-checker.boulder", "health-checker.boulder",