github.com/letsencrypt/boulder@v0.20251208.0/cmd/boulder-va/main.go (about)

     1  package notmain
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/jmhodges/clock"
    10  
    11  	"github.com/letsencrypt/boulder/bdns"
    12  	"github.com/letsencrypt/boulder/cmd"
    13  	"github.com/letsencrypt/boulder/config"
    14  	"github.com/letsencrypt/boulder/features"
    15  	bgrpc "github.com/letsencrypt/boulder/grpc"
    16  	"github.com/letsencrypt/boulder/iana"
    17  	"github.com/letsencrypt/boulder/va"
    18  	vaConfig "github.com/letsencrypt/boulder/va/config"
    19  	vapb "github.com/letsencrypt/boulder/va/proto"
    20  )
    21  
    22  // RemoteVAGRPCClientConfig  contains the information necessary to setup a gRPC
    23  // client connection. The following GRPC client configuration field combinations
    24  // are allowed:
    25  //
    26  // ServerAddress, DNSAuthority, [Timeout], [HostOverride]
    27  // SRVLookup, DNSAuthority, [Timeout], [HostOverride], [SRVResolver]
    28  // SRVLookups, DNSAuthority, [Timeout], [HostOverride], [SRVResolver]
    29  type RemoteVAGRPCClientConfig struct {
    30  	cmd.GRPCClientConfig
    31  	// Perspective uniquely identifies the Network Perspective used to
    32  	// perform the validation, as specified in BRs Section 5.4.1,
    33  	// Requirement 2.7 ("Multi-Perspective Issuance Corroboration attempts
    34  	// from each Network Perspective"). It should uniquely identify a group
    35  	// of RVAs deployed in the same datacenter.
    36  	Perspective string `validate:"required"`
    37  
    38  	// RIR indicates the Regional Internet Registry where this RVA is
    39  	// located. This field is used to identify the RIR region from which a
    40  	// given validation was performed, as specified in the "Phased
    41  	// Implementation Timeline" in BRs Section 3.2.2.9. It must be one of
    42  	// the following values:
    43  	//   - ARIN
    44  	//   - RIPE
    45  	//   - APNIC
    46  	//   - LACNIC
    47  	//   - AFRINIC
    48  	RIR string `validate:"required,oneof=ARIN RIPE APNIC LACNIC AFRINIC"`
    49  }
    50  
    51  type Config struct {
    52  	VA struct {
    53  		vaConfig.Common
    54  		RemoteVAs []RemoteVAGRPCClientConfig `validate:"omitempty,dive"`
    55  		// SlowRemoteTimeout sets how long the VA is willing to wait for slow
    56  		// RemoteVA instances to finish their work. It starts counting from
    57  		// when the VA first gets a quorum of (un)successful remote results.
    58  		// Leaving this value zero means the VA won't early-cancel slow remotes.
    59  		SlowRemoteTimeout config.Duration
    60  		Features          features.Config
    61  	}
    62  
    63  	Syslog        cmd.SyslogConfig
    64  	OpenTelemetry cmd.OpenTelemetryConfig
    65  }
    66  
    67  func main() {
    68  	grpcAddr := flag.String("addr", "", "gRPC listen address override")
    69  	debugAddr := flag.String("debug-addr", "", "Debug server address override")
    70  	configFile := flag.String("config", "", "File path to the configuration file for this service")
    71  	flag.Parse()
    72  	if *configFile == "" {
    73  		flag.Usage()
    74  		os.Exit(1)
    75  	}
    76  
    77  	var c Config
    78  	err := cmd.ReadConfigFile(*configFile, &c)
    79  	cmd.FailOnError(err, "Reading JSON config file into config structure")
    80  	err = c.VA.SetDefaultsAndValidate(grpcAddr, debugAddr)
    81  	cmd.FailOnError(err, "Setting and validating default config values")
    82  
    83  	features.Set(c.VA.Features)
    84  	scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.VA.DebugAddr)
    85  	defer oTelShutdown(context.Background())
    86  	logger.Info(cmd.VersionString())
    87  	clk := clock.New()
    88  
    89  	var servers bdns.ServerProvider
    90  
    91  	if len(c.VA.DNSStaticResolvers) != 0 {
    92  		servers, err = bdns.NewStaticProvider(c.VA.DNSStaticResolvers)
    93  		cmd.FailOnError(err, "Couldn't start static DNS server resolver")
    94  	} else {
    95  		servers, err = bdns.StartDynamicProvider(c.VA.DNSProvider, 60*time.Second, "tcp")
    96  		cmd.FailOnError(err, "Couldn't start dynamic DNS server resolver")
    97  	}
    98  	defer servers.Stop()
    99  
   100  	tlsConfig, err := c.VA.TLS.Load(scope)
   101  	cmd.FailOnError(err, "tlsConfig config")
   102  
   103  	var resolver bdns.Client
   104  	if !c.VA.DNSAllowLoopbackAddresses {
   105  		resolver = bdns.New(
   106  			c.VA.DNSTimeout.Duration,
   107  			servers,
   108  			scope,
   109  			clk,
   110  			c.VA.DNSTries,
   111  			c.VA.UserAgent,
   112  			logger,
   113  			tlsConfig)
   114  	} else {
   115  		resolver = bdns.NewTest(
   116  			c.VA.DNSTimeout.Duration,
   117  			servers,
   118  			scope,
   119  			clk,
   120  			c.VA.DNSTries,
   121  			c.VA.UserAgent,
   122  			logger,
   123  			tlsConfig)
   124  	}
   125  	var remotes []va.RemoteVA
   126  	if len(c.VA.RemoteVAs) > 0 {
   127  		for _, rva := range c.VA.RemoteVAs {
   128  			vaConn, err := bgrpc.ClientSetup(&rva.GRPCClientConfig, tlsConfig, scope, clk)
   129  			cmd.FailOnError(err, "Unable to create remote VA client")
   130  			remotes = append(
   131  				remotes,
   132  				va.RemoteVA{
   133  					RemoteClients: va.RemoteClients{
   134  						VAClient:  vapb.NewVAClient(vaConn),
   135  						CAAClient: vapb.NewCAAClient(vaConn),
   136  					},
   137  					Address:     rva.ServerAddress,
   138  					Perspective: rva.Perspective,
   139  					RIR:         rva.RIR,
   140  				},
   141  			)
   142  		}
   143  	}
   144  
   145  	vai, err := va.NewValidationAuthorityImpl(
   146  		resolver,
   147  		remotes,
   148  		c.VA.UserAgent,
   149  		c.VA.IssuerDomain,
   150  		scope,
   151  		clk,
   152  		logger,
   153  		c.VA.AccountURIPrefixes,
   154  		va.PrimaryPerspective,
   155  		"",
   156  		iana.IsReservedAddr,
   157  		c.VA.SlowRemoteTimeout.Duration,
   158  	)
   159  	cmd.FailOnError(err, "Unable to create VA server")
   160  
   161  	start, err := bgrpc.NewServer(c.VA.GRPC, logger).Add(
   162  		&vapb.VA_ServiceDesc, vai).Add(
   163  		&vapb.CAA_ServiceDesc, vai).Build(tlsConfig, scope, clk)
   164  	cmd.FailOnError(err, "Unable to setup VA gRPC server")
   165  	cmd.FailOnError(start(), "VA gRPC service failed")
   166  }
   167  
   168  func init() {
   169  	cmd.RegisterCommand("boulder-va", main, &cmd.ConfigValidator{Config: &Config{}})
   170  }