...

Source file src/github.com/letsencrypt/boulder/cmd/crl-storer/main.go

Documentation: github.com/letsencrypt/boulder/cmd/crl-storer

     1  package notmain
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"net/http"
     7  	"os"
     8  
     9  	"github.com/aws/aws-sdk-go-v2/aws"
    10  	"github.com/aws/aws-sdk-go-v2/config"
    11  	"github.com/aws/aws-sdk-go-v2/service/s3"
    12  	awsl "github.com/aws/smithy-go/logging"
    13  
    14  	"github.com/letsencrypt/boulder/cmd"
    15  	"github.com/letsencrypt/boulder/crl/storer"
    16  	cspb "github.com/letsencrypt/boulder/crl/storer/proto"
    17  	"github.com/letsencrypt/boulder/features"
    18  	bgrpc "github.com/letsencrypt/boulder/grpc"
    19  	"github.com/letsencrypt/boulder/issuance"
    20  	blog "github.com/letsencrypt/boulder/log"
    21  )
    22  
    23  type Config struct {
    24  	CRLStorer struct {
    25  		cmd.ServiceConfig
    26  
    27  		// IssuerCerts is a list of paths to issuer certificates on disk. These will
    28  		// be used to validate the CRLs received by this service before uploading
    29  		// them.
    30  		IssuerCerts []string `validate:"min=1,dive,required"`
    31  
    32  		// S3Endpoint is the URL at which the S3-API-compatible object storage
    33  		// service can be reached. This can be used to point to a non-Amazon storage
    34  		// service, or to point to a fake service for testing. It should be left
    35  		// blank by default.
    36  		S3Endpoint string
    37  		// S3Bucket is the AWS Bucket that uploads should go to. Must be created
    38  		// (and have appropriate permissions set) beforehand.
    39  		S3Bucket string
    40  		// AWSConfigFile is the path to a file on disk containing an AWS config.
    41  		// The format of the configuration file is specified at
    42  		// https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html.
    43  		AWSConfigFile string
    44  		// AWSCredsFile is the path to a file on disk containing AWS credentials.
    45  		// The format of the credentials file is specified at
    46  		// https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html.
    47  		AWSCredsFile string
    48  
    49  		Features map[string]bool
    50  	}
    51  
    52  	Syslog        cmd.SyslogConfig
    53  	OpenTelemetry cmd.OpenTelemetryConfig
    54  }
    55  
    56  // awsLogger implements the github.com/aws/smithy-go/logging.Logger interface.
    57  type awsLogger struct {
    58  	blog.Logger
    59  }
    60  
    61  func (log awsLogger) Logf(c awsl.Classification, format string, v ...interface{}) {
    62  	switch c {
    63  	case awsl.Debug:
    64  		log.Debugf(format, v...)
    65  	case awsl.Warn:
    66  		log.Warningf(format, v...)
    67  	}
    68  }
    69  
    70  func main() {
    71  	configFile := flag.String("config", "", "File path to the configuration file for this service")
    72  	flag.Parse()
    73  	if *configFile == "" {
    74  		flag.Usage()
    75  		os.Exit(1)
    76  	}
    77  
    78  	var c Config
    79  	err := cmd.ReadConfigFile(*configFile, &c)
    80  	cmd.FailOnError(err, "Reading JSON config file into config structure")
    81  
    82  	err = features.Set(c.CRLStorer.Features)
    83  	cmd.FailOnError(err, "Failed to set feature flags")
    84  
    85  	scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.CRLStorer.DebugAddr)
    86  	defer oTelShutdown(context.Background())
    87  	logger.Info(cmd.VersionString())
    88  	clk := cmd.Clock()
    89  
    90  	tlsConfig, err := c.CRLStorer.TLS.Load(scope)
    91  	cmd.FailOnError(err, "TLS config")
    92  
    93  	issuers := make([]*issuance.Certificate, 0, len(c.CRLStorer.IssuerCerts))
    94  	for _, filepath := range c.CRLStorer.IssuerCerts {
    95  		cert, err := issuance.LoadCertificate(filepath)
    96  		cmd.FailOnError(err, "Failed to load issuer cert")
    97  		issuers = append(issuers, cert)
    98  	}
    99  
   100  	// Load the "default" AWS configuration, but override the set of config and
   101  	// credential files it reads from to just those specified in our JSON config,
   102  	// to ensure that it's not accidentally reading anything from the homedir or
   103  	// its other default config locations.
   104  	awsConfig, err := config.LoadDefaultConfig(
   105  		context.Background(),
   106  		config.WithSharedConfigFiles([]string{c.CRLStorer.AWSConfigFile}),
   107  		config.WithSharedCredentialsFiles([]string{c.CRLStorer.AWSCredsFile}),
   108  		config.WithHTTPClient(new(http.Client)),
   109  		config.WithLogger(awsLogger{logger}),
   110  		config.WithClientLogMode(aws.LogRequestEventMessage|aws.LogResponseEventMessage),
   111  	)
   112  	cmd.FailOnError(err, "Failed to load AWS config")
   113  
   114  	s3opts := make([]func(*s3.Options), 0)
   115  	if c.CRLStorer.S3Endpoint != "" {
   116  		s3opts = append(
   117  			s3opts,
   118  			s3.WithEndpointResolver(s3.EndpointResolverFromURL(c.CRLStorer.S3Endpoint)),
   119  			func(o *s3.Options) { o.UsePathStyle = true },
   120  		)
   121  	}
   122  	s3client := s3.NewFromConfig(awsConfig, s3opts...)
   123  
   124  	csi, err := storer.New(issuers, s3client, c.CRLStorer.S3Bucket, scope, logger, clk)
   125  	cmd.FailOnError(err, "Failed to create CRLStorer impl")
   126  
   127  	start, err := bgrpc.NewServer(c.CRLStorer.GRPC, logger).Add(
   128  		&cspb.CRLStorer_ServiceDesc, csi).Build(tlsConfig, scope, clk)
   129  	cmd.FailOnError(err, "Unable to setup CRLStorer gRPC server")
   130  
   131  	cmd.FailOnError(start(), "CRLStorer gRPC service failed")
   132  }
   133  
   134  func init() {
   135  	cmd.RegisterCommand("crl-storer", main, &cmd.ConfigValidator{Config: &Config{}})
   136  }
   137  

View as plain text