mirror of https://github.com/caddyserver/caddy.git
pki: Add trust subcommand to install root cert (closes #3204)
This commit is contained in:
parent
904d9cab39
commit
244b839f98
2
caddy.go
2
caddy.go
|
@ -372,7 +372,7 @@ func run(newCfg *Config, start bool) error {
|
|||
}
|
||||
|
||||
if newCfg.storage == nil {
|
||||
newCfg.storage = &certmagic.FileStorage{Path: AppDataDir()}
|
||||
newCfg.storage = DefaultStorage
|
||||
}
|
||||
certmagic.Default.Storage = newCfg.storage
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/smallstep/truststore"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -323,6 +324,27 @@ func (ca CA) newReplacer() *caddy.Replacer {
|
|||
return repl
|
||||
}
|
||||
|
||||
// installRoot installs this CA's root certificate into the
|
||||
// local trust store(s) if it is not already trusted. The CA
|
||||
// must already be provisioned.
|
||||
func (ca CA) installRoot() error {
|
||||
// avoid password prompt if already trusted
|
||||
if trusted(ca.root) {
|
||||
ca.log.Info("root certificate is already trusted by system",
|
||||
zap.String("path", ca.rootCertPath))
|
||||
return nil
|
||||
}
|
||||
|
||||
ca.log.Warn("installing root certificate (you might be prompted for password)",
|
||||
zap.String("path", ca.rootCertPath))
|
||||
|
||||
return truststore.Install(ca.root,
|
||||
truststore.WithDebug(),
|
||||
truststore.WithFirefox(),
|
||||
truststore.WithJava(),
|
||||
)
|
||||
}
|
||||
|
||||
const (
|
||||
defaultCAID = "local"
|
||||
defaultCAName = "Caddy Local Authority"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package caddypki
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -26,6 +27,25 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
caddycmd.RegisterCommand(caddycmd.Command{
|
||||
Name: "trust",
|
||||
Func: cmdTrust,
|
||||
Short: "Installs a CA certificate into local trust stores",
|
||||
Long: `
|
||||
Adds a root certificate into the local trust stores. Intended for
|
||||
development environments only.
|
||||
|
||||
Since Caddy will install its root certificates into the local trust
|
||||
stores automatically when they are first generated, this command is
|
||||
only necessary if you need to pre-install the certificates before
|
||||
using them; for example, if you have elevated privileges at one
|
||||
point but not later, you will want to use this command so that a
|
||||
password prompt is not required later.
|
||||
|
||||
This command installs the root certificate only for Caddy's
|
||||
default CA.`,
|
||||
})
|
||||
|
||||
caddycmd.RegisterCommand(caddycmd.Command{
|
||||
Name: "untrust",
|
||||
Func: cmdUntrust,
|
||||
|
@ -57,6 +77,30 @@ If no flags are specified, --ca=local is assumed.`,
|
|||
})
|
||||
}
|
||||
|
||||
func cmdTrust(fs caddycmd.Flags) (int, error) {
|
||||
// we have to create a sort of dummy context so that
|
||||
// the CA can provision itself...
|
||||
ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()})
|
||||
defer cancel()
|
||||
|
||||
// provision the CA, which generates and stores a root
|
||||
// certificate if one doesn't already exist in storage
|
||||
ca := CA{
|
||||
storage: caddy.DefaultStorage,
|
||||
}
|
||||
err := ca.Provision(ctx, defaultCAID, caddy.Log())
|
||||
if err != nil {
|
||||
return caddy.ExitCodeFailedStartup, err
|
||||
}
|
||||
|
||||
err = ca.installRoot()
|
||||
if err != nil {
|
||||
return caddy.ExitCodeFailedStartup, err
|
||||
}
|
||||
|
||||
return caddy.ExitCodeSuccess, nil
|
||||
}
|
||||
|
||||
func cmdUntrust(fs caddycmd.Flags) (int, error) {
|
||||
ca := fs.String("ca")
|
||||
cert := fs.String("cert")
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/smallstep/truststore"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -71,30 +70,15 @@ func (p *PKI) Start() error {
|
|||
// install roots to trust store, if not disabled
|
||||
for _, ca := range p.CAs {
|
||||
if ca.InstallTrust != nil && !*ca.InstallTrust {
|
||||
ca.log.Warn("root certificate trust store installation disabled; local clients may show warnings",
|
||||
ca.log.Warn("root certificate trust store installation disabled; unconfigured clients may show warnings",
|
||||
zap.String("path", ca.rootCertPath))
|
||||
continue
|
||||
}
|
||||
|
||||
// avoid password prompt if already trusted
|
||||
if trusted(ca.root) {
|
||||
ca.log.Info("root certificate is already trusted by system",
|
||||
zap.String("path", ca.rootCertPath))
|
||||
continue
|
||||
}
|
||||
|
||||
ca.log.Warn("trusting root certificate (you might be prompted for password)",
|
||||
zap.String("path", ca.rootCertPath))
|
||||
|
||||
err := truststore.Install(ca.root,
|
||||
truststore.WithDebug(),
|
||||
truststore.WithFirefox(),
|
||||
truststore.WithJava(),
|
||||
)
|
||||
if err != nil {
|
||||
if err := ca.installRoot(); err != nil {
|
||||
// could be some system dependencies that are missing;
|
||||
// shouldn't totally prevent startup, but we should log it
|
||||
p.log.Error("failed to install root certificate",
|
||||
ca.log.Error("failed to install root certificate",
|
||||
zap.Error(err),
|
||||
zap.String("certificate_file", ca.rootCertPath))
|
||||
}
|
||||
|
|
|
@ -155,3 +155,6 @@ func AppDataDir() string {
|
|||
|
||||
// ConfigAutosavePath is the default path to which the last config will be persisted.
|
||||
var ConfigAutosavePath = filepath.Join(AppConfigDir(), "autosave.json")
|
||||
|
||||
// DefaultStorage is Caddy's default storage module.
|
||||
var DefaultStorage = &certmagic.FileStorage{Path: AppDataDir()}
|
||||
|
|
Loading…
Reference in New Issue