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, 00:15 UTC
httpcaddyfile: Support configuring `pki` app names via global options (#4450)
Francis Lavoie committed
Jan 5, 2022 at 22:45 UTC
4b9849c7922c3a0a7b1bd487f5d890fcff32aaba
2 files changed
+185
-3
caddyconfig/httpcaddyfile/pkiapp.go
+93
-3
@@ -16,23 +16,108 @@ package httpcaddyfile
16
17
import (
18
"github.com/caddyserver/caddy/v2/caddyconfig"
19
+ "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
20
"github.com/caddyserver/caddy/v2/modules/caddypki"
21
)
22
23
+func init() {
24
+ RegisterGlobalOption("pki", parsePKIApp)
25
+}
26
+
27
+// parsePKIApp parses the global log option. Syntax:
28
+//
29
+// pki {
30
+// ca [<id>] {
31
+// name <name>
32
+// root_cn <name>
33
+// intermediate_cn <name>
34
+// }
35
+// }
36
+//
37
+// When the CA ID is unspecified, 'local' is assumed.
38
+//
39
+func parsePKIApp(d *caddyfile.Dispenser, existingVal interface{}) (interface{}, error) {
40
+ pki := &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}
41
+
42
+ for d.Next() {
43
+ for nesting := d.Nesting(); d.NextBlock(nesting); {
44
+ switch d.Val() {
45
+ case "ca":
46
+ pkiCa := new(caddypki.CA)
47
+ if d.NextArg() {
48
+ pkiCa.ID = d.Val()
49
+ if d.NextArg() {
50
+ return nil, d.ArgErr()
51
+ }
52
+ }
53
+ if pkiCa.ID == "" {
54
+ pkiCa.ID = caddypki.DefaultCAID
55
+ }
56
+
57
+ for nesting := d.Nesting(); d.NextBlock(nesting); {
58
+ switch d.Val() {
59
+ case "name":
60
+ if !d.NextArg() {
61
+ return nil, d.ArgErr()
62
+ }
63
+ pkiCa.Name = d.Val()
64
+
65
+ case "root_cn":
66
+ if !d.NextArg() {
67
+ return nil, d.ArgErr()
68
+ }
69
+ pkiCa.RootCommonName = d.Val()
70
+
71
+ case "intermediate_cn":
72
+ if !d.NextArg() {
73
+ return nil, d.ArgErr()
74
+ }
75
+ pkiCa.IntermediateCommonName = d.Val()
76
+
77
+ default:
78
+ return nil, d.Errf("unrecognized pki ca option '%s'", d.Val())
79
+ }
80
+ }
81
+
82
+ pki.CAs[pkiCa.ID] = pkiCa
83
+
84
+ default:
85
+ return nil, d.Errf("unrecognized pki option '%s'", d.Val())
86
+ }
87
+ }
88
+ }
89
+
90
+ return pki, nil
91
+}
92
+
93
func (st ServerType) buildPKIApp(
94
pairings []sbAddrAssociation,
95
options map[string]interface{},
96
warnings []caddyconfig.Warning,
97
) (*caddypki.PKI, []caddyconfig.Warning, error) {
98
28
- pkiApp := &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}
29
-
99
skipInstallTrust := false
100
if _, ok := options["skip_install_trust"]; ok {
101
skipInstallTrust = true
102
}
103
falseBool := false
104
105
+ // Load the PKI app configured via global options
106
+ var pkiApp *caddypki.PKI
107
+ unwrappedPki, ok := options["pki"].(*caddypki.PKI)
108
+ if ok {
109
+ pkiApp = unwrappedPki
110
+ } else {
111
+ pkiApp = &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}
112
+ }
113
+ for _, ca := range pkiApp.CAs {
114
+ if skipInstallTrust {
115
+ ca.InstallTrust = &falseBool
116
+ }
117
+ pkiApp.CAs[ca.ID] = ca
118
+ }
119
+
120
+ // Add in the CAs configured via directives
121
for _, p := range pairings {
122
for _, sblock := range p.serverBlocks {
123
// find all the CAs that were defined and add them to the app config
@@ -42,7 +127,12 @@ func (st ServerType) buildPKIApp(
127
if skipInstallTrust {
128
ca.InstallTrust = &falseBool
129
}
45
- pkiApp.CAs[ca.ID] = ca
130
+
131
+ // the CA might already exist from global options, so
132
+ // don't overwrite it in that case
133
+ if _, ok := pkiApp.CAs[ca.ID]; !ok {
134
+ pkiApp.CAs[ca.ID] = ca
135
+ }
136
}
137
}
138
}
caddytest/integration/caddyfile_adapt/global_options_skip_install_trust.txt
+92
@@ -1,10 +1,34 @@
1
{
2
skip_install_trust
3
+ pki {
4
+ ca {
5
+ name "Local"
6
+ root_cn "Custom Local Root Name"
7
+ intermediate_cn "Custom Local Intermediate Name"
8
+ }
9
+ ca foo {
10
+ name "Foo"
11
+ root_cn "Custom Foo Root Name"
12
+ intermediate_cn "Custom Foo Intermediate Name"
13
+ }
14
+ }
15
}
16
17
a.example.com {
18
tls internal
19
}
20
+
21
+acme.example.com {
22
+ acme_server {
23
+ ca foo
24
+ }
25
+}
26
+
27
+acme-bar.example.com {
28
+ acme_server {
29
+ ca bar
30
+ }
31
+}
32
----------
33
{
34
"apps": {
@@ -15,6 +39,56 @@ a.example.com {
39
":443"
40
],
41
"routes": [
42
+ {
43
+ "match": [
44
+ {
45
+ "host": [
46
+ "acme-bar.example.com"
47
+ ]
48
+ }
49
+ ],
50
+ "handle": [
51
+ {
52
+ "handler": "subroute",
53
+ "routes": [
54
+ {
55
+ "handle": [
56
+ {
57
+ "ca": "bar",
58
+ "handler": "acme_server"
59
+ }
60
+ ]
61
+ }
62
+ ]
63
+ }
64
+ ],
65
+ "terminal": true
66
+ },
67
+ {
68
+ "match": [
69
+ {
70
+ "host": [
71
+ "acme.example.com"
72
+ ]
73
+ }
74
+ ],
75
+ "handle": [
76
+ {
77
+ "handler": "subroute",
78
+ "routes": [
79
+ {
80
+ "handle": [
81
+ {
82
+ "ca": "foo",
83
+ "handler": "acme_server"
84
+ }
85
+ ]
86
+ }
87
+ ]
88
+ }
89
+ ],
90
+ "terminal": true
91
+ },
92
{
93
"match": [
94
{
@@ -31,7 +105,19 @@ a.example.com {
105
},
106
"pki": {
107
"certificate_authorities": {
108
+ "bar": {
109
+ "install_trust": false
110
+ },
111
+ "foo": {
112
+ "name": "Foo",
113
+ "root_common_name": "Custom Foo Root Name",
114
+ "intermediate_common_name": "Custom Foo Intermediate Name",
115
+ "install_trust": false
116
+ },
117
"local": {
118
+ "name": "Local",
119
+ "root_common_name": "Custom Local Root Name",
120
+ "intermediate_common_name": "Custom Local Intermediate Name",
121
"install_trust": false
122
}
123
}
@@ -39,6 +125,12 @@ a.example.com {
125
"tls": {
126
"automation": {
127
"policies": [
128
+ {
129
+ "subjects": [
130
+ "acme-bar.example.com",
131
+ "acme.example.com"
132
+ ]
133
+ },
134
{
135
"subjects": [
136
"a.example.com"