Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

httpcaddyfile: Support configuring pki app names via global options #4450

Merged
merged 3 commits into from Jan 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
96 changes: 93 additions & 3 deletions caddyconfig/httpcaddyfile/pkiapp.go
Expand Up @@ -16,23 +16,108 @@ package httpcaddyfile

import (
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/modules/caddypki"
)

func init() {
RegisterGlobalOption("pki", parsePKIApp)
}

// parsePKIApp parses the global log option. Syntax:
//
// pki {
// ca [<id>] {
// name <name>
// root_cn <name>
// intermediate_cn <name>
// }
// }
//
// When the CA ID is unspecified, 'local' is assumed.
//
func parsePKIApp(d *caddyfile.Dispenser, existingVal interface{}) (interface{}, error) {
mholt marked this conversation as resolved.
Show resolved Hide resolved
pki := &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}

for d.Next() {
for nesting := d.Nesting(); d.NextBlock(nesting); {
switch d.Val() {
case "ca":
pkiCa := new(caddypki.CA)
if d.NextArg() {
pkiCa.ID = d.Val()
if d.NextArg() {
return nil, d.ArgErr()
}
}
if pkiCa.ID == "" {
pkiCa.ID = caddypki.DefaultCAID
}

for nesting := d.Nesting(); d.NextBlock(nesting); {
switch d.Val() {
case "name":
if !d.NextArg() {
return nil, d.ArgErr()
}
pkiCa.Name = d.Val()

case "root_cn":
if !d.NextArg() {
return nil, d.ArgErr()
}
pkiCa.RootCommonName = d.Val()

case "intermediate_cn":
if !d.NextArg() {
return nil, d.ArgErr()
}
pkiCa.IntermediateCommonName = d.Val()

default:
return nil, d.Errf("unrecognized pki ca option '%s'", d.Val())
}
}

pki.CAs[pkiCa.ID] = pkiCa

default:
return nil, d.Errf("unrecognized pki option '%s'", d.Val())
}
}
}

return pki, nil
}

func (st ServerType) buildPKIApp(
pairings []sbAddrAssociation,
options map[string]interface{},
warnings []caddyconfig.Warning,
) (*caddypki.PKI, []caddyconfig.Warning, error) {

pkiApp := &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}

skipInstallTrust := false
if _, ok := options["skip_install_trust"]; ok {
skipInstallTrust = true
}
falseBool := false

// Load the PKI app configured via global options
var pkiApp *caddypki.PKI
unwrappedPki, ok := options["pki"].(*caddypki.PKI)
if ok {
pkiApp = unwrappedPki
} else {
pkiApp = &caddypki.PKI{CAs: make(map[string]*caddypki.CA)}
}
for _, ca := range pkiApp.CAs {
if skipInstallTrust {
ca.InstallTrust = &falseBool
}
pkiApp.CAs[ca.ID] = ca
}

// Add in the CAs configured via directives
for _, p := range pairings {
for _, sblock := range p.serverBlocks {
// find all the CAs that were defined and add them to the app config
Expand All @@ -42,7 +127,12 @@ func (st ServerType) buildPKIApp(
if skipInstallTrust {
ca.InstallTrust = &falseBool
}
pkiApp.CAs[ca.ID] = ca

// the CA might already exist from global options, so
// don't overwrite it in that case
if _, ok := pkiApp.CAs[ca.ID]; !ok {
pkiApp.CAs[ca.ID] = ca
}
}
}
}
Expand Down
@@ -1,10 +1,34 @@
{
skip_install_trust
pki {
ca {
name "Local"
root_cn "Custom Local Root Name"
intermediate_cn "Custom Local Intermediate Name"
}
ca foo {
name "Foo"
root_cn "Custom Foo Root Name"
intermediate_cn "Custom Foo Intermediate Name"
}
}
}

a.example.com {
tls internal
}

acme.example.com {
acme_server {
ca foo
}
}

acme-bar.example.com {
acme_server {
ca bar
}
}
----------
{
"apps": {
Expand All @@ -15,6 +39,56 @@ a.example.com {
":443"
],
"routes": [
{
"match": [
{
"host": [
"acme-bar.example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"ca": "bar",
"handler": "acme_server"
}
]
}
]
}
],
"terminal": true
},
{
"match": [
{
"host": [
"acme.example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"ca": "foo",
"handler": "acme_server"
}
]
}
]
}
],
"terminal": true
},
{
"match": [
{
Expand All @@ -31,14 +105,32 @@ a.example.com {
},
"pki": {
"certificate_authorities": {
"bar": {
"install_trust": false
},
"foo": {
"name": "Foo",
"root_common_name": "Custom Foo Root Name",
"intermediate_common_name": "Custom Foo Intermediate Name",
"install_trust": false
},
"local": {
"name": "Local",
"root_common_name": "Custom Local Root Name",
"intermediate_common_name": "Custom Local Intermediate Name",
"install_trust": false
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"acme-bar.example.com",
"acme.example.com"
]
},
{
"subjects": [
"a.example.com"
Expand Down