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 }