1 package notmain
2
3 import (
4 "context"
5 "flag"
6 "os"
7 "time"
8
9 akamaipb "github.com/letsencrypt/boulder/akamai/proto"
10 capb "github.com/letsencrypt/boulder/ca/proto"
11 "github.com/letsencrypt/boulder/cmd"
12 "github.com/letsencrypt/boulder/config"
13 "github.com/letsencrypt/boulder/ctpolicy"
14 "github.com/letsencrypt/boulder/ctpolicy/ctconfig"
15 "github.com/letsencrypt/boulder/ctpolicy/loglist"
16 "github.com/letsencrypt/boulder/features"
17 "github.com/letsencrypt/boulder/goodkey"
18 "github.com/letsencrypt/boulder/goodkey/sagoodkey"
19 bgrpc "github.com/letsencrypt/boulder/grpc"
20 "github.com/letsencrypt/boulder/issuance"
21 "github.com/letsencrypt/boulder/policy"
22 pubpb "github.com/letsencrypt/boulder/publisher/proto"
23 "github.com/letsencrypt/boulder/ra"
24 rapb "github.com/letsencrypt/boulder/ra/proto"
25 sapb "github.com/letsencrypt/boulder/sa/proto"
26 vapb "github.com/letsencrypt/boulder/va/proto"
27 )
28
29 type Config struct {
30 RA struct {
31 cmd.ServiceConfig
32 cmd.HostnamePolicyConfig
33
34 RateLimitPoliciesFilename string `validate:"required"`
35
36 MaxContactsPerRegistration int
37
38 SAService *cmd.GRPCClientConfig
39 VAService *cmd.GRPCClientConfig
40 CAService *cmd.GRPCClientConfig
41 OCSPService *cmd.GRPCClientConfig
42 PublisherService *cmd.GRPCClientConfig
43 AkamaiPurgerService *cmd.GRPCClientConfig
44
45 MaxNames int `validate:"required,min=1"`
46
47
48
49
50
51 AuthorizationLifetimeDays int `validate:"required,min=1,max=397"`
52
53
54
55
56 PendingAuthorizationLifetimeDays int `validate:"required,min=1,max=29"`
57
58
59 GoodKey goodkey.Config
60
61
62
63 OrderLifetime config.Duration
64
65
66
67
68
69
70
71 FinalizeTimeout config.Duration `validate:"-"`
72
73
74
75
76
77
78
79
80
81 CTLogs ctconfig.CTConfig
82
83
84
85
86 InformationalCTLogs []ctconfig.LogDescription
87
88
89
90
91 IssuerCerts []string `validate:"min=1,dive,required"`
92
93 Features map[string]bool
94 }
95
96 PA cmd.PAConfig
97
98 Syslog cmd.SyslogConfig
99 OpenTelemetry cmd.OpenTelemetryConfig
100 }
101
102 func main() {
103 grpcAddr := flag.String("addr", "", "gRPC listen address override")
104 debugAddr := flag.String("debug-addr", "", "Debug server address override")
105 configFile := flag.String("config", "", "File path to the configuration file for this service")
106 flag.Parse()
107 if *configFile == "" {
108 flag.Usage()
109 os.Exit(1)
110 }
111
112 var c Config
113 err := cmd.ReadConfigFile(*configFile, &c)
114 cmd.FailOnError(err, "Reading JSON config file into config structure")
115
116 err = features.Set(c.RA.Features)
117 cmd.FailOnError(err, "Failed to set feature flags")
118
119 if *grpcAddr != "" {
120 c.RA.GRPC.Address = *grpcAddr
121 }
122 if *debugAddr != "" {
123 c.RA.DebugAddr = *debugAddr
124 }
125
126 scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.RA.DebugAddr)
127 defer oTelShutdown(context.Background())
128 logger.Info(cmd.VersionString())
129
130
131 cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration")
132
133 pa, err := policy.New(c.PA.Challenges, logger)
134 cmd.FailOnError(err, "Couldn't create PA")
135
136 if c.RA.HostnamePolicyFile == "" {
137 cmd.Fail("HostnamePolicyFile must be provided.")
138 }
139 err = pa.LoadHostnamePolicyFile(c.RA.HostnamePolicyFile)
140 cmd.FailOnError(err, "Couldn't load hostname policy file")
141
142 tlsConfig, err := c.RA.TLS.Load(scope)
143 cmd.FailOnError(err, "TLS config")
144
145 clk := cmd.Clock()
146
147 vaConn, err := bgrpc.ClientSetup(c.RA.VAService, tlsConfig, scope, clk)
148 cmd.FailOnError(err, "Unable to create VA client")
149 vac := vapb.NewVAClient(vaConn)
150 caaClient := vapb.NewCAAClient(vaConn)
151
152 caConn, err := bgrpc.ClientSetup(c.RA.CAService, tlsConfig, scope, clk)
153 cmd.FailOnError(err, "Unable to create CA client")
154 cac := capb.NewCertificateAuthorityClient(caConn)
155
156 ocspConn, err := bgrpc.ClientSetup(c.RA.OCSPService, tlsConfig, scope, clk)
157 cmd.FailOnError(err, "Unable to create CA OCSP client")
158 ocspc := capb.NewOCSPGeneratorClient(ocspConn)
159
160 saConn, err := bgrpc.ClientSetup(c.RA.SAService, tlsConfig, scope, clk)
161 cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
162 sac := sapb.NewStorageAuthorityClient(saConn)
163
164 conn, err := bgrpc.ClientSetup(c.RA.PublisherService, tlsConfig, scope, clk)
165 cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to Publisher")
166 pubc := pubpb.NewPublisherClient(conn)
167
168 apConn, err := bgrpc.ClientSetup(c.RA.AkamaiPurgerService, tlsConfig, scope, clk)
169 cmd.FailOnError(err, "Unable to create a Akamai Purger client")
170 apc := akamaipb.NewAkamaiPurgerClient(apConn)
171
172 issuerCertPaths := c.RA.IssuerCerts
173 issuerCerts := make([]*issuance.Certificate, len(issuerCertPaths))
174 for i, issuerCertPath := range issuerCertPaths {
175 issuerCerts[i], err = issuance.LoadCertificate(issuerCertPath)
176 cmd.FailOnError(err, "Failed to load issuer certificate")
177 }
178
179
180
181
182
183 var ctp *ctpolicy.CTPolicy
184 if len(c.RA.CTLogs.SCTLogs) <= 0 {
185 cmd.Fail("Must configure CTLogs")
186 }
187
188 allLogs, err := loglist.New(c.RA.CTLogs.LogListFile)
189 cmd.FailOnError(err, "Failed to parse log list")
190
191 sctLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.SCTLogs, loglist.Issuance)
192 cmd.FailOnError(err, "Failed to load SCT logs")
193
194 infoLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.InfoLogs, loglist.Informational)
195 cmd.FailOnError(err, "Failed to load informational logs")
196
197 finalLogs, err := allLogs.SubsetForPurpose(c.RA.CTLogs.FinalLogs, loglist.Informational)
198 cmd.FailOnError(err, "Failed to load final logs")
199
200 ctp = ctpolicy.New(pubc, sctLogs, infoLogs, finalLogs, c.RA.CTLogs.Stagger.Duration, logger, scope)
201
202
203
204
205
206 if c.RA.AuthorizationLifetimeDays <= 0 || c.RA.AuthorizationLifetimeDays > 397 {
207 cmd.Fail("authorizationLifetimeDays value must be greater than 0 and less than 398")
208 }
209 authorizationLifetime := time.Duration(c.RA.AuthorizationLifetimeDays) * 24 * time.Hour
210
211
212
213
214
215 if c.RA.PendingAuthorizationLifetimeDays <= 0 || c.RA.PendingAuthorizationLifetimeDays > 29 {
216 cmd.Fail("pendingAuthorizationLifetimeDays value must be greater than 0 and less than 30")
217 }
218 pendingAuthorizationLifetime := time.Duration(c.RA.PendingAuthorizationLifetimeDays) * 24 * time.Hour
219
220 if features.Enabled(features.AsyncFinalize) && c.RA.FinalizeTimeout.Duration == 0 {
221 cmd.Fail("finalizeTimeout must be supplied when AsyncFinalize feature is enabled")
222 }
223
224 kp, err := sagoodkey.NewKeyPolicy(&c.RA.GoodKey, sac.KeyBlocked)
225 cmd.FailOnError(err, "Unable to create key policy")
226
227 if c.RA.MaxNames == 0 {
228 cmd.Fail("Error in RA config: MaxNames must not be 0")
229 }
230
231 rai := ra.NewRegistrationAuthorityImpl(
232 clk,
233 logger,
234 scope,
235 c.RA.MaxContactsPerRegistration,
236 kp,
237 c.RA.MaxNames,
238 authorizationLifetime,
239 pendingAuthorizationLifetime,
240 pubc,
241 caaClient,
242 c.RA.OrderLifetime.Duration,
243 c.RA.FinalizeTimeout.Duration,
244 ctp,
245 apc,
246 issuerCerts,
247 )
248 defer rai.DrainFinalize()
249
250 policyErr := rai.LoadRateLimitPoliciesFile(c.RA.RateLimitPoliciesFilename)
251 cmd.FailOnError(policyErr, "Couldn't load rate limit policies file")
252 rai.PA = pa
253
254 rai.VA = vac
255 rai.CA = cac
256 rai.OCSP = ocspc
257 rai.SA = sac
258
259 start, err := bgrpc.NewServer(c.RA.GRPC, logger).Add(
260 &rapb.RegistrationAuthority_ServiceDesc, rai).Build(tlsConfig, scope, clk)
261 cmd.FailOnError(err, "Unable to setup RA gRPC server")
262
263 cmd.FailOnError(start(), "RA gRPC service failed")
264 }
265
266 func init() {
267 cmd.RegisterCommand("boulder-ra", main, &cmd.ConfigValidator{Config: &Config{}})
268 }
269
View as plain text