boulder/cmd/boulder-publisher/main.go

106 lines
2.7 KiB
Go

package main
import (
"flag"
"os"
"time"
ct "github.com/google/certificate-transparency-go"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/features"
bgrpc "github.com/letsencrypt/boulder/grpc"
"github.com/letsencrypt/boulder/publisher"
pubPB "github.com/letsencrypt/boulder/publisher/proto"
)
type config struct {
Publisher struct {
cmd.ServiceConfig
Features map[string]bool
}
Syslog cmd.SyslogConfig
Common struct {
CT struct {
IntermediateBundleFilename string
}
}
}
func main() {
grpcAddr := flag.String("addr", "", "gRPC listen address override")
debugAddr := flag.String("debug-addr", "", "Debug server address override")
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")
err = features.Set(c.Publisher.Features)
cmd.FailOnError(err, "Failed to set feature flags")
if *grpcAddr != "" {
c.Publisher.GRPC.Address = *grpcAddr
}
if *debugAddr != "" {
c.Publisher.DebugAddr = *debugAddr
}
scope, logger := cmd.StatsAndLogging(c.Syslog, c.Publisher.DebugAddr)
defer logger.AuditPanic()
logger.Info(cmd.VersionString())
if c.Common.CT.IntermediateBundleFilename == "" {
logger.AuditErr("No CT submission bundle provided")
os.Exit(1)
}
pemBundle, err := core.LoadCertBundle(c.Common.CT.IntermediateBundleFilename)
cmd.FailOnError(err, "Failed to load CT submission bundle")
bundle := []ct.ASN1Cert{}
for _, cert := range pemBundle {
bundle = append(bundle, ct.ASN1Cert{Data: cert.Raw})
}
tlsConfig, err := c.Publisher.TLS.Load()
cmd.FailOnError(err, "TLS config")
clk := cmd.Clock()
pubi := publisher.New(
bundle,
logger,
scope)
serverMetrics := bgrpc.NewServerMetrics(scope)
grpcSrv, l, err := bgrpc.NewServer(c.Publisher.GRPC, tlsConfig, serverMetrics, clk)
cmd.FailOnError(err, "Unable to setup Publisher gRPC server")
gw := bgrpc.NewPublisherServerWrapper(pubi)
pubPB.RegisterPublisherServer(grpcSrv, gw)
// Collect HTTP GET debug data every second from each log which
// we are requesting SCTs from. This will allow us to verify during
// CT outages we've seen in the past if the issue is with the CT
// client itself or something in the larger publisher/golang http
// library.
if features.Enabled(features.ProbeCTLogs) {
go func() {
t := time.NewTicker(time.Second)
for range t.C {
go pubi.ProbeLogs()
}
}()
}
go cmd.CatchSignals(logger, grpcSrv.GracefulStop)
err = cmd.FilterShutdownErrors(grpcSrv.Serve(l))
cmd.FailOnError(err, "Publisher gRPC service failed")
}