@marcel91200 / caddy Mirror · read-only / commits / 244b839f
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

pki: Add trust subcommand to install root cert (closes #3204)

Matthew Holt committed Mar 31, 2020 at 17:56 UTC 244b839f9813ae68c5527e6aadadaff0642c1a00
5 files changed +73 -20
caddy.go
+1 -1
@@ -372,7 +372,7 @@ func run(newCfg *Config, start bool) error {
372 }
373
374 if newCfg.storage == nil {
375 - newCfg.storage = &certmagic.FileStorage{Path: AppDataDir()}
375 + newCfg.storage = DefaultStorage
376 }
377 certmagic.Default.Storage = newCfg.storage
378
modules/caddypki/ca.go
+22
@@ -24,6 +24,7 @@ import (
24
25 "github.com/caddyserver/caddy/v2"
26 "github.com/caddyserver/certmagic"
27 + "github.com/smallstep/truststore"
28 "go.uber.org/zap"
29 )
30
@@ -323,6 +324,27 @@ func (ca CA) newReplacer() *caddy.Replacer {
324 return repl
325 }
326
327 +// installRoot installs this CA's root certificate into the
328 +// local trust store(s) if it is not already trusted. The CA
329 +// must already be provisioned.
330 +func (ca CA) installRoot() error {
331 + // avoid password prompt if already trusted
332 + if trusted(ca.root) {
333 + ca.log.Info("root certificate is already trusted by system",
334 + zap.String("path", ca.rootCertPath))
335 + return nil
336 + }
337 +
338 + ca.log.Warn("installing root certificate (you might be prompted for password)",
339 + zap.String("path", ca.rootCertPath))
340 +
341 + return truststore.Install(ca.root,
342 + truststore.WithDebug(),
343 + truststore.WithFirefox(),
344 + truststore.WithJava(),
345 + )
346 +}
347 +
348 const (
349 defaultCAID = "local"
350 defaultCAName = "Caddy Local Authority"
modules/caddypki/command.go
+44
@@ -15,6 +15,7 @@
15 package caddypki
16
17 import (
18 + "context"
19 "flag"
20 "fmt"
21 "os"
@@ -26,6 +27,25 @@ import (
27 )
28
29 func init() {
30 + caddycmd.RegisterCommand(caddycmd.Command{
31 + Name: "trust",
32 + Func: cmdTrust,
33 + Short: "Installs a CA certificate into local trust stores",
34 + Long: `
35 +Adds a root certificate into the local trust stores. Intended for
36 +development environments only.
37 +
38 +Since Caddy will install its root certificates into the local trust
39 +stores automatically when they are first generated, this command is
40 +only necessary if you need to pre-install the certificates before
41 +using them; for example, if you have elevated privileges at one
42 +point but not later, you will want to use this command so that a
43 +password prompt is not required later.
44 +
45 +This command installs the root certificate only for Caddy's
46 +default CA.`,
47 + })
48 +
49 caddycmd.RegisterCommand(caddycmd.Command{
50 Name: "untrust",
51 Func: cmdUntrust,
@@ -57,6 +77,30 @@ If no flags are specified, --ca=local is assumed.`,
77 })
78 }
79
80 +func cmdTrust(fs caddycmd.Flags) (int, error) {
81 + // we have to create a sort of dummy context so that
82 + // the CA can provision itself...
83 + ctx, cancel := caddy.NewContext(caddy.Context{Context: context.Background()})
84 + defer cancel()
85 +
86 + // provision the CA, which generates and stores a root
87 + // certificate if one doesn't already exist in storage
88 + ca := CA{
89 + storage: caddy.DefaultStorage,
90 + }
91 + err := ca.Provision(ctx, defaultCAID, caddy.Log())
92 + if err != nil {
93 + return caddy.ExitCodeFailedStartup, err
94 + }
95 +
96 + err = ca.installRoot()
97 + if err != nil {
98 + return caddy.ExitCodeFailedStartup, err
99 + }
100 +
101 + return caddy.ExitCodeSuccess, nil
102 +}
103 +
104 func cmdUntrust(fs caddycmd.Flags) (int, error) {
105 ca := fs.String("ca")
106 cert := fs.String("cert")
modules/caddypki/pki.go
+3 -19
@@ -18,7 +18,6 @@ import (
18 "fmt"
19
20 "github.com/caddyserver/caddy/v2"
21 - "github.com/smallstep/truststore"
21 "go.uber.org/zap"
22 )
23
@@ -71,30 +70,15 @@ func (p *PKI) Start() error {
70 // install roots to trust store, if not disabled
71 for _, ca := range p.CAs {
72 if ca.InstallTrust != nil && !*ca.InstallTrust {
74 - ca.log.Warn("root certificate trust store installation disabled; local clients may show warnings",
73 + ca.log.Warn("root certificate trust store installation disabled; unconfigured clients may show warnings",
74 zap.String("path", ca.rootCertPath))
75 continue
76 }
77
79 - // avoid password prompt if already trusted
80 - if trusted(ca.root) {
81 - ca.log.Info("root certificate is already trusted by system",
82 - zap.String("path", ca.rootCertPath))
83 - continue
84 - }
85 -
86 - ca.log.Warn("trusting root certificate (you might be prompted for password)",
87 - zap.String("path", ca.rootCertPath))
88 -
89 - err := truststore.Install(ca.root,
90 - truststore.WithDebug(),
91 - truststore.WithFirefox(),
92 - truststore.WithJava(),
93 - )
94 - if err != nil {
78 + if err := ca.installRoot(); err != nil {
79 // could be some system dependencies that are missing;
80 // shouldn't totally prevent startup, but we should log it
97 - p.log.Error("failed to install root certificate",
81 + ca.log.Error("failed to install root certificate",
82 zap.Error(err),
83 zap.String("certificate_file", ca.rootCertPath))
84 }
storage.go
+3
@@ -155,3 +155,6 @@ func AppDataDir() string {
155
156 // ConfigAutosavePath is the default path to which the last config will be persisted.
157 var ConfigAutosavePath = filepath.Join(AppConfigDir(), "autosave.json")
158 +
159 +// DefaultStorage is Caddy's default storage module.
160 +var DefaultStorage = &certmagic.FileStorage{Path: AppDataDir()}