cmd

package
v0.0.0-...-3baac6f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 15, 2024 License: MPL-2.0 Imports: 44 Imported by: 958

Documentation

Overview

Package cmd provides utilities that underlie the specific commands.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuditPanic

func AuditPanic()

AuditPanic catches and logs panics, then exits with exit code 1. This method should be called in a defer statement as early as possible.

func AvailableCommands

func AvailableCommands() []string

func AvailableConfigValidators

func AvailableConfigValidators() []string

AvailableConfigValidators returns a list of Boulder component names for which a *ConfigValidator has been registered.

func CatchSignals

func CatchSignals(callback func())

CatchSignals blocks until a SIGTERM, SIGINT, or SIGHUP is received, then executes the given callback. The callback should not block, it should simply signal other goroutines (particularly the main goroutine) to clean themselves up and exit. This function is intended to be called in its own goroutine, while the main goroutine waits for an indication that the other goroutines have exited cleanly.

func Clock

func Clock() clock.Clock

Clock functions similarly to clock.New(), but the returned value can be changed using the FAKECLOCK environment variable if the 'integration' build flag is set.

This function returns the default Clock.

func Fail

func Fail(msg string)

Fail raises a panic with a special type that causes `AuditPanic` to audit log the provided message and then exit nonzero (without printing a stack trace).

func FailOnError

func FailOnError(err error, msg string)

FailOnError calls Fail if the provided error is non-nil. This is useful for one-line error handling in top-level executables, but should generally be avoided in libraries. The message argument is optional.

func LookupCommand

func LookupCommand(name string) func()

func NewLogger

func NewLogger(logConf SyslogConfig) blog.Logger

NewLogger creates a logger object with the provided settings, sets it as the global logger, and returns it.

It also sets the logging systems for various packages we use to go through the created logger, and sets up a periodic log event for the current timestamp.

func NewOpenTelemetry

func NewOpenTelemetry(config OpenTelemetryConfig, logger blog.Logger) func(ctx context.Context)

NewOpenTelemetry sets up our OpenTelemetry tracing It returns a graceful shutdown function to be deferred.

func ReadConfigFile

func ReadConfigFile(filename string, out interface{}) error

ReadConfigFile takes a file path as an argument and attempts to unmarshal the content of the file into a struct containing a configuration of a boulder component. Any config keys in the JSON file which do not correspond to expected keys in the config struct will result in errors.

func RegisterCommand

func RegisterCommand(name string, f func(), cv *ConfigValidator)

RegisterCommand registers a subcommand and its corresponding config validator. The provided func() is called when the subcommand is invoked on the command line. The ConfigValidator is optional and used to validate the config file for the subcommand.

func StatsAndLogging

func StatsAndLogging(logConf SyslogConfig, otConf OpenTelemetryConfig, addr string) (prometheus.Registerer, blog.Logger, func(context.Context))

StatsAndLogging sets up an AuditLogger, Prometheus Registerer, and OpenTelemetry tracing. It returns the Registerer and AuditLogger, along with a graceful shutdown function to be deferred.

It spawns off an HTTP server on the provided port to report the stats and provide pprof profiling handlers.

The constructed AuditLogger as the default logger, and configures the mysql and grpc packages to use our logger. This must be called before any gRPC code is called, because gRPC's SetLogger doesn't use any locking.

This function does not return an error, and will panic on problems.

func ValidateJSONConfig

func ValidateJSONConfig(cv *ConfigValidator, in io.Reader) error

ValidateJSONConfig takes a *ConfigValidator and an io.Reader containing a JSON representation of a config. The JSON data is unmarshaled into the *ConfigValidator's inner Config and then validated according to the 'validate' tags for on each field. Callers can use cmd.LookupConfigValidator to get a *ConfigValidator for a given Boulder component. This is exported for use in SRE CI tooling.

func ValidateYAMLConfig

func ValidateYAMLConfig(cv *ConfigValidator, in io.Reader) error

ValidateYAMLConfig takes a *ConfigValidator and an io.Reader containing a YAML representation of a config. The YAML data is unmarshaled into the *ConfigValidator's inner Config and then validated according to the 'validate' tags for on each field. Callers can use cmd.LookupConfigValidator to get a *ConfigValidator for a given Boulder component. This is exported for use in SRE CI tooling.

func VersionString

func VersionString() string

VersionString produces a friendly Application version string.

func WaitForSignal

func WaitForSignal()

WaitForSignal blocks until a SIGTERM, SIGINT, or SIGHUP is received. It then returns, allowing execution to resume, generally allowing a main() function to return and trigger and deferred cleanup functions. This function is intended to be called directly from the main goroutine, while a gRPC or HTTP server runs in a background goroutine.

Types

type ConfigValidator

type ConfigValidator struct {
	Config     interface{}
	Validators map[string]validator.Func
}

func LookupConfigValidator

func LookupConfigValidator(name string) *ConfigValidator

LookupConfigValidator constructs an instance of the *ConfigValidator for the given Boulder component name. If no *ConfigValidator was registered, nil is returned.

type DBConfig

type DBConfig struct {
	// A file containing a connect URL for the DB.
	DBConnectFile string `validate:"required"`

	// MaxOpenConns sets the maximum number of open connections to the
	// database. If MaxIdleConns is greater than 0 and MaxOpenConns is
	// less than MaxIdleConns, then MaxIdleConns will be reduced to
	// match the new MaxOpenConns limit. If n < 0, then there is no
	// limit on the number of open connections.
	MaxOpenConns int `validate:"min=-1"`

	// MaxIdleConns sets the maximum number of connections in the idle
	// connection pool. If MaxOpenConns is greater than 0 but less than
	// MaxIdleConns, then MaxIdleConns will be reduced to match the
	// MaxOpenConns limit. If n < 0, no idle connections are retained.
	MaxIdleConns int `validate:"min=-1"`

	// ConnMaxLifetime sets the maximum amount of time a connection may
	// be reused. Expired connections may be closed lazily before reuse.
	// If d < 0, connections are not closed due to a connection's age.
	ConnMaxLifetime config.Duration `validate:"-"`

	// ConnMaxIdleTime sets the maximum amount of time a connection may
	// be idle. Expired connections may be closed lazily before reuse.
	// If d < 0, connections are not closed due to a connection's idle
	// time.
	ConnMaxIdleTime config.Duration `validate:"-"`
}

DBConfig defines how to connect to a database. The connect string is stored in a file separate from the config, because it can contain a password, which we want to keep out of configs.

func (*DBConfig) URL

func (d *DBConfig) URL() (string, error)

URL returns the DBConnect URL represented by this DBConfig object, loading it from the file on disk. Leading and trailing whitespace is stripped.

type DNSProvider

type DNSProvider struct {
	// DNSAuthority is the single <hostname|IPv4|[IPv6]>:<port> of the DNS
	// server to be used for resolution of DNS backends. If the address contains
	// a hostname it will be resolved via the system DNS. If the port is left
	// unspecified it will default to '53'. If this field is left unspecified
	// the system DNS will be used for resolution of DNS backends.
	DNSAuthority string `validate:"required,ip|hostname|hostname_port"`

	// SRVLookup contains the service and domain name used to construct a SRV
	// DNS query to lookup DNS backends. 'Domain' is required. 'Service' is
	// optional and will be defaulted to 'dns' if left unspecified.
	//
	// Usage: If the resource record is 'unbound.service.consul', then the
	// 'Service' is 'unbound' and the 'Domain' is 'service.consul'. The expected
	// dNSName to be authenticated in the server certificate would be
	// 'unbound.service.consul'. The 'proto' field of the SRV record MUST
	// contain 'udp' and the 'port' field MUST be a valid port. In a Consul
	// configuration file you would specify 'unbound.service.consul' as:
	//
	// services {
	//   id      = "unbound-1" // Must be unique
	//   name    = "unbound"
	//   address = "10.77.77.77"
	//   port    = 8053
	//   tags    = ["udp"]
	// }
	//
	// services {
	//   id      = "unbound-2" // Must be unique
	//   name    = "unbound"
	//   address = "10.77.77.77"
	//   port    = 8153
	//   tags    = ["udp"]
	// }
	//
	// If you've added the above to your Consul configuration file (and reloaded
	// Consul) then you should be able to resolve the following dig query:
	//
	// $ dig @10.55.55.10 -t SRV _unbound._udp.service.consul +short
	// 1 1 8053 0a4d4d4d.addr.dc1.consul.
	// 1 1 8153 0a4d4d4d.addr.dc1.consul.
	SRVLookup ServiceDomain `validate:"required"`
}

DNSProvider contains the configuration for a DNS provider in the bdns package which supports dynamic reloading of its backends.

type GRPCClientConfig

type GRPCClientConfig struct {
	// DNSAuthority is a single <hostname|IPv4|[IPv6]>:<port> of the DNS server
	// to be used for resolution of gRPC backends. If the address contains a
	// hostname the gRPC client will resolve it via the system DNS. If the
	// address contains a port, the client will use it directly, otherwise port
	// 53 is used.
	DNSAuthority string `validate:"required_with=SRVLookup SRVLookups,omitempty,ip|hostname|hostname_port"`

	// SRVLookup contains the service and domain name the gRPC client will use
	// to construct a SRV DNS query to lookup backends. For example: if the
	// resource record is 'foo.service.consul', then the 'Service' is 'foo' and
	// the 'Domain' is 'service.consul'. The expected dNSName to be
	// authenticated in the server certificate would be 'foo.service.consul'.
	//
	// Note: The 'proto' field of the SRV record MUST contain 'tcp' and the
	// 'port' field MUST be a valid port. In a Consul configuration file you
	// would specify 'foo.service.consul' as:
	//
	// services {
	//   id      = "some-unique-id-1"
	//   name    = "foo"
	//   address = "10.77.77.77"
	//   port    = 8080
	//   tags    = ["tcp"]
	// }
	// services {
	//   id      = "some-unique-id-2"
	//   name    = "foo"
	//   address = "10.77.77.77"
	//   port    = 8180
	//   tags    = ["tcp"]
	// }
	//
	// If you've added the above to your Consul configuration file (and reloaded
	// Consul) then you should be able to resolve the following dig query:
	//
	// $ dig @10.55.55.10 -t SRV _foo._tcp.service.consul +short
	// 1 1 8080 0a585858.addr.dc1.consul.
	// 1 1 8080 0a4d4d4d.addr.dc1.consul.
	SRVLookup *ServiceDomain `validate:"required_without_all=SRVLookups ServerAddress ServerIPAddresses"`

	// SRVLookups allows you to pass multiple SRV records to the gRPC client.
	// The gRPC client will resolves each SRV record and use the results to
	// construct a list of backends to connect to. For more details, see the
	// documentation for the SRVLookup field. Note: while you can pass multiple
	// targets to the gRPC client using this field, all of the targets will use
	// the same HostOverride and TLS configuration.
	SRVLookups []*ServiceDomain `validate:"required_without_all=SRVLookup ServerAddress ServerIPAddresses"`

	// SRVResolver is an optional override to indicate that a specific
	// implementation of the SRV resolver should be used. The default is 'srv'
	// For more details, see the documentation in:
	// grpc/internal/resolver/dns/dns_resolver.go.
	SRVResolver string `validate:"excluded_with=ServerAddress ServerIPAddresses,isdefault|oneof=srv nonce-srv"`

	// ServerAddress is a single <hostname|IPv4|[IPv6]>:<port> or `:<port>` that
	// the gRPC client will, if necessary, resolve via DNS and then connect to.
	// If the address provided is 'foo.service.consul:8080' then the dNSName to
	// be authenticated in the server certificate would be 'foo.service.consul'.
	//
	// In a Consul configuration file you would specify 'foo.service.consul' as:
	//
	// services {
	//   id      = "some-unique-id-1"
	//   name    = "foo"
	//   address = "10.77.77.77"
	// }
	// services {
	//   id      = "some-unique-id-2"
	//   name    = "foo"
	//   address = "10.88.88.88"
	// }
	//
	// If you've added the above to your Consul configuration file (and reloaded
	// Consul) then you should be able to resolve the following dig query:
	//
	// $ dig A @10.55.55.10 foo.service.consul +short
	// 10.77.77.77
	// 10.88.88.88
	ServerAddress string `validate:"required_without_all=ServerIPAddresses SRVLookup SRVLookups,omitempty,hostname_port"`

	// ServerIPAddresses is a comma separated list of IP addresses, in the
	// format `<IPv4|[IPv6]>:<port>` or `:<port>`, that the gRPC client will
	// connect to. If the addresses provided are ["10.77.77.77", "10.88.88.88"]
	// then the iPAddress' to be authenticated in the server certificate would
	// be '10.77.77.77' and '10.88.88.88'.
	ServerIPAddresses []string `validate:"required_without_all=ServerAddress SRVLookup SRVLookups,omitempty,dive,hostname_port"`

	// HostOverride is an optional override for the dNSName the client will
	// verify in the certificate presented by the server.
	HostOverride string `validate:"excluded_with=ServerIPAddresses,omitempty,hostname"`
	Timeout      config.Duration

	// NoWaitForReady turns off our (current) default of setting grpc.WaitForReady(true).
	// This means if all of a GRPC client's backends are down, it will error immediately.
	// The current default, grpc.WaitForReady(true), means that if all of a GRPC client's
	// backends are down, it will wait until either one becomes available or the RPC
	// times out.
	NoWaitForReady bool
}

GRPCClientConfig contains the information necessary to setup a gRPC client connection. The following field combinations are allowed:

ServerIPAddresses, [Timeout] ServerAddress, DNSAuthority, [Timeout], [HostOverride] SRVLookup, DNSAuthority, [Timeout], [HostOverride], [SRVResolver] SRVLookups, DNSAuthority, [Timeout], [HostOverride], [SRVResolver]

func (*GRPCClientConfig) MakeTargetAndHostOverride

func (c *GRPCClientConfig) MakeTargetAndHostOverride() (string, string, error)

MakeTargetAndHostOverride constructs the target URI that the gRPC client will connect to and the hostname (only for 'ServerAddress' and 'SRVLookup') that will be validated during the mTLS handshake. An error is returned if the provided configuration is invalid.

type GRPCServerConfig

type GRPCServerConfig struct {
	Address string `json:"address" validate:"omitempty,hostname_port"`
	// Services is a map of service names to configuration specific to that service.
	// These service names must match the service names advertised by gRPC itself,
	// which are identical to the names set in our gRPC .proto files prefixed by
	// the package names set in those files (e.g. "ca.CertificateAuthority").
	Services map[string]GRPCServiceConfig `json:"services" validate:"required,dive,required"`
	// MaxConnectionAge specifies how long a connection may live before the server sends a GoAway to the
	// client. Because gRPC connections re-resolve DNS after a connection close,
	// this controls how long it takes before a client learns about changes to its
	// backends.
	// https://pkg.go.dev/google.golang.org/grpc/keepalive#ServerParameters
	MaxConnectionAge config.Duration `validate:"required"`
}

GRPCServerConfig contains the information needed to start a gRPC server.

type GRPCServiceConfig

type GRPCServiceConfig struct {
	// PerServiceClientNames is a map of gRPC service names to client certificate
	// SANs. The upstream listening server will reject connections from clients
	// which do not appear in this list, and the server interceptor will reject
	// RPC calls for this service from clients which are not listed here.
	ClientNames []string `json:"clientNames" validate:"min=1,dive,hostname,required"`
}

GRPCServiceConfig contains the information needed to configure a gRPC service.

type HMACKeyConfig

type HMACKeyConfig struct {
	KeyFile string `validate:"required"`
}

HMACKeyConfig specifies a path to a file containing an HMAC key. The key must consist of 256 bits of random data to be suitable for use as a 256-bit hashing key (e.g., the output of `openssl rand -hex 32`).

func (*HMACKeyConfig) Load

func (hc *HMACKeyConfig) Load() ([]byte, error)

Load loads the HMAC key from the file, ensures it is exactly 32 characters in length, and returns it as a byte slice.

type HostnamePolicyConfig

type HostnamePolicyConfig struct {
	HostnamePolicyFile string `validate:"required"`
}

HostnamePolicyConfig specifies a file from which to load a policy regarding what hostnames to issue for.

type OpenTelemetryConfig

type OpenTelemetryConfig struct {
	// Endpoint to connect to with the OTLP protocol over gRPC.
	// It should be of the form "localhost:4317"
	//
	// It always connects over plaintext, and so is only intended to connect
	// to a local OpenTelemetry collector. This should not be used over an
	// insecure network.
	Endpoint string

	// SampleRatio is the ratio of new traces to head sample.
	// This only affects new traces without a parent with its own sampling
	// decision, and otherwise use the parent's sampling decision.
	//
	// Set to something between 0 and 1, where 1 is sampling all traces.
	// This is primarily meant as a pressure relief if the Endpoint we connect to
	// is being overloaded, and we otherwise handle sampling in the collectors.
	// See otel trace.ParentBased and trace.TraceIDRatioBased for details.
	SampleRatio float64
}

OpenTelemetryConfig configures tracing via OpenTelemetry. To enable tracing, set a nonzero SampleRatio and configure an Endpoint

type OpenTelemetryHTTPConfig

type OpenTelemetryHTTPConfig struct {
	// TrustIncomingSpans should only be set true if there's a trusted service
	// connecting to Boulder, such as a load balancer that's tracing-aware.
	// If false, the default, incoming traces won't be set as the parent.
	// See otelhttp.WithPublicEndpoint
	TrustIncomingSpans bool
}

OpenTelemetryHTTPConfig configures the otelhttp server tracing.

func (*OpenTelemetryHTTPConfig) Options

func (c *OpenTelemetryHTTPConfig) Options() []otelhttp.Option

Options returns the otelhttp options for this configuration. They can be passed to otelhttp.NewHandler or Boulder's wrapper, measured_http.New.

type PAConfig

type PAConfig struct {
	DBConfig   `validate:"-"`
	Challenges map[core.AcmeChallenge]bool `validate:"omitempty,dive,keys,oneof=http-01 dns-01 tls-alpn-01,endkeys"`
}

PAConfig specifies how a policy authority should connect to its database, what policies it should enforce, and what challenges it should offer.

func (PAConfig) CheckChallenges

func (pc PAConfig) CheckChallenges() error

CheckChallenges checks whether the list of challenges in the PA config actually contains valid challenge names

type PasswordConfig

type PasswordConfig struct {
	PasswordFile string `validate:"required"`
}

PasswordConfig contains a path to a file containing a password.

func (*PasswordConfig) Pass

func (pc *PasswordConfig) Pass() (string, error)

Pass returns a password, extracted from the PasswordConfig's PasswordFile

type SMTPConfig

type SMTPConfig struct {
	PasswordConfig
	Server   string `validate:"required"`
	Port     string `validate:"required,numeric,min=1,max=65535"`
	Username string `validate:"required"`
}

type ServiceConfig

type ServiceConfig struct {
	// DebugAddr is the address to run the /debug handlers on.
	DebugAddr string `validate:"omitempty,hostname_port"`
	GRPC      *GRPCServerConfig
	TLS       TLSConfig

	// HealthCheckInterval is the duration between deep health checks of the
	// service. Defaults to 5 seconds.
	HealthCheckInterval config.Duration `validate:"-"`
}

ServiceConfig contains config items that are common to all our services, to be embedded in other config structs.

type ServiceDomain

type ServiceDomain struct {
	// Service is the service name to be used for SRV lookups. For example: if
	// record is 'foo.service.consul', then the Service is 'foo'.
	Service string `validate:"required"`

	// Domain is the domain name to be used for SRV lookups. For example: if the
	// record is 'foo.service.consul', then the Domain is 'service.consul'.
	Domain string `validate:"required"`
}

ServiceDomain contains the service and domain name the gRPC or bdns provider will use to construct a SRV DNS query to lookup backends.

type SyslogConfig

type SyslogConfig struct {
	// When absent or zero, this causes no logs to be emitted on stdout/stderr.
	// Errors and warnings will be emitted on stderr if the configured level
	// allows.
	StdoutLevel int `validate:"min=-1,max=7"`
	// When absent or zero, this defaults to logging all messages of level 6
	// or below. To disable syslog logging entirely, set this to -1.
	SyslogLevel int `validate:"min=-1,max=7"`
}

SyslogConfig defines the config for syslogging. 3 means "error", 4 means "warning", 6 is "info" and 7 is "debug". Configuring a given level causes all messages at that level and below to be logged.

type TLSConfig

type TLSConfig struct {
	CertFile string `validate:"required"`
	KeyFile  string `validate:"required"`
	// The CACertFile file may contain any number of root certificates and will
	// be deduplicated internally.
	CACertFile string `validate:"required"`
}

TLSConfig represents certificates and a key for authenticated TLS.

func (*TLSConfig) Load

func (t *TLSConfig) Load(scope prometheus.Registerer) (*tls.Config, error)

Load reads and parses the certificates and key listed in the TLSConfig, and returns a *tls.Config suitable for either client or server use. The CACertFile file may contain any number of root certificates and will be deduplicated internally. Prometheus metrics for various certificate fields will be exported.

Directories

Path Synopsis
Package main provides the "admin" tool, which can perform various administrative actions (such as revoking certificates) against a Boulder deployment.
Package main provides the "admin" tool, which can perform various administrative actions (such as revoking certificates) against a Boulder deployment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL