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() { configPath := flag.String("config", "config.yml", "Path to configuration file") flag.Parse() configBytes, err := ioutil.ReadFile(*configPath) cmd.FailOnError(err, fmt.Sprintf("Failed to read configuration file from '%s'", *configPath)) var c config err = yaml.Unmarshal(configBytes, &c) cmd.FailOnError(err, fmt.Sprintf("Failed to parse configuration file from '%s'", *configPath)) go cmd.DebugServer(c.DebugAddr) stats, err := statsd.NewClient(c.StatsdServer, c.StatsdPrefix) cmd.FailOnError(err, "Failed to create StatsD client") scope := metrics.NewStatsdScope(stats, "caa-service") resolver := bdns.NewDNSResolverImpl( c.DNSTimeout.Duration, []string{c.DNSResolver}, scope, clock.Default(), 5, ) s, l, err := bgrpc.NewServer(&c.GRPC, scope) cmd.FailOnError(err, "Failed to setup gRPC server") ccs := &caaCheckerServer{resolver, scope} pb.RegisterCAACheckerServer(s, ccs) err = s.Serve(l) cmd.FailOnError(err, "gRPC service failed") }
func setupWFE(c config, logger blog.Logger, stats metrics.Scope) (core.RegistrationAuthority, core.StorageAuthority) { amqpConf := c.WFE.AMQP var rac core.RegistrationAuthority if c.WFE.RAService != nil { conn, err := bgrpc.ClientSetup(c.WFE.RAService, stats) cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to RA") rac = bgrpc.NewRegistrationAuthorityClient(rapb.NewRegistrationAuthorityClient(conn)) } else { var err error rac, err = rpc.NewRegistrationAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create RA AMQP client") } var sac core.StorageAuthority if c.WFE.SAService != nil { conn, err := bgrpc.ClientSetup(c.WFE.SAService, stats) cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA") sac = bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn)) } else { var err error sac, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create SA client") } return rac, sac }
// newGoogleSafeBrowsing returns nil if the GoogleSafeBrowsing struct given is // nil. If an empty Google API key or an unreadable data directory is in the // GoogleSafeBrowsing config struct, this function runs cmd.FailOnError. func newGoogleSafeBrowsing(gsb *cmd.GoogleSafeBrowsingConfig) va.SafeBrowsing { if gsb == nil { return nil } if gsb.APIKey == "" { cmd.FailOnError(errors.New(""), "a Google Safe Browsing config was given but it did not include a Google API key in APIKey") } if gsb.DataDir == "" { cmd.FailOnError(errors.New(""), "a Google Safe Browsing config was given but it did not include data directory to store the hashes file in DataDir") } f, err := os.Open(gsb.DataDir) if err != nil { if os.IsNotExist(err) { cmd.FailOnError(err, fmt.Sprintf("Google Safe Browsing data directory (%#v) does not exist", gsb.DataDir)) } cmd.FailOnError(err, "unable to open Google Safe Browsing data directory") } f.Close() sbc, err := safebrowsing.NewSafeBrowsing(gsb.APIKey, gsb.DataDir) if err != nil { cmd.FailOnError(err, "unable to create new safe browsing client") } return sbc }
func setupClients(c cmd.OCSPUpdaterConfig, stats metrics.Scope) ( core.CertificateAuthority, core.Publisher, core.StorageAuthority, ) { amqpConf := c.AMQP var cac core.CertificateAuthority if c.CAService != nil { conn, err := bgrpc.ClientSetup(c.CAService, stats) cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to CA") cac = bgrpc.NewCertificateAuthorityClient(capb.NewCertificateAuthorityClient(conn)) } else { var err error cac, err = rpc.NewCertificateAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create CA client") } conn, err := bgrpc.ClientSetup(c.Publisher, stats) cmd.FailOnError(err, "Failed to load credentials and create connection to service") pubc := bgrpc.NewPublisherClientWrapper(pubPB.NewPublisherClient(conn)) var sac core.StorageAuthority if c.SAService != nil { conn, err := bgrpc.ClientSetup(c.SAService, stats) cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA") sac = bgrpc.NewStorageAuthorityClient(sapb.NewStorageAuthorityClient(conn)) } else { sac, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create SA client") } return cac, pubc, sac }
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 main() { app := cmd.NewAppShell("boulder-publisher", "Submits issued certificates to CT logs") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { pubi, err := publisher.NewPublisherImpl(c.Common.CT) cmd.FailOnError(err, "Could not setup Publisher") go cmd.DebugServer(c.Publisher.DebugAddr) go cmd.ProfileCmd("Publisher", stats) saRPC, err := rpc.NewAmqpRPCClient("Publisher->SA", c.AMQP.SA.Server, c, 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, c.Publisher.MaxConcurrentRPCServerRequests, c) cmd.FailOnError(err, "Unable to create Publisher RPC server") rpc.NewPublisherServer(pubs, &pubi) err = pubs.Start(c) cmd.FailOnError(err, "Unable to run Publisher RPC server") } app.Run() }
func main() { app := cmd.NewAppShell("activity-monitor", "RPC activity monitor") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { go cmd.DebugServer(c.ActivityMonitor.DebugAddr) amqpConf := c.ActivityMonitor.AMQP server, err := rpc.NewMonitorServer(amqpConf, 0, stats) cmd.FailOnError(err, "Could not connect to AMQP") ae := analysisengine.NewLoggingAnalysisEngine() messages := expvar.NewInt("messages") server.HandleDeliveries(rpc.DeliveryHandler(func(d amqp.Delivery) { messages.Add(1) ae.ProcessMessage(d) })) go cmd.ProfileCmd("AM", stats) err = server.Start(amqpConf) cmd.FailOnError(err, "Unable to run Activity Monitor") } app.Run() }
func main() { app := cmd.NewAppShell("boulder-sa", "Handles SQL operations") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { saConf := c.SA go cmd.DebugServer(saConf.DebugAddr) dbMap, err := sa.NewDbMap(saConf.DBConnect) cmd.FailOnError(err, "Couldn't connect to SA database") sai, err := sa.NewSQLStorageAuthority(dbMap, clock.Default()) cmd.FailOnError(err, "Failed to create SA impl") sai.SetSQLDebug(c.SQL.SQLDebug) go cmd.ProfileCmd("SA", stats) amqpConf := saConf.AMQP sas, err := rpc.NewAmqpRPCServer(amqpConf, c.SA.MaxConcurrentRPCServerRequests, stats) cmd.FailOnError(err, "Unable to create SA RPC server") rpc.NewStorageAuthorityServer(sas, sai) err = sas.Start(amqpConf) cmd.FailOnError(err, "Unable to run SA RPC server") } app.Run() }
func main() { server := *server conn, err := amqp.Dial(server) cmd.FailOnError(err, "Could not connect to AMQP") ch, err := conn.Channel() cmd.FailOnError(err, "Could not connect to AMQP") err = ch.ExchangeDeclare( amqpExchange, amqpExchangeType, amqpExchangeDurable, amqpDeleteUnused, amqpInternal, amqpNoWait, nil) cmd.FailOnError(err, "Declaring exchange") _, err = ch.QueueDeclare( monitorQueueName, amqpQueueDurable, amqpDeleteUnused, amqpExclusive, amqpNoWait, nil) if err != nil { cmd.FailOnError(err, "Could not declare queue") } }
func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { // Validate PA config and set defaults if needed cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration") c.PA.SetDefaultChallengesIfEmpty() 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, c.PA.Challenges) 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) amqpConf := c.RA.AMQP vac, err := rpc.NewValidationAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create SA client") var dc *ra.DomainCheck if c.RA.UseIsSafeDomain { dc = &ra.DomainCheck{VA: 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(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, rai) err = ras.Start(amqpConf) cmd.FailOnError(err, "Unable to run RA RPC server") } 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() { configFile := flag.String("config", "", "File path to the configuration file for this service") flag.Parse() if *configFile == "" { flag.Usage() os.Exit(1) } var c config err := cmd.ReadConfigFile(*configFile, &c) cmd.FailOnError(err, "Reading JSON config file into config structure") conf := c.OCSPUpdater stats, auditlogger := cmd.StatsAndLogging(c.Statsd, c.Syslog) scope := metrics.NewStatsdScope(stats, "OCSPUpdater") defer auditlogger.AuditPanic() auditlogger.Info(cmd.VersionString(clientName)) // Configure DB dbURL, err := conf.DBConfig.URL() cmd.FailOnError(err, "Couldn't load DB URL") dbMap, err := sa.NewDbMap(dbURL, conf.DBConfig.MaxDBConns) cmd.FailOnError(err, "Could not connect to database") go sa.ReportDbConnCount(dbMap, scope) cac, pubc, sac := setupClients(conf, scope) updater, err := newUpdater( scope, clock.Default(), dbMap, cac, pubc, sac, // Necessary evil for now conf, c.Common.CT.Logs, c.Common.IssuerCert, auditlogger, ) 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.Error()) } }(l) } go cmd.DebugServer(conf.DebugAddr) go cmd.ProfileCmd(scope) // Sleep forever (until signaled) select {} }
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("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-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) 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") 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) 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 setupWFE(c cmd.Config, logger blog.Logger, stats metrics.Statter) (*rpc.RegistrationAuthorityClient, *rpc.StorageAuthorityClient) { amqpConf := c.WFE.AMQP rac, err := rpc.NewRegistrationAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create RA client") sac, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create SA client") return rac, sac }
func main() { app := cmd.NewAppShell("boulder-va", "Handles challenge validation") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.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 } clk := clock.Default() sbc := newGoogleSafeBrowsing(c.VA.GoogleSafeBrowsing) vai := va.NewValidationAuthorityImpl(pc, sbc, stats, clk) dnsTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse DNS timeout") scoped := metrics.NewStatsdScope(stats, "VA", "DNS") dnsTries := c.VA.DNSTries if dnsTries < 1 { dnsTries = 1 } if !c.Common.DNSAllowLoopbackAddresses { vai.DNSResolver = bdns.NewDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver}, scoped, clk, dnsTries) } else { vai.DNSResolver = bdns.NewTestDNSResolverImpl(dnsTimeout, []string{c.Common.DNSResolver}, scoped, clk, dnsTries) } vai.UserAgent = c.VA.UserAgent vai.IssuerDomain = c.VA.IssuerDomain amqpConf := c.VA.AMQP rac, err := rpc.NewRegistrationAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create RA client") vai.RA = rac vas, err := rpc.NewAmqpRPCServer(amqpConf, c.VA.MaxConcurrentRPCServerRequests, stats) cmd.FailOnError(err, "Unable to create VA RPC server") rpc.NewValidationAuthorityServer(vas, vai) err = vas.Start(amqpConf) 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, stats metrics.Statter, logger blog.Logger) { go cmd.DebugServer(c.OCSPResponder.DebugAddr) go cmd.ProfileCmd("OCSP", stats) config := c.OCSPResponder var source cfocsp.Source // DBConfig takes precedence over Source, if present. dbConnect, err := config.DBConfig.URL() cmd.FailOnError(err, "Reading DB config") if dbConnect == "" { dbConnect = config.Source } url, err := url.Parse(dbConnect) cmd.FailOnError(err, fmt.Sprintf("Source was not a URL: %s", config.Source)) if url.Scheme == "mysql+tcp" { logger.Info(fmt.Sprintf("Loading OCSP Database for CA Cert: %s", c.Common.IssuerCert)) dbMap, err := sa.NewDbMap(config.Source) cmd.FailOnError(err, "Could not connect to database") sa.SetSQLDebug(dbMap, logger) source, err = makeDBSource(dbMap, c.Common.IssuerCert, logger) 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 := mux(stats, c.OCSPResponder.Path, source) srv := &http.Server{ Addr: c.OCSPResponder.ListenAddress, Handler: m, } 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 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 setup(c *cli.Context) (statsd.Statter, *blog.AuditLogger, *rpc.StorageAuthorityClient) { configJSON, err := ioutil.ReadFile(c.GlobalString("config")) cmd.FailOnError(err, "Failed to read config file") var conf config err = json.Unmarshal(configJSON, &conf) cmd.FailOnError(err, "Failed to parse config file") stats, logger := cmd.StatsAndLogging(conf.Statsd, conf.Syslog) sa, err := rpc.NewStorageAuthorityClient("orphan-finder", &conf.AMQP, stats) cmd.FailOnError(err, "Failed to create SA client") return stats, logger, sa }
func main() { dryRun := flag.Bool("dryRun", true, "Whether to do a dry run.") sleep := flag.Duration("sleep", 60*time.Second, "How long to sleep between batches.") batchSize := flag.Uint("batchSize", 1000, "Number of certificates to process between sleeps.") numBatches := flag.Uint("numBatches", 999999, "Stop processing after N batches.") type config struct { NotAfterBackFiller struct { cmd.DBConfig } Statsd cmd.StatsdConfig Syslog cmd.SyslogConfig } configFile := flag.String("config", "", "File containing a JSON config.") flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n\n", usageIntro) fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) flag.PrintDefaults() } flag.Parse() if *configFile == "" { flag.Usage() os.Exit(1) } configData, err := ioutil.ReadFile(*configFile) cmd.FailOnError(err, fmt.Sprintf("Reading %q", *configFile)) var cfg config err = json.Unmarshal(configData, &cfg) cmd.FailOnError(err, "Unmarshaling config") stats, log := cmd.StatsAndLogging(cfg.Statsd, cfg.Syslog) defer log.AuditPanic() dbURL, err := cfg.NotAfterBackFiller.DBConfig.URL() cmd.FailOnError(err, "Couldn't load DB URL") dbMap, err := sa.NewDbMap(dbURL, 10) cmd.FailOnError(err, "Could not connect to database") go sa.ReportDbConnCount(dbMap, metrics.NewStatsdScope(stats, "NotAfterBackfiller")) b := backfiller{ dbMap: dbMap, log: log, clk: cmd.Clock(), dryRun: *dryRun, batchSize: *batchSize, numBatches: *numBatches, sleep: *sleep, } err = b.processForever() cmd.FailOnError(err, "Could not process certificate batches") }
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 setupWFE(c cmd.Config) (rpc.RegistrationAuthorityClient, rpc.StorageAuthorityClient, chan *amqp.Error) { ch := cmd.AmqpChannel(c.AMQP.Server) closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) rac, err := rpc.NewRegistrationAuthorityClient(c.AMQP.RA.Client, c.AMQP.RA.Server, ch) cmd.FailOnError(err, "Unable to create RA client") sac, err := rpc.NewStorageAuthorityClient(c.AMQP.SA.Client, c.AMQP.SA.Server, ch) cmd.FailOnError(err, "Unable to create SA client") return rac, sac, closeChan }
func main() { issuerFile := flag.String("issuer", "", "Issuer certificate (PEM)") responderFile := flag.String("responder", "", "OCSP responder certificate (DER)") targetFile := flag.String("target", "", "Certificate whose status is being reported (PEM)") pkcs11File := flag.String("pkcs11", "", pkcs11Usage) outFile := flag.String("out", "", "File to which the OCSP response will be written") thisUpdateString := flag.String("thisUpdate", "", "Time for ThisUpdate field, RFC3339 format (e.g. 2016-09-02T00:00:00Z)") nextUpdateString := flag.String("nextUpdate", "", "Time for NextUpdate field, RFC3339 format") status := flag.Int("status", 0, "Status for response (0 = good, 1 = revoked)") flag.Usage = func() { fmt.Fprint(os.Stderr, usage) flag.PrintDefaults() } flag.Parse() if len(*outFile) == 0 { cmd.FailOnError(fmt.Errorf("No output file provided"), "") } thisUpdate, err := time.Parse(time.RFC3339, *thisUpdateString) cmd.FailOnError(err, "Parsing thisUpdate flag") nextUpdate, err := time.Parse(time.RFC3339, *nextUpdateString) cmd.FailOnError(err, "Parsing nextUpdate flag") issuer, responder, target, pkcs11, err := readFiles(*issuerFile, *responderFile, *targetFile, *pkcs11File) cmd.FailOnError(err, "Failed to read files") // Instantiate the private key from PKCS11 priv, err := pkcs11key.New(pkcs11.Module, pkcs11.TokenLabel, pkcs11.PIN, pkcs11.PrivateKeyLabel) cmd.FailOnError(err, "Failed to load PKCS#11 key") // Populate the remaining fields in the template template := ocsp.Response{ SerialNumber: target.SerialNumber, Certificate: responder, Status: *status, ThisUpdate: thisUpdate, NextUpdate: nextUpdate, } if !core.KeyDigestEquals(responder.PublicKey, priv.Public()) { cmd.FailOnError(fmt.Errorf("PKCS#11 pubkey does not match pubkey "+ "in responder certificate"), "loading keys") } // Sign the OCSP response responseBytes, err := ocsp.CreateResponse(issuer, responder, template, priv) cmd.FailOnError(err, "Failed to sign OCSP response") _, err = ocsp.ParseResponse(responseBytes, nil) cmd.FailOnError(err, "Failed to parse signed response") responseBytesBase64 := base64.StdEncoding.EncodeToString(responseBytes) + "\n" // Write the OCSP response to stdout err = ioutil.WriteFile(*outFile, []byte(responseBytesBase64), 0666) cmd.FailOnError(err, "Failed to write output file") }
func main() { app := cmd.NewAppShell("boulder-ca", "Handles issuance operations") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { // Validate PA config and set defaults if needed cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration") c.PA.SetDefaultChallengesIfEmpty() // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.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, c.PA.Challenges) cmd.FailOnError(err, "Couldn't create PA") cai, err := ca.NewCertificateAuthorityImpl(c.CA, clock.Default(), stats, c.Common.IssuerCert) cmd.FailOnError(err, "Failed to create CA impl") cai.PA = pa go cmd.ProfileCmd("CA", stats) saRPC, err := rpc.NewAmqpRPCClient("CA->SA", c.AMQP.SA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") pubRPC, err := rpc.NewAmqpRPCClient("CA->Publisher", c.AMQP.Publisher.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") pubc, err := rpc.NewPublisherClient(pubRPC) cmd.FailOnError(err, "Failed to create Publisher client") cai.Publisher = &pubc cai.SA = &sac cas, err := rpc.NewAmqpRPCServer(c.AMQP.CA.Server, c.CA.MaxConcurrentRPCServerRequests, c) cmd.FailOnError(err, "Unable to create CA RPC server") rpc.NewCertificateAuthorityServer(cas, cai) err = cas.Start(c) cmd.FailOnError(err, "Unable to run CA RPC server") } app.Run() }
func setupClients(c cmd.Config) (rpc.CertificateAuthorityClient, chan *amqp.Error) { ch, err := rpc.AmqpChannel(c) cmd.FailOnError(err, "Could not connect to AMQP") closeChan := ch.NotifyClose(make(chan *amqp.Error, 1)) caRPC, err := rpc.NewAmqpRPCClient("OCSP->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") return cac, closeChan }
func main() { app := cmd.NewAppShell("boulder-va", "Handles challenge validation") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.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 } sbc := newGoogleSafeBrowsing(c.VA.GoogleSafeBrowsing) vai := va.NewValidationAuthorityImpl(pc, sbc, 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 raRPC, err := rpc.NewAmqpRPCClient("VA->RA", c.AMQP.RA.Server, c, 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, c.VA.MaxConcurrentRPCServerRequests, c) 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 setupWFE(c cmd.Config, logger *blog.AuditLogger, stats statsd.Statter) (rpc.RegistrationAuthorityClient, rpc.StorageAuthorityClient) { raRPC, err := rpc.NewAmqpRPCClient("WFE->RA", c.AMQP.RA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("WFE->SA", c.AMQP.SA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") rac, err := rpc.NewRegistrationAuthorityClient(raRPC) cmd.FailOnError(err, "Unable to create RA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") return rac, sac }