@@ -18,9 +18,10 @@ import (
1818 "github.com/letsencrypt/boulder/features"
1919 "github.com/letsencrypt/boulder/goodkey"
2020 bgrpc "github.com/letsencrypt/boulder/grpc"
21+ "github.com/letsencrypt/boulder/grpc/noncebalancer"
2122 "github.com/letsencrypt/boulder/issuance"
2223 blog "github.com/letsencrypt/boulder/log"
23- noncepb "github.com/letsencrypt/boulder/nonce/proto "
24+ "github.com/letsencrypt/boulder/nonce"
2425 rapb "github.com/letsencrypt/boulder/ra/proto"
2526 sapb "github.com/letsencrypt/boulder/sa/proto"
2627 "github.com/letsencrypt/boulder/wfe2"
@@ -50,16 +51,36 @@ type Config struct {
5051
5152 RAService * cmd.GRPCClientConfig
5253 SAService * cmd.GRPCClientConfig
53- // GetNonceService contains a gRPC config for any nonce-service instances
54- // which we want to retrieve nonces from. In a multi-DC deployment this
55- // should refer to any local nonce-service instances.
54+
55+ // GetNonceService is a gRPC config which contains a single SRV name
56+ // used to lookup nonce-service instances used exclusively for nonce
57+ // creation. In a multi-DC deployment this should refer to local
58+ // nonce-service instances only.
5659 GetNonceService * cmd.GRPCClientConfig
60+
5761 // RedeemNonceServices contains a map of nonce-service prefixes to
5862 // gRPC configs we want to use to redeem nonces. In a multi-DC deployment
5963 // this should contain all nonce-services from all DCs as we want to be
6064 // able to redeem nonces generated at any DC.
65+ //
66+ // DEPRECATED: See RedeemNonceService, below.
67+ // TODO (#6610) Remove this after all configs have migrated to
68+ // `RedeemNonceService`.
6169 RedeemNonceServices map [string ]cmd.GRPCClientConfig
6270
71+ // RedeemNonceService is a gRPC config which contains a list of SRV
72+ // names used to lookup nonce-service instances used exclusively for
73+ // nonce redemption. In a multi-DC deployment this should contain both
74+ // local and remote nonce-service instances.
75+ RedeemNonceService * cmd.GRPCClientConfig
76+
77+ // NoncePrefixKey is a secret used for deriving the prefix of each nonce
78+ // instance. It should contain 256 bits of random data to be suitable as
79+ // an HMAC-SHA256 key (e.g. the output of `openssl rand -hex 32`). In a
80+ // multi-DC deployment this value should be the same across all
81+ // boulder-wfe and nonce-service instances.
82+ NoncePrefixKey cmd.PasswordConfig
83+
6384 // CertificateChains maps AIA issuer URLs to certificate filenames.
6485 // Certificates are read into the chain in the order they are defined in the
6586 // slice of filenames.
@@ -280,7 +301,7 @@ func loadChain(certFiles []string) (*issuance.Certificate, []byte, error) {
280301 return certs [0 ], buf .Bytes (), nil
281302}
282303
283- func setupWFE (c Config , scope prometheus.Registerer , clk clock.Clock ) (rapb.RegistrationAuthorityClient , sapb.StorageAuthorityReadOnlyClient , noncepb. NonceServiceClient , map [string ]noncepb. NonceServiceClient ) {
304+ func setupWFE (c Config , scope prometheus.Registerer , clk clock.Clock ) (rapb.RegistrationAuthorityClient , sapb.StorageAuthorityReadOnlyClient , nonce. Getter , map [string ]nonce. Redeemer , nonce. Redeemer , string ) {
284305 tlsConfig , err := c .WFE .TLS .Load ()
285306 cmd .FailOnError (err , "TLS config" )
286307
@@ -292,21 +313,56 @@ func setupWFE(c Config, scope prometheus.Registerer, clk clock.Clock) (rapb.Regi
292313 cmd .FailOnError (err , "Failed to load credentials and create gRPC connection to SA" )
293314 sac := sapb .NewStorageAuthorityReadOnlyClient (saConn )
294315
295- var rns noncepb.NonceServiceClient
296- npm := map [string ]noncepb.NonceServiceClient {}
297- if c .WFE .GetNonceService != nil {
298- rnsConn , err := bgrpc .ClientSetup (c .WFE .GetNonceService , tlsConfig , scope , clk )
299- cmd .FailOnError (err , "Failed to load credentials and create gRPC connection to get nonce service" )
300- rns = noncepb .NewNonceServiceClient (rnsConn )
316+ // TODO(#6610) Refactor these checks.
317+ if c .WFE .RedeemNonceService != nil && c .WFE .RedeemNonceServices != nil {
318+ cmd .Fail ("Only one of 'redeemNonceService' or 'redeemNonceServices' should be configured." )
319+ }
320+ if c .WFE .RedeemNonceService == nil && c .WFE .RedeemNonceServices == nil {
321+ cmd .Fail ("One of 'redeemNonceService' or 'redeemNonceServices' must be configured." )
322+ }
323+ if c .WFE .RedeemNonceService != nil && c .WFE .NoncePrefixKey .PasswordFile == "" {
324+ cmd .Fail ("'noncePrefixKey' must be configured if 'redeemNonceService' is configured." )
325+ }
326+ if c .WFE .GetNonceService == nil {
327+ cmd .Fail ("'getNonceService' must be configured" )
328+ }
329+
330+ var rncKey string
331+ if c .WFE .NoncePrefixKey .PasswordFile != "" {
332+ rncKey , err = c .WFE .NoncePrefixKey .Pass ()
333+ cmd .FailOnError (err , "Failed to load noncePrefixKey" )
334+ }
335+
336+ getNonceConn , err := bgrpc .ClientSetup (c .WFE .GetNonceService , tlsConfig , scope , clk )
337+ cmd .FailOnError (err , "Failed to load credentials and create gRPC connection to get nonce service" )
338+ gnc := nonce .NewGetter (getNonceConn )
339+
340+ var rnc nonce.Redeemer
341+ var npm map [string ]nonce.Redeemer
342+ if c .WFE .RedeemNonceService != nil {
343+ // Dispatch nonce redemption RPCs dynamically.
344+ if c .WFE .RedeemNonceService .SRVResolver != noncebalancer .SRVResolverScheme {
345+ cmd .Fail (fmt .Sprintf (
346+ "'redeemNonceService.SRVResolver' must be set to %q" , noncebalancer .SRVResolverScheme ),
347+ )
348+ }
349+ redeemNonceConn , err := bgrpc .ClientSetup (c .WFE .RedeemNonceService , tlsConfig , scope , clk )
350+ cmd .FailOnError (err , "Failed to load credentials and create gRPC connection to redeem nonce service" )
351+ rnc = nonce .NewRedeemer (redeemNonceConn )
352+ } else {
353+ // Dispatch nonce redpemption RPCs using a static mapping.
354+ //
355+ // TODO(#6610) Remove code below and the `npm` mapping.
356+ npm = make (map [string ]nonce.Redeemer )
301357 for prefix , serviceConfig := range c .WFE .RedeemNonceServices {
302358 serviceConfig := serviceConfig
303359 conn , err := bgrpc .ClientSetup (& serviceConfig , tlsConfig , scope , clk )
304360 cmd .FailOnError (err , "Failed to load credentials and create gRPC connection to redeem nonce service" )
305- npm [prefix ] = noncepb . NewNonceServiceClient (conn )
361+ npm [prefix ] = nonce . NewRedeemer (conn )
306362 }
307363 }
308364
309- return rac , sac , rns , npm
365+ return rac , sac , gnc , npm , rnc , rncKey
310366}
311367
312368type errorWriter struct {
@@ -391,7 +447,7 @@ func main() {
391447
392448 clk := cmd .Clock ()
393449
394- rac , sac , rns , npm := setupWFE (c , stats , clk )
450+ rac , sac , gnc , npm , rnc , npKey := setupWFE (c , stats , clk )
395451
396452 kp , err := goodkey .NewKeyPolicy (& c .WFE .GoodKey , sac .KeyBlocked )
397453 cmd .FailOnError (err , "Unable to create key policy" )
@@ -434,15 +490,17 @@ func main() {
434490 kp ,
435491 allCertChains ,
436492 issuerCerts ,
437- rns ,
438- npm ,
439493 logger ,
440494 c .WFE .Timeout .Duration ,
441495 c .WFE .StaleTimeout .Duration ,
442496 authorizationLifetime ,
443497 pendingAuthorizationLifetime ,
444498 rac ,
445499 sac ,
500+ gnc ,
501+ npm ,
502+ rnc ,
503+ npKey ,
446504 accountGetter ,
447505 )
448506 cmd .FailOnError (err , "Unable to create WFE" )
0 commit comments