func main() { app := cmd.NewAppShell("ocsp-updater", "Generates and updates OCSP responses") app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) blog.SetAuditLogger(auditlogger) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() go cmd.DebugServer(c.OCSPUpdater.DebugAddr) go cmd.ProfileCmd("OCSP-Updater", stats) // Configure DB dbMap, err := sa.NewDbMap(c.OCSPUpdater.DBConnect) cmd.FailOnError(err, "Could not connect to database") cac, pubc, sac, closeChan := setupClients(c, stats) updater, err := newUpdater( stats, clock.Default(), dbMap, cac, pubc, sac, // Necessary evil for now c.OCSPUpdater, len(c.Common.CT.Logs), ) for _, l := range updater.loops { go func(loop *looper) { err = loop.loop() if err != nil { auditlogger.AuditErr(err) } }(l) } cmd.FailOnError(err, "Failed to create updater") // TODO(): When the channel falls over so do we for now, if the AMQP channel // has already closed there is no real cleanup we can do. This is due to // really needing to change the underlying AMQP Server/Client reconnection // logic. err = <-closeChan auditlogger.AuditErr(fmt.Errorf(" [!] AMQP Channel closed, exiting: [%s]", err)) os.Exit(1) } app.Run() }
func setupContext(context *cli.Context) (rpc.CertificateAuthorityClient, *blog.AuditLogger, *gorp.DbMap, rpc.StorageAuthorityClient) { c, err := loadConfig(context) cmd.FailOnError(err, "Failed to load Boulder configuration") stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") blog.SetAuditLogger(auditlogger) ch, err := rpc.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") caRPC, err := rpc.NewAmqpRPCClient("revoker->CA", c.AMQP.CA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") dbMap, err := sa.NewDbMap(c.Revoker.DBConnect) cmd.FailOnError(err, "Couldn't setup database connection") saRPC, err := rpc.NewAmqpRPCClient("AdminRevoker->SA", c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") return cac, auditlogger, dbMap, sac }
func main() { app := cmd.NewAppShell("activity-monitor") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Could not connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.ActivityMonitor.DebugAddr) ch, err := rpc.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") go cmd.ProfileCmd("AM", stats) auditlogger.Info(app.VersionString()) startMonitor(ch, auditlogger, stats) } app.Run() }
func main() { app := cmd.NewAppShell("boulder-sa") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) sai, err := sa.NewSQLStorageAuthority(c.SA.DBDriver, c.SA.DBName) cmd.FailOnError(err, "Failed to create SA impl") go cmd.ProfileCmd("SA", stats) for { ch := cmd.AmqpChannel(c.AMQP.Server) closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) sas := rpc.NewStorageAuthorityServer(c.AMQP.SA.Server, ch, sai) cmd.RunUntilSignaled(auditlogger, sas, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ca") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.DebugAddr) cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBConnect) cmd.FailOnError(err, "Failed to create CA database") if c.SQL.CreateTables { err = cadb.CreateTablesIfNotExists() cmd.FailOnError(err, "Failed to create CA tables") } cai, err := ca.NewCertificateAuthorityImpl(cadb, c.CA, c.Common.IssuerCert) cmd.FailOnError(err, "Failed to create CA impl") cai.MaxKeySize = c.Common.MaxKeySize go cmd.ProfileCmd("CA", stats) for { ch, err := cmd.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) saRPC, err := rpc.NewAmqpRPCClient("CA->SA", c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") cai.SA = &sac cas := rpc.NewAmqpRPCServer(c.AMQP.CA.Server, ch) err = rpc.NewCertificateAuthorityServer(cas, cai) cmd.FailOnError(err, "Unable to create CA server") auditlogger.Info(app.VersionString()) cmd.RunUntilSignaled(auditlogger, cas, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("external-cert-importer", "Imports external certificates for POP checks") app.App.Flags = append(app.App.Flags, cli.StringFlag{ Name: "a, valid-certs-file", Value: "ssl-observatory-valid-certs.csv", Usage: "The CSV file containing the valid certs to import.", }, cli.StringFlag{ Name: "d, domains-file", Value: "ssl-observatory-domains.csv", Usage: "The CSV file containing the domains associated with the certs that are being imported.", }, cli.StringFlag{ Name: "r, invalid-certs-file", Value: "ssl-observatory-invalid-certs.csv", Usage: "The CSV file Containing now invalid certs which should be removed.", }, cli.Float64Flag{ Name: "statsd-rate", Value: 0.1, Usage: "A floating point number between 0 and 1 representing the rate at which the statsd client will send data.", }) app.Config = func(c *cli.Context, config cmd.Config) cmd.Config { fmt.Println(c.Args()) config.ExternalCertImporter.CertsToImportCSVFilename = c.GlobalString("a") config.ExternalCertImporter.DomainsToImportCSVFilename = c.GlobalString("d") config.ExternalCertImporter.CertsToRemoveCSVFilename = c.GlobalString("r") config.ExternalCertImporter.StatsdRate = float32(math.Min(math.Max(c.Float64("statsd-rate"), 0.0), 1.0)) return config } app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") blog.SetAuditLogger(auditlogger) // Configure DB dbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Could not connect to database") dbMap.AddTableWithName(core.ExternalCert{}, "externalCerts").SetKeys(false, "SHA1") dbMap.AddTableWithName(core.IdentifierData{}, "identifierData").SetKeys(false, "CertSHA1") // Note that this order of operations is intentional: we first add // new certs to the database. Then, since certs are identified by // the entries in the identifiers table, we add those. Then, we // can remove invalid certs (which first removes the associated // identifiers). addCerts(c.ExternalCertImporter.CertsToImportCSVFilename, dbMap, stats, c.ExternalCertImporter.StatsdRate) addIdentifiers(c.ExternalCertImporter.DomainsToImportCSVFilename, dbMap, stats, c.ExternalCertImporter.StatsdRate) removeInvalidCerts(c.ExternalCertImporter.CertsToRemoveCSVFilename, dbMap, stats, c.ExternalCertImporter.StatsdRate) } app.Run() }
func main() { app := cmd.NewAppShell("boulder-wfe") app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) wfe, err := wfe.NewWebFrontEndImpl() cmd.FailOnError(err, "Unable to create WFE") rac, sac, closeChan := setupWFE(c) wfe.RA = &rac wfe.SA = &sac wfe.Stats = stats wfe.SubscriberAgreementURL = c.SubscriberAgreementURL wfe.IssuerCert, err = cmd.LoadCert(c.Common.IssuerCert) cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.Common.IssuerCert)) go cmd.ProfileCmd("WFE", stats) go func() { // sit around and reconnect to AMQP if the channel // drops for some reason and repopulate the wfe object // with new RA and SA rpc clients. for { for err := range closeChan { auditlogger.Warning(fmt.Sprintf("AMQP Channel closed, will reconnect in 5 seconds: [%s]", err)) time.Sleep(time.Second * 5) rac, sac, closeChan = setupWFE(c) wfe.RA = &rac wfe.SA = &sac auditlogger.Warning("Reconnected to AMQP") } } }() // Set up paths wfe.BaseURL = c.Common.BaseURL wfe.HandlePaths() auditlogger.Info(app.VersionString()) // Add HandlerTimer to output resp time + success/failure stats to statsd auditlogger.Info(fmt.Sprintf("Server running, listening on %s...\n", c.WFE.ListenAddress)) err = http.ListenAndServe(c.WFE.ListenAddress, HandlerTimer(http.DefaultServeMux, stats)) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ca", "Handles issuance operations") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.DebugAddr) dbMap, err := sa.NewDbMap(c.CA.DBConnect) cmd.FailOnError(err, "Couldn't connect to CA database") cadb, err := ca.NewCertificateAuthorityDatabaseImpl(dbMap) cmd.FailOnError(err, "Failed to create CA database") paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") cai, err := ca.NewCertificateAuthorityImpl(cadb, c.CA, clock.Default(), c.Common.IssuerCert) cmd.FailOnError(err, "Failed to create CA impl") cai.MaxKeySize = c.Common.MaxKeySize cai.PA = pa go cmd.ProfileCmd("CA", stats) connectionHandler := func(srv *rpc.AmqpRPCServer) { saRPC, err := rpc.NewAmqpRPCClient("CA->SA", c.AMQP.SA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") cai.SA = &sac } cas, err := rpc.NewAmqpRPCServer(c.AMQP.CA.Server, connectionHandler) cmd.FailOnError(err, "Unable to create CA RPC server") rpc.NewCertificateAuthorityServer(cas, cai) auditlogger.Info(app.VersionString()) err = cas.Start(c) cmd.FailOnError(err, "Unable to run CA RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("ocsp-updater", "Generates and updates OCSP responses") app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) blog.SetAuditLogger(auditlogger) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() go cmd.DebugServer(c.OCSPUpdater.DebugAddr) go cmd.ProfileCmd("OCSP-Updater", stats) // Configure DB dbMap, err := sa.NewDbMap(c.OCSPUpdater.DBConnect) cmd.FailOnError(err, "Could not connect to database") cac, pubc, sac := setupClients(c, stats) updater, err := newUpdater( stats, clock.Default(), dbMap, cac, pubc, sac, // Necessary evil for now c.OCSPUpdater, len(c.Common.CT.Logs), c.Common.IssuerCert, ) cmd.FailOnError(err, "Failed to create updater") for _, l := range updater.loops { go func(loop *looper) { err = loop.loop() if err != nil { auditlogger.AuditErr(err) } }(l) } // Sleep forever (until signaled) select {} } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ocsp-responder", "Handles OCSP requests") app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.OCSPResponder.DebugAddr) go cmd.ProfileCmd("OCSP", stats) auditlogger.Info(app.VersionString()) // Configure DB dbMap, err := sa.NewDbMap(c.OCSPResponder.DBConnect) cmd.FailOnError(err, "Could not connect to database") sa.SetSQLDebug(dbMap, c.SQL.SQLDebug) // Load the CA's key so we can store its SubjectKey in the DB caCertDER, err := cmd.LoadCert(c.Common.IssuerCert) cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.Common.IssuerCert)) caCert, err := x509.ParseCertificate(caCertDER) cmd.FailOnError(err, fmt.Sprintf("Couldn't parse cert read from [%s]", c.Common.IssuerCert)) if len(caCert.SubjectKeyId) == 0 { cmd.FailOnError(fmt.Errorf("Empty subjectKeyID"), "Unable to use CA certificate") } // Construct source from DB auditlogger.Info(fmt.Sprintf("Loading OCSP Database for CA Cert ID: %s", hex.EncodeToString(caCert.SubjectKeyId))) src, err := NewSourceFromDatabase(dbMap, caCert.SubjectKeyId) cmd.FailOnError(err, "Could not connect to OCSP database") // Configure HTTP m := http.NewServeMux() m.Handle(c.OCSPResponder.Path, cfocsp.Responder{Source: src}) // Add HandlerTimer to output resp time + success/failure stats to statsd auditlogger.Info(fmt.Sprintf("Server running, listening on %s...\n", c.OCSPResponder.ListenAddress)) err = http.ListenAndServe(c.OCSPResponder.ListenAddress, HandlerTimer(m, stats)) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-va") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.VA.DebugAddr) go cmd.ProfileCmd("VA", stats) vai := va.NewValidationAuthorityImpl(c.CA.TestMode) dnsTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse DNS timeout") vai.DNSResolver = core.NewDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver}) vai.UserAgent = c.VA.UserAgent for { ch, err := cmd.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) raRPC, err := rpc.NewAmqpRPCClient("VA->RA", c.AMQP.RA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") rac, err := rpc.NewRegistrationAuthorityClient(raRPC) cmd.FailOnError(err, "Unable to create RA client") vai.RA = &rac vas := rpc.NewAmqpRPCServer(c.AMQP.VA.Server, ch) err = rpc.NewValidationAuthorityServer(vas, &vai) cmd.FailOnError(err, "Unable to create VA server") auditlogger.Info(app.VersionString()) cmd.RunUntilSignaled(auditlogger, vas, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("boulder-sa") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.SA.DebugAddr) sai, err := sa.NewSQLStorageAuthority(c.SA.DBDriver, c.SA.DBConnect) cmd.FailOnError(err, "Failed to create SA impl") sai.SetSQLDebug(c.SQL.SQLDebug) if c.SQL.CreateTables { err = sai.CreateTablesIfNotExists() cmd.FailOnError(err, "Failed to create tables") } go cmd.ProfileCmd("SA", stats) for { ch, err := cmd.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) sas := rpc.NewAmqpRPCServer(c.AMQP.SA.Server, ch) err = rpc.NewStorageAuthorityServer(sas, sai) cmd.FailOnError(err, "Could create SA RPC server") auditlogger.Info(app.VersionString()) cmd.RunUntilSignaled(auditlogger, sas, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ra") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) rai := ra.NewRegistrationAuthorityImpl() go cmd.ProfileCmd("RA", stats) for { ch := cmd.AmqpChannel(c.AMQP.Server) closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) vac, err := rpc.NewValidationAuthorityClient(c.AMQP.VA.Client, c.AMQP.VA.Server, ch) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(c.AMQP.CA.Client, c.AMQP.CA.Server, ch) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(c.AMQP.SA.Client, c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create SA client") rai.VA = &vac rai.CA = &cac rai.SA = &sac ras, err := rpc.NewRegistrationAuthorityServer(c.AMQP.RA.Server, ch, &rai) cmd.FailOnError(err, "Unable to create RA server") cmd.RunUntilSignaled(auditlogger, ras, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("boulder-sa") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.SA.DebugAddr) dbMap, err := sa.NewDbMap(c.SA.DBConnect) cmd.FailOnError(err, "Couldn't connect to SA database") sai, err := sa.NewSQLStorageAuthority(dbMap) cmd.FailOnError(err, "Failed to create SA impl") sai.SetSQLDebug(c.SQL.SQLDebug) if c.SQL.CreateTables { err = sai.CreateTablesIfNotExists() cmd.FailOnError(err, "Failed to create tables") } go cmd.ProfileCmd("SA", stats) connectionHandler := func(*rpc.AmqpRPCServer) {} sas, err := rpc.NewAmqpRPCServer(c.AMQP.SA.Server, connectionHandler) cmd.FailOnError(err, "Unable to create SA RPC server") rpc.NewStorageAuthorityServer(sas, sai) auditlogger.Info(app.VersionString()) err = sas.Start(c) cmd.FailOnError(err, "Unable to run SA RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-publisher", "Submits issued certificates to CT logs") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Could not connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) pubi, err := publisher.NewPublisherImpl(c.Publisher.CT) cmd.FailOnError(err, "Could not setup Publisher") go cmd.DebugServer(c.Publisher.DebugAddr) go cmd.ProfileCmd("Publisher", stats) connectionHandler := func(srv *rpc.AmqpRPCServer) { saRPC, err := rpc.NewAmqpRPCClient("Publisher->SA", c.AMQP.SA.Server, srv.Channel, stats) cmd.FailOnError(err, "Unable to create SA RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") pubi.SA = &sac } pubs, err := rpc.NewAmqpRPCServer(c.AMQP.Publisher.Server, connectionHandler) cmd.FailOnError(err, "Unable to create Publisher RPC server") rpc.NewPublisherServer(pubs, &pubi) auditlogger.Info(app.VersionString()) err = pubs.Start(c) cmd.FailOnError(err, "Unable to run Publisher RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ca") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBName) cmd.FailOnError(err, "Failed to create CA database") cai, err := ca.NewCertificateAuthorityImpl(cadb, c.CA) cmd.FailOnError(err, "Failed to create CA impl") go cmd.ProfileCmd("CA", stats) for { ch := cmd.AmqpChannel(c.AMQP.Server) closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) sac, err := rpc.NewStorageAuthorityClient(c.AMQP.SA.Client, c.AMQP.SA.Client, ch) cmd.FailOnError(err, "Failed to create SA client") cai.SA = &sac cas, err := rpc.NewCertificateAuthorityServer(c.AMQP.CA.Server, ch, cai) cmd.FailOnError(err, "Unable to create CA server") cmd.RunUntilSignaled(auditlogger, cas, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("cert-checker", "Checks validity of certificates issued in the last 90 days") app.App.Flags = append(app.App.Flags, cli.IntFlag{ Name: "workers", Value: runtime.NumCPU(), Usage: "The number of concurrent workers used to process certificates", }, cli.StringFlag{ Name: "report-dir-path", Usage: "The path to write a JSON report on the certificates checks to (if no path is provided the report will not be written out)", }, cli.StringFlag{ Name: "db-connect", Usage: "SQL URI if not provided in the configuration file", }) app.Config = func(c *cli.Context, config cmd.Config) cmd.Config { config.CertChecker.ReportDirectoryPath = c.GlobalString("report-dir-path") if connect := c.GlobalString("db-connect"); connect != "" { config.CertChecker.DBConnect = connect } if workers := c.GlobalInt("workers"); workers != 0 { config.CertChecker.Workers = workers } return config } app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") blog.SetAuditLogger(auditlogger) auditlogger.Info(app.VersionString()) saDbMap, err := sa.NewDbMap(c.CertChecker.DBConnect) cmd.FailOnError(err, "Could not connect to database") paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Could not connect to policy database") checker := newChecker(saDbMap, paDbMap, clock.Default(), c.PA.EnforcePolicyWhitelist) auditlogger.Info("# Getting certificates issued in the last 90 days") // Since we grab certificates in batches we don't want this to block, when it // is finished it will close the certificate channel which allows the range // loops in checker.processCerts to break go func() { err = checker.getCerts() cmd.FailOnError(err, "Batch retrieval of certificates failed") }() auditlogger.Info(fmt.Sprintf("# Processing certificates using %d workers", c.CertChecker.Workers)) wg := new(sync.WaitGroup) for i := 0; i < c.CertChecker.Workers; i++ { wg.Add(1) go checker.processCerts(wg) } wg.Wait() auditlogger.Info(fmt.Sprintf( "# Finished processing certificates, sample: %d, good: %d, bad: %d", len(checker.issuedReport.Entries), checker.issuedReport.GoodCerts, checker.issuedReport.BadCerts, )) err = checker.issuedReport.save(c.CertChecker.ReportDirectoryPath) cmd.FailOnError(err, "Couldn't save issued certificate report") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.RA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") rai := ra.NewRegistrationAuthorityImpl(clock.Default(), auditlogger) rai.AuthzBase = c.Common.BaseURL + wfe.AuthzPath rai.MaxKeySize = c.Common.MaxKeySize rai.PA = pa raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) go cmd.ProfileCmd("RA", stats) connectionHandler := func(srv *rpc.AmqpRPCServer) { vaRPC, err := rpc.NewAmqpRPCClient("RA->VA", c.AMQP.VA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") caRPC, err := rpc.NewAmqpRPCClient("RA->CA", c.AMQP.CA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("RA->SA", c.AMQP.SA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") vac, err := rpc.NewValidationAuthorityClient(vaRPC) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") rai.VA = &vac rai.CA = &cac rai.SA = &sac } ras, err := rpc.NewAmqpRPCServer(c.AMQP.RA.Server, connectionHandler) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, &rai) auditlogger.Info(app.VersionString()) err = ras.Start(c) cmd.FailOnError(err, "Unable to run RA RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ra") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.RA.DebugAddr) rai := ra.NewRegistrationAuthorityImpl() rai.AuthzBase = c.Common.BaseURL + wfe.AuthzPath rai.MaxKeySize = c.Common.MaxKeySize raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) go cmd.ProfileCmd("RA", stats) for { ch, err := cmd.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) vaRPC, err := rpc.NewAmqpRPCClient("RA->VA", c.AMQP.VA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") caRPC, err := rpc.NewAmqpRPCClient("RA->CA", c.AMQP.CA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("RA->SA", c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") vac, err := rpc.NewValidationAuthorityClient(vaRPC) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") rai.VA = &vac rai.CA = &cac rai.SA = &sac ras := rpc.NewAmqpRPCServer(c.AMQP.RA.Server, ch) err = rpc.NewRegistrationAuthorityServer(ras, &rai) cmd.FailOnError(err, "Unable to create RA server") auditlogger.Info(app.VersionString()) cmd.RunUntilSignaled(auditlogger, ras, closeChan) } } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.RA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") rateLimitPolicies, err := cmd.LoadRateLimitPolicies(c.RA.RateLimitPoliciesFilename) cmd.FailOnError(err, "Couldn't load rate limit policies file") go cmd.ProfileCmd("RA", stats) vaRPC, err := rpc.NewAmqpRPCClient("RA->VA", c.AMQP.VA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") caRPC, err := rpc.NewAmqpRPCClient("RA->CA", c.AMQP.CA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("RA->SA", c.AMQP.SA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") vac, err := rpc.NewValidationAuthorityClient(vaRPC) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") var dc *ra.DomainCheck if c.RA.UseIsSafeDomain { dc = &ra.DomainCheck{&vac} } rai := ra.NewRegistrationAuthorityImpl(clock.Default(), auditlogger, stats, dc, rateLimitPolicies, c.RA.MaxContactsPerRegistration) rai.PA = pa raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") if !c.Common.DNSAllowLoopbackAddresses { rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } else { rai.DNSResolver = core.NewTestDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } rai.VA = &vac rai.CA = &cac rai.SA = &sac ras, err := rpc.NewAmqpRPCServer(c.AMQP.RA.Server, c.RA.MaxConcurrentRPCServerRequests, c) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, rai) err = ras.Start(c) cmd.FailOnError(err, "Unable to run RA RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("expiration-mailer") app.App.Flags = append(app.App.Flags, cli.IntFlag{ Name: "cert_limit", Value: 100, EnvVar: "CERT_LIMIT", Usage: "Count of certificates to process per expiration period", }) app.Config = func(c *cli.Context, config cmd.Config) cmd.Config { if c.GlobalInt("cert_limit") > 0 { config.Mailer.CertLimit = c.GlobalInt("cert_limit") } return config } app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) auditlogger.Info(app.VersionString()) go cmd.DebugServer(c.Mailer.DebugAddr) // Configure DB dbMap, err := sa.NewDbMap(c.Mailer.DBConnect) cmd.FailOnError(err, "Could not connect to database") ch, err := rpc.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") saRPC, err := rpc.NewAmqpRPCClient("ExpirationMailer->SA", c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") // Load email template emailTmpl, err := ioutil.ReadFile(c.Mailer.EmailTemplate) cmd.FailOnError(err, fmt.Sprintf("Could not read email template file [%s]", c.Mailer.EmailTemplate)) tmpl, err := template.New("expiry-email").Parse(string(emailTmpl)) cmd.FailOnError(err, "Could not parse email template") mailClient := mail.New(c.Mailer.Server, c.Mailer.Port, c.Mailer.Username, c.Mailer.Password) var nags durationSlice for _, nagDuration := range c.Mailer.NagTimes { dur, err := time.ParseDuration(nagDuration) if err != nil { auditlogger.Err(fmt.Sprintf("Failed to parse nag duration string [%s]: %s", nagDuration, err)) return } nags = append(nags, dur) } // Make sure durations are sorted in increasing order sort.Sort(nags) m := mailer{ stats: stats, log: auditlogger, dbMap: dbMap, rs: sac, mailer: &mailClient, emailTemplate: tmpl, nagTimes: nags, limit: c.Mailer.CertLimit, } auditlogger.Info("expiration-mailer: Starting") err = m.findExpiringCertificates() cmd.FailOnError(err, "expiration-mailer has failed") } app.Run() }
func main() { app := cmd.NewAppShell("boulder") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) // Run StatsD profiling go cmd.ProfileCmd("Monolith", stats) // Create the components wfei, err := wfe.NewWebFrontEndImpl() cmd.FailOnError(err, "Unable to create WFE") sa, err := sa.NewSQLStorageAuthority(c.SA.DBDriver, c.SA.DBName) cmd.FailOnError(err, "Unable to create SA") sa.SetSQLDebug(c.SQL.SQLDebug) ra := ra.NewRegistrationAuthorityImpl() va := va.NewValidationAuthorityImpl(c.CA.TestMode) dnsTimeout, err := time.ParseDuration(c.VA.DNSTimeout) cmd.FailOnError(err, "Couldn't parse DNS timeout") va.DNSResolver = core.NewDNSResolver(dnsTimeout, []string{c.VA.DNSResolver}) va.UserAgent = c.VA.UserAgent cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBName) cmd.FailOnError(err, "Failed to create CA database") ca, err := ca.NewCertificateAuthorityImpl(cadb, c.CA, c.Common.IssuerCert) cmd.FailOnError(err, "Unable to create CA") if c.SQL.CreateTables { err = sa.CreateTablesIfNotExists() cmd.FailOnError(err, "Failed to create SA tables") err = cadb.CreateTablesIfNotExists() cmd.FailOnError(err, "Failed to create CA tables") } // Wire them up wfei.RA = &ra wfei.SA = sa wfei.Stats = stats wfei.SubscriberAgreementURL = c.SubscriberAgreementURL wfei.IssuerCert, err = cmd.LoadCert(c.Common.IssuerCert) cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.Common.IssuerCert)) ra.CA = ca ra.SA = sa ra.VA = &va va.RA = &ra ca.SA = sa // Set up paths ra.AuthzBase = c.Common.BaseURL + wfe.AuthzPath wfei.BaseURL = c.Common.BaseURL wfei.HandlePaths() ra.MaxKeySize = c.Common.MaxKeySize ca.MaxKeySize = c.Common.MaxKeySize auditlogger.Info(app.VersionString()) fmt.Fprintf(os.Stderr, "Server running, listening on %s...\n", c.WFE.ListenAddress) err = http.ListenAndServe(c.WFE.ListenAddress, HandlerTimer(http.DefaultServeMux, stats)) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-va", "Handles challenge validation") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.VA.DebugAddr) go cmd.ProfileCmd("VA", stats) pc := &va.PortConfig{ HTTPPort: 80, HTTPSPort: 443, TLSPort: 443, } if c.VA.PortConfig.HTTPPort != 0 { pc.HTTPPort = c.VA.PortConfig.HTTPPort } if c.VA.PortConfig.HTTPSPort != 0 { pc.HTTPSPort = c.VA.PortConfig.HTTPSPort } if c.VA.PortConfig.TLSPort != 0 { pc.TLSPort = c.VA.PortConfig.TLSPort } vai := va.NewValidationAuthorityImpl(pc, stats, clock.Default()) dnsTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse DNS timeout") if !c.Common.DNSAllowLoopbackAddresses { vai.DNSResolver = core.NewDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver}) } else { vai.DNSResolver = core.NewTestDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver}) } vai.UserAgent = c.VA.UserAgent connectionHandler := func(srv *rpc.AmqpRPCServer) { raRPC, err := rpc.NewAmqpRPCClient("VA->RA", c.AMQP.RA.Server, srv.Channel, stats) cmd.FailOnError(err, "Unable to create RPC client") rac, err := rpc.NewRegistrationAuthorityClient(raRPC) cmd.FailOnError(err, "Unable to create RA client") vai.RA = &rac } vas, err := rpc.NewAmqpRPCServer(c.AMQP.VA.Server, connectionHandler, c.VA.MaxConcurrentRPCServerRequests) cmd.FailOnError(err, "Unable to create VA RPC server") rpc.NewValidationAuthorityServer(vas, vai) err = vas.Start(c) cmd.FailOnError(err, "Unable to run VA RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-ocsp-responder", "Handles OCSP requests") app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.OCSPResponder.DebugAddr) go cmd.ProfileCmd("OCSP", stats) config := c.OCSPResponder var source cfocsp.Source url, err := url.Parse(config.Source) cmd.FailOnError(err, fmt.Sprintf("Source was not a URL: %s", config.Source)) if url.Scheme == "mysql+tcp" { auditlogger.Info(fmt.Sprintf("Loading OCSP Database for CA Cert: %s", c.Common.IssuerCert)) source, err = makeDBSource(config.Source, c.Common.IssuerCert, c.SQL.SQLDebug) cmd.FailOnError(err, "Couldn't load OCSP DB") } else if url.Scheme == "file" { filename := url.Path // Go interprets cwd-relative file urls (file:test/foo.txt) as having the // relative part of the path in the 'Opaque' field. if filename == "" { filename = url.Opaque } source, err = cfocsp.NewSourceFromFile(filename) cmd.FailOnError(err, fmt.Sprintf("Couldn't read file: %s", url.Path)) } else { cmd.FailOnError(errors.New(`"source" parameter not found in JSON config`), "unable to start ocsp-responder") } stopTimeout, err := time.ParseDuration(c.OCSPResponder.ShutdownStopTimeout) cmd.FailOnError(err, "Couldn't parse shutdown stop timeout") killTimeout, err := time.ParseDuration(c.OCSPResponder.ShutdownKillTimeout) cmd.FailOnError(err, "Couldn't parse shutdown kill timeout") m := http.StripPrefix(c.OCSPResponder.Path, handler(source, c.OCSPResponder.MaxAge.Duration)) httpMonitor := metrics.NewHTTPMonitor(stats, m, "OCSP") srv := &http.Server{ Addr: c.OCSPResponder.ListenAddress, Handler: httpMonitor.Handle(), } hd := &httpdown.HTTP{ StopTimeout: stopTimeout, KillTimeout: killTimeout, Stats: metrics.NewFBAdapter(stats, "OCSP", clock.Default()), } err = httpdown.ListenAndServe(srv, hd) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }
func main() { app := cmd.NewAppShell("ocsp-updater") app.App.Flags = append(app.App.Flags, cli.IntFlag{ Name: "limit", Value: 100, EnvVar: "OCSP_LIMIT", Usage: "Count of responses to process per run", }) app.Config = func(c *cli.Context, config cmd.Config) cmd.Config { config.OCSPUpdater.ResponseLimit = c.GlobalInt("limit") return config } app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.OCSPUpdater.DebugAddr) // Configure DB dbMap, err := sa.NewDbMap(c.OCSPUpdater.DBConnect) cmd.FailOnError(err, "Could not connect to database") cac, closeChan := setupClients(c) go func() { // Abort if we disconnect from AMQP for { for err := range closeChan { auditlogger.Warning(fmt.Sprintf(" [!] AMQP Channel closed, aborting early: [%s]", err)) panic(err) } } }() auditlogger.Info(app.VersionString()) updater := &OCSPUpdater{ cac: cac, dbMap: dbMap, stats: stats, log: auditlogger, } // Calculate the cut-off timestamp if c.OCSPUpdater.MinTimeToExpiry == "" { panic("Config must specify a MinTimeToExpiry period.") } dur, err := time.ParseDuration(c.OCSPUpdater.MinTimeToExpiry) cmd.FailOnError(err, "Could not parse MinTimeToExpiry from config.") oldestLastUpdatedTime := time.Now().Add(-dur) auditlogger.Info(fmt.Sprintf("Searching for OCSP responses older than %s", oldestLastUpdatedTime)) // When we choose to batch responses, it may be best to restrict count here, // change the transaction to survive the whole findStaleResponses, and to // loop this method call however many times is appropriate. err = updater.findStaleResponses(oldestLastUpdatedTime, c.OCSPUpdater.ResponseLimit) if err != nil { auditlogger.WarningErr(err) } } app.Run() }
func main() { app := cli.NewApp() app.Name = "akamai-purger" app.Usage = "Purge a resource from the Akamai CDN cache" app.Version = cmd.Version() app.Author = "Boulder contributors" app.Email = "*****@*****.**" app.Flags = []cli.Flag{ cli.StringFlag{ Name: "config", Value: "config.json", EnvVar: "BOULDER_CONFIG", Usage: "Path to Boulder JSON configuration file", }, cli.StringFlag{ Name: "url", Usage: "URL to purge from CDN", }, } app.Action = func(c *cli.Context) { configFileName := c.GlobalString("config") url := c.GlobalString("url") if url == "" || configFileName == "" { fmt.Println("Both -url -config (or BOULDER_CONFIG) are required") return } configJSON, err := ioutil.ReadFile(configFileName) if err != nil { fmt.Printf("Failed to read config file: %s\n", err) return } var config cmd.Config err = json.Unmarshal(configJSON, &config) stats, err := statsd.NewClient(config.Statsd.Server, config.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(config.Syslog.Network, config.Syslog.Server, config.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.Version) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) akamaiClient, err := akamai.NewCachePurgeClient( config.OCSPUpdater.AkamaiBaseURL, config.OCSPUpdater.AkamaiClientToken, config.OCSPUpdater.AkamaiClientSecret, config.OCSPUpdater.AkamaiAccessToken, config.OCSPUpdater.AkamaiPurgeRetries, config.OCSPUpdater.AkamaiPurgeRetryBackoff.Duration, auditlogger, stats, ) cmd.FailOnError(err, "Failed to create Akamai CachePurgeClient") err = akamaiClient.Purge([]string{url}) cmd.FailOnError(err, "Failed to purge requested resource") } err := app.Run(os.Args) cmd.FailOnError(err, "Failed to run application") }
func main() { app := cmd.NewAppShell("boulder") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) // Run StatsD profiling go cmd.ProfileCmd("Monolith", stats) // Create the components wfe := wfe.NewWebFrontEndImpl() sa, err := sa.NewSQLStorageAuthority(c.SA.DBDriver, c.SA.DBName) cmd.FailOnError(err, "Unable to create SA") ra := ra.NewRegistrationAuthorityImpl() va := va.NewValidationAuthorityImpl(c.CA.TestMode) cadb, err := ca.NewCertificateAuthorityDatabaseImpl(c.CA.DBDriver, c.CA.DBName) cmd.FailOnError(err, "Failed to create CA database") ca, err := ca.NewCertificateAuthorityImpl(cadb, c.CA) cmd.FailOnError(err, "Unable to create CA") // Wire them up wfe.RA = &ra wfe.SA = sa wfe.Stats = stats wfe.SubscriberAgreementURL = c.SubscriberAgreementURL wfe.IssuerCert, err = cmd.LoadCert(c.CA.IssuerCert) cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.CA.IssuerCert)) ra.CA = ca ra.SA = sa ra.VA = &va va.RA = &ra ca.SA = sa // Set up paths wfe.BaseURL = c.WFE.BaseURL wfe.HandlePaths() // We need to tell the RA how to make challenge URIs // XXX: Better way to do this? Part of improved configuration ra.AuthzBase = wfe.AuthzBase fmt.Fprintf(os.Stderr, "Server running, listening on %s...\n", c.WFE.ListenAddress) err = http.ListenAndServe(c.WFE.ListenAddress, HandlerTimer(http.DefaultServeMux, stats)) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-wfe", "Handles HTTP API requests") addrFlag := cli.StringFlag{ Name: "addr", Value: "", Usage: "if set, overrides the listenAddr setting in the WFE config", EnvVar: "WFE_LISTEN_ADDR", } app.App.Flags = append(app.App.Flags, addrFlag) app.Config = func(c *cli.Context, config cmd.Config) cmd.Config { if c.GlobalString("addr") != "" { config.WFE.ListenAddress = c.GlobalString("addr") } return config } app.Action = func(c cmd.Config) { // Set up logging stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.WFE.DebugAddr) wfe, err := wfe.NewWebFrontEndImpl(stats, clock.Default()) cmd.FailOnError(err, "Unable to create WFE") rac, sac, closeChan := setupWFE(c, auditlogger, stats) wfe.RA = &rac wfe.SA = &sac wfe.SubscriberAgreementURL = c.SubscriberAgreementURL wfe.AllowOrigins = c.WFE.AllowOrigins wfe.CertCacheDuration, err = time.ParseDuration(c.WFE.CertCacheDuration) cmd.FailOnError(err, "Couldn't parse certificate caching duration") wfe.CertNoCacheExpirationWindow, err = time.ParseDuration(c.WFE.CertNoCacheExpirationWindow) cmd.FailOnError(err, "Couldn't parse certificate expiration no-cache window") wfe.IndexCacheDuration, err = time.ParseDuration(c.WFE.IndexCacheDuration) cmd.FailOnError(err, "Couldn't parse index caching duration") wfe.IssuerCacheDuration, err = time.ParseDuration(c.WFE.IssuerCacheDuration) cmd.FailOnError(err, "Couldn't parse issuer caching duration") wfe.ShutdownStopTimeout, err = time.ParseDuration(c.WFE.ShutdownStopTimeout) cmd.FailOnError(err, "Couldn't parse shutdown stop timeout") wfe.ShutdownKillTimeout, err = time.ParseDuration(c.WFE.ShutdownKillTimeout) cmd.FailOnError(err, "Couldn't parse shutdown kill timeout") wfe.IssuerCert, err = cmd.LoadCert(c.Common.IssuerCert) cmd.FailOnError(err, fmt.Sprintf("Couldn't read issuer cert [%s]", c.Common.IssuerCert)) go cmd.ProfileCmd("WFE", stats) go func() { // sit around and reconnect to AMQP if the channel // drops for some reason and repopulate the wfe object // with new RA and SA rpc clients. for { for err := range closeChan { auditlogger.Warning(fmt.Sprintf(" [!] AMQP Channel closed, will reconnect in 5 seconds: [%s]", err)) time.Sleep(time.Second * 5) rac, sac, closeChan = setupWFE(c, auditlogger, stats) wfe.RA = &rac wfe.SA = &sac } } }() // Set up paths wfe.BaseURL = c.Common.BaseURL h, err := wfe.Handler() cmd.FailOnError(err, "Problem setting up HTTP handlers") httpMonitor := metrics.NewHTTPMonitor(stats, h, "WFE") auditlogger.Info(fmt.Sprintf("Server running, listening on %s...\n", c.WFE.ListenAddress)) srv := &http.Server{ Addr: c.WFE.ListenAddress, Handler: httpMonitor.Handle(), } hd := &httpdown.HTTP{ StopTimeout: wfe.ShutdownStopTimeout, KillTimeout: wfe.ShutdownKillTimeout, Stats: metrics.NewFBAdapter(stats, "WFE", clock.Default()), } err = httpdown.ListenAndServe(srv, hd) cmd.FailOnError(err, "Error starting HTTP server") } app.Run() }