From e7edaaffeea915ff7fe66c29c8b5bb0b13446e80 Mon Sep 17 00:00:00 2001 From: Steven Clark Date: Fri, 25 Feb 2022 13:26:34 -0500 Subject: [PATCH] Force certain PKI operations to go to the Primary Performance cluster immediately (#14287) --- builtin/logical/pki/backend.go | 26 +++++++++++++++++++ builtin/logical/pki/path_intermediate.go | 20 +++++++++----- builtin/logical/pki/path_root.go | 33 ++++++++++++++++-------- go.mod | 4 +-- go.sum | 4 +-- 5 files changed, 66 insertions(+), 21 deletions(-) diff --git a/builtin/logical/pki/backend.go b/builtin/logical/pki/backend.go index 61b241a44..c0a1a0916 100644 --- a/builtin/logical/pki/backend.go +++ b/builtin/logical/pki/backend.go @@ -20,6 +20,32 @@ const ( roleRequired = 2 ) +/* + * PKI requests are a bit special to keep up with the various failure and load issues. + * The main ca and intermediate requests are always forwarded to the Primary cluster's active + * node to write and send the key material/config globally across all clusters. + * + * CRL/Revocation and Issued certificate apis are handled by the active node within the cluster + * they originate. Which means if a request comes into a performance secondary cluster the writes + * will be forwarded to that cluster's active node and not go all the way up to the performance primary's + * active node. + * + * If a certificate issue request has a role in which no_store is set to true that node itself + * will issue the certificate and not forward the request to the active node. + * + * Following the same pattern if a managed key is involved to sign an issued certificate request + * and the local node does not have access for some reason to it, the request will be forwarded to + * the active node within the cluster only. + * + * To make sense of what goes where the following bits need to be analyzed within the codebase. + * 1. The backend LocalStorage paths determine what storage paths will remain within a + * cluster and not be forwarded to a performance primary + * 2. Within each path's OperationHandler definition, check to see if ForwardPerformanceStandby & + * ForwardPerformanceSecondary flags are set to short-circuit the request to a given active node + * 3. Within the managed key util class in pki, an initialization failure could cause the request + * to be forwarded to an active node if not already on it. + */ + // Factory creates a new backend implementing the logical.Backend interface func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { b := Backend(conf) diff --git a/builtin/logical/pki/path_intermediate.go b/builtin/logical/pki/path_intermediate.go index 318f9afbe..fc578d6fe 100644 --- a/builtin/logical/pki/path_intermediate.go +++ b/builtin/logical/pki/path_intermediate.go @@ -14,9 +14,13 @@ import ( func pathGenerateIntermediate(b *backend) *framework.Path { ret := &framework.Path{ Pattern: "intermediate/generate/" + framework.GenericNameRegex("exported"), - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathGenerateIntermediate, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.pathGenerateIntermediate, + // Read more about why these flags are set in backend.go + ForwardPerformanceStandby: true, + ForwardPerformanceSecondary: true, + }, }, HelpSynopsis: pathGenerateIntermediateHelpSyn, @@ -49,9 +53,13 @@ previously-generated key from the generation endpoint.`, }, }, - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathSetSignedIntermediate, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.pathSetSignedIntermediate, + // Read more about why these flags are set in backend.go + ForwardPerformanceStandby: true, + ForwardPerformanceSecondary: true, + }, }, HelpSynopsis: pathSetSignedIntermediateHelpSyn, diff --git a/builtin/logical/pki/path_root.go b/builtin/logical/pki/path_root.go index 5ac9c63e9..8aee14427 100644 --- a/builtin/logical/pki/path_root.go +++ b/builtin/logical/pki/path_root.go @@ -29,8 +29,13 @@ func pathGenerateRoot(b *backend) *framework.Path { ret := &framework.Path{ Pattern: "root/generate/" + framework.GenericNameRegex("exported"), - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathCAGenerateRoot, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.pathCAGenerateRoot, + // Read more about why these flags are set in backend.go + ForwardPerformanceStandby: true, + ForwardPerformanceSecondary: true, + }, }, HelpSynopsis: pathGenerateRootHelpSyn, @@ -47,9 +52,13 @@ func pathGenerateRoot(b *backend) *framework.Path { func pathDeleteRoot(b *backend) *framework.Path { ret := &framework.Path{ Pattern: "root", - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.DeleteOperation: b.pathCADeleteRoot, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.DeleteOperation: &framework.PathOperation{ + Callback: b.pathCADeleteRoot, + // Read more about why these flags are set in backend.go + ForwardPerformanceStandby: true, + ForwardPerformanceSecondary: true, + }, }, HelpSynopsis: pathDeleteRootHelpSyn, @@ -62,9 +71,10 @@ func pathDeleteRoot(b *backend) *framework.Path { func pathSignIntermediate(b *backend) *framework.Path { ret := &framework.Path{ Pattern: "root/sign-intermediate", - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathCASignIntermediate, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.pathCASignIntermediate, + }, }, HelpSynopsis: pathSignIntermediateHelpSyn, @@ -100,9 +110,10 @@ the non-repudiation flag.`, func pathSignSelfIssued(b *backend) *framework.Path { ret := &framework.Path{ Pattern: "root/sign-self-issued", - - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.pathCASignSelfIssued, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.pathCASignSelfIssued, + }, }, Fields: map[string]*framework.FieldSchema{ diff --git a/go.mod b/go.mod index 3f74cbd33..6b5fd21e6 100644 --- a/go.mod +++ b/go.mod @@ -63,7 +63,7 @@ require ( github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 github.com/hashicorp/go-gcp-common v0.7.0 github.com/hashicorp/go-hclog v1.1.0 - github.com/hashicorp/go-kms-wrapping v0.6.8 + github.com/hashicorp/go-kms-wrapping v0.7.0 github.com/hashicorp/go-memdb v1.3.2 github.com/hashicorp/go-msgpack v1.1.5 github.com/hashicorp/go-multierror v1.1.1 @@ -130,6 +130,7 @@ require ( github.com/kr/text v0.2.0 github.com/lib/pq v1.10.3 github.com/mattn/go-colorable v0.1.12 + github.com/mattn/go-isatty v0.0.14 github.com/mholt/archiver v3.1.1+incompatible github.com/michaelklishin/rabbit-hole/v2 v2.11.0 github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a @@ -305,7 +306,6 @@ require ( github.com/klauspost/compress v1.13.6 // indirect github.com/linode/linodego v0.7.1 // indirect github.com/mattn/go-ieproxy v0.0.1 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/miekg/dns v1.1.41 // indirect github.com/mitchellh/hashstructure v1.0.0 // indirect diff --git a/go.sum b/go.sum index 9bf626be4..66eae2eed 100644 --- a/go.sum +++ b/go.sum @@ -843,8 +843,8 @@ github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-kms-wrapping v0.6.8 h1:Tu4X6xRFyV3i9SSthYVGnyNaof3VTxVo2tBQ7bdHiwE= -github.com/hashicorp/go-kms-wrapping v0.6.8/go.mod h1:rmGmNzO/DIBzUyisFjeocXvazOlxgO5K8vsFQkUn7Hk= +github.com/hashicorp/go-kms-wrapping v0.7.0 h1:UBagVJn4nSNOSjjtpkR370VOEBLnGMXfQcIlE/WL/7o= +github.com/hashicorp/go-kms-wrapping v0.7.0/go.mod h1:rmGmNzO/DIBzUyisFjeocXvazOlxgO5K8vsFQkUn7Hk= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0 h1:xuTi5ZwjimfpvpL09jDE71smCBRpnF5xfo871BSX4gs= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8=