Merge pull request #862 from smallstep/startup-info

Print some basic configuration info on startup
This commit is contained in:
Carl Tashian 2022-04-05 15:33:59 -07:00 committed by GitHub
commit 949c29d7db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 3 deletions

View File

@ -80,6 +80,14 @@ type Authority struct {
adminMutex sync.RWMutex adminMutex sync.RWMutex
} }
type Info struct {
StartTime time.Time
RootX509Certs []*x509.Certificate
SSHCAUserPublicKey []byte
SSHCAHostPublicKey []byte
DNSNames []string
}
// New creates and initiates a new Authority type. // New creates and initiates a new Authority type.
func New(cfg *config.Config, opts ...Option) (*Authority, error) { func New(cfg *config.Config, opts ...Option) (*Authority, error) {
err := cfg.Validate() err := cfg.Validate()
@ -294,8 +302,6 @@ func (a *Authority) init() error {
return err return err
} }
a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate) a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate)
sum := sha256.Sum256(resp.RootCertificate.Raw)
log.Printf("Using root fingerprint '%s'", hex.EncodeToString(sum[:]))
} }
} }
@ -561,6 +567,21 @@ func (a *Authority) GetAdminDatabase() admin.DB {
return a.adminDB return a.adminDB
} }
func (a *Authority) GetInfo() Info {
ai := Info{
StartTime: a.startTime,
RootX509Certs: a.rootX509Certs,
DNSNames: a.config.DNSNames,
}
if a.sshCAUserCertSignKey != nil {
ai.SSHCAUserPublicKey = ssh.MarshalAuthorizedKey(a.sshCAUserCertSignKey.PublicKey())
}
if a.sshCAHostCertSignKey != nil {
ai.SSHCAHostPublicKey = ssh.MarshalAuthorizedKey(a.sshCAHostCertSignKey.PublicKey())
}
return ai
}
// IsAdminAPIEnabled returns a boolean indicating whether the Admin API has // IsAdminAPIEnabled returns a boolean indicating whether the Admin API has
// been enabled. // been enabled.
func (a *Authority) IsAdminAPIEnabled() bool { func (a *Authority) IsAdminAPIEnabled() bool {

View File

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"reflect" "reflect"
"strings"
"sync" "sync"
"github.com/go-chi/chi" "github.com/go-chi/chi"
@ -26,11 +27,14 @@ import (
scepAPI "github.com/smallstep/certificates/scep/api" scepAPI "github.com/smallstep/certificates/scep/api"
"github.com/smallstep/certificates/server" "github.com/smallstep/certificates/server"
"github.com/smallstep/nosql" "github.com/smallstep/nosql"
"go.step.sm/cli-utils/step"
"go.step.sm/crypto/x509util"
) )
type options struct { type options struct {
configFile string configFile string
linkedCAToken string linkedCAToken string
quiet bool
password []byte password []byte
issuerPassword []byte issuerPassword []byte
sshHostPassword []byte sshHostPassword []byte
@ -101,6 +105,13 @@ func WithLinkedCAToken(token string) Option {
} }
} }
// WithQuiet sets the quiet flag.
func WithQuiet(quiet bool) Option {
return func(o *options) {
o.quiet = quiet
}
}
// CA is the type used to build the complete certificate authority. It builds // CA is the type used to build the complete certificate authority. It builds
// the HTTP server, set ups the middlewares and the HTTP handlers. // the HTTP server, set ups the middlewares and the HTTP handlers.
type CA struct { type CA struct {
@ -288,6 +299,35 @@ func (ca *CA) Run() error {
var wg sync.WaitGroup var wg sync.WaitGroup
errs := make(chan error, 1) errs := make(chan error, 1)
if !ca.opts.quiet {
authorityInfo := ca.auth.GetInfo()
log.Printf("Starting %s", step.Version())
log.Printf("Documentation: https://u.step.sm/docs/ca")
log.Printf("Community Discord: https://u.step.sm/discord")
if step.Contexts().GetCurrent() != nil {
log.Printf("Current context: %s", step.Contexts().GetCurrent().Name)
}
log.Printf("Config file: %s", ca.opts.configFile)
baseURL := fmt.Sprintf("https://%s%s",
authorityInfo.DNSNames[0],
ca.config.Address[strings.LastIndex(ca.config.Address, ":"):])
log.Printf("The primary server URL is %s", baseURL)
log.Printf("Root certificates are available at %s/roots.pem", baseURL)
if len(authorityInfo.DNSNames) > 1 {
log.Printf("Additional configured hostnames: %s",
strings.Join(authorityInfo.DNSNames[1:], ", "))
}
for _, crt := range authorityInfo.RootX509Certs {
log.Printf("X.509 Root Fingerprint: %s", x509util.Fingerprint(crt))
}
if authorityInfo.SSHCAHostPublicKey != nil {
log.Printf("SSH Host CA Key is %s\n", authorityInfo.SSHCAHostPublicKey)
}
if authorityInfo.SSHCAUserPublicKey != nil {
log.Printf("SSH User CA Key: %s\n", authorityInfo.SSHCAUserPublicKey)
}
}
if ca.insecureSrv != nil { if ca.insecureSrv != nil {
wg.Add(1) wg.Add(1)
go func() { go func() {
@ -355,6 +395,7 @@ func (ca *CA) Reload() error {
WithSSHUserPassword(ca.opts.sshUserPassword), WithSSHUserPassword(ca.opts.sshUserPassword),
WithIssuerPassword(ca.opts.issuerPassword), WithIssuerPassword(ca.opts.issuerPassword),
WithLinkedCAToken(ca.opts.linkedCAToken), WithLinkedCAToken(ca.opts.linkedCAToken),
WithQuiet(ca.opts.quiet),
WithConfigFile(ca.opts.configFile), WithConfigFile(ca.opts.configFile),
WithDatabase(ca.auth.GetDatabase()), WithDatabase(ca.auth.GetDatabase()),
) )

View File

@ -58,6 +58,11 @@ certificate issuer private key used in the RA mode.`,
Usage: "token used to enable the linked ca.", Usage: "token used to enable the linked ca.",
EnvVar: "STEP_CA_TOKEN", EnvVar: "STEP_CA_TOKEN",
}, },
cli.BoolFlag{
Name: "quiet",
Usage: "disable startup information",
EnvVar: "STEP_CA_QUIET",
},
cli.StringFlag{ cli.StringFlag{
Name: "context", Name: "context",
Usage: "The name of the authority's context.", Usage: "The name of the authority's context.",
@ -74,6 +79,7 @@ func appAction(ctx *cli.Context) error {
issuerPassFile := ctx.String("issuer-password-file") issuerPassFile := ctx.String("issuer-password-file")
resolver := ctx.String("resolver") resolver := ctx.String("resolver")
token := ctx.String("token") token := ctx.String("token")
quiet := ctx.Bool("quiet")
if ctx.NArg() > 1 { if ctx.NArg() > 1 {
return errs.TooManyArguments(ctx) return errs.TooManyArguments(ctx)
@ -155,7 +161,8 @@ To get a linked authority token:
ca.WithSSHHostPassword(sshHostPassword), ca.WithSSHHostPassword(sshHostPassword),
ca.WithSSHUserPassword(sshUserPassword), ca.WithSSHUserPassword(sshUserPassword),
ca.WithIssuerPassword(issuerPassword), ca.WithIssuerPassword(issuerPassword),
ca.WithLinkedCAToken(token)) ca.WithLinkedCAToken(token),
ca.WithQuiet(quiet))
if err != nil { if err != nil {
fatal(err) fatal(err)
} }