Example #1
0
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()
}
Example #2
0
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
}
Example #3
0
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()
}
Example #4
0
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()
}
Example #5
0
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()
}
Example #6
0
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()
}
Example #7
0
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()
}
Example #8
0
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()
}
Example #9
0
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()
}
Example #10
0
File: main.go Project: sjas/boulder
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()
}
Example #11
0
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()
}
Example #12
0
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()
}
Example #13
0
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()
}
Example #14
0
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()
}
Example #15
0
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()
}
Example #16
0
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()
}
Example #17
0
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()
}
Example #18
0
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()
}
Example #19
0
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()
}
Example #20
0
File: main.go Project: ekr/boulder
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()
}
Example #21
0
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()
}
Example #22
0
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()
}
Example #23
0
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()
}
Example #24
0
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()
}
Example #25
0
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()
}
Example #26
0
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")
}
Example #27
0
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()
}
Example #28
0
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()
}