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
ocsp: Add OCSP Stapling support for cluster, gateway and leafnodes #2263
Conversation
c79ab14
to
e86b5ca
Compare
} | ||
|
||
// When server makes a client connection, need to also present an OCSP Staple. | ||
tc.GetClientCertificate = func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is required for gateways, cluster and leafnode remote URL connections.
} | ||
return tc, mon, nil | ||
} | ||
|
||
func (s *Server) setupOCSPStapleStoreDir() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to ocsp.go from server.go
|
||
// RequireAndVerifyClientCert is used to tell a client that it | ||
// should send the client cert to the server. | ||
tc.ClientAuth = tls.RequireAndVerifyClientCert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar to gateways and cluster connections, we need to enforce this for leafnode remote URL connections in case OCSP stapling has been enabled so that the server can validate the staple of the client connection.
@@ -79,6 +79,8 @@ type ClusterOpts struct { | |||
|
|||
// Not exported (used in tests) | |||
resolver netResolver | |||
// Snapshot of configured TLS options. | |||
tlsConfigOpts *TLSConfigOpts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are needed in case we cannot find a certificate in the chain, then we load again from the ca file that was configured.
@@ -1338,53 +1344,6 @@ func (s *Server) applyOptions(ctx *reloadContext, opts []option) { | |||
s.Noticef("Reloaded server configuration") | |||
} | |||
|
|||
func (s *Server) reloadOCSP() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to ocsp.go
@@ -388,6 +388,12 @@ func NewServer(opts *Options) (*Server, error) { | |||
// Ensure that non-exported options (used in tests) are properly set. | |||
s.setLeafNodeNonExportedOptions() | |||
|
|||
// Setup OCSP Stapling. This will abort server from starting if there | |||
// are no valid staples and OCSP policy is to Always or MustStaple. | |||
if err := s.enableOCSP(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enableOCSP had to be done when NewServer is called instead of Start, otherwise gateway remotes TLS callbacks were not properly configured
e86b5ca
to
7b6a5f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The one real issue below is something I think we can handle by documenting as a limitation, so approving as-is.
server/ocsp.go
Outdated
@@ -246,12 +247,12 @@ func (oc *OCSPMonitor) run() { | |||
nextRun = oc.getNextRun() | |||
t := resp.NextUpdate.Format(time.RFC3339Nano) | |||
s.Noticef( | |||
"Found existing OCSP status for certificate at '%s': good, next update %s, checking again in %s", | |||
"Found OCSP status for certificate at '%s': good, next update %s, checking again in %s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a case where the context logger in s
already ensures that the kind will be logged, so including kind
again here would be duplicative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add the kind here, looks like this right now:
[84511] [DBG] [::1]:61387 - cid:3 - "v1.11.0:go" - Client connection closed: Client Closed
[84511] [INF] Received OCSP status for certificate 'configs/certs/ocsp/server-status-request-url-01-cert.pem': good, next update 2021-06-08T22:45:47Z, checking again in 1.8333895s
[84511] [ERR] Received OCSP status for certificate 'configs/certs/ocsp/server-status-request-url-01-cert.pem': revoked
[84511] [DBG] 127.0.0.1:61388 - cid:4 - Client connection created
[84511] [DBG] 127.0.0.1:61388 - cid:4 - Starting TLS client connection handshake
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the kind to get more context:
[84778] [INF] Found OCSP status for Client certificate at 'configs/certs/ocsp/server-cert.pem': good, next update 2021-06-08T22:52:06Z, checking again in 1.984172s
[84778] [DBG] 127.0.0.1:61841 - cid:3 - Client connection created
[84778] [DBG] 127.0.0.1:61841 - cid:3 - Starting TLS client connection handshake
[84778] [DBG] 127.0.0.1:61841 - cid:3 - TLS handshake complete
[84778] [DBG] 127.0.0.1:61841 - cid:3 - TLS version 1.3, cipher suite TLS_AES_128_GCM_SHA256
[84778] [DBG] 127.0.0.1:61841 - cid:3 - "v1.11.0:go" - Client connection closed: Client Closed
[84778] [INF] Received OCSP status for Client certificate 'configs/certs/ocsp/server-cert.pem': good, next update 2021-06-08T22:52:08Z, checking again in 1.9809375s
[84778] [ERR] Received OCSP status for Client certificate 'configs/certs/ocsp/server-cert.pem': revoked
// Apply latest TLS configuration. | ||
config.apply(tc) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to allow promotion to requiring OCSP but not demotion from requiring OCSP. If the reload requires OCSP before/after we override the field to do "the same thing" via the apply, but there's nothing to undo the mutated field from an earlier apply, is there?
Do we care? We could just document it as a limitation, "removing OCSP as a requirement for a connection requires a full restart, not just a reload".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case the cert does not have the must staple flag and running in auto mode which is the default, then it would get disabled here: https://github.com/nats-io/nats-server/pull/2263/files#diff-7bc3c6340f0feb2d8426342029fd9c192a397b1ade67c05e25a90d076c39248bR359
return fmt.Errorf("%s client missing TLS verified chains", kind) | ||
} | ||
chain := s.VerifiedChains[0] | ||
resp, err := ocsp.ParseResponseForCert(oresp, chain[0], issuer) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just quick note here, the issuer
here in the callback is already the result getOCSPIssuer
so no need to call it once again.
7b6a5f3
to
aecf6a6
Compare
Signed-off-by: Waldemar Quevedo <wally@synadia.com> Signed-off-by: Jaime Piña <jaime@synadia.com>
aecf6a6
to
6c99219
Compare
Adds OCSP Stapling support for cluster, gateway and leafnode connections.
Signed-off-by: Waldemar Quevedo wally@synadia.com
Signed-off-by: Jaime Piña jaime@synadia.com