diff options
author | Shreyas Kalyan <shreyas.kalyan@10gen.com> | 2020-11-05 13:04:51 -0800 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-01-25 19:32:21 +0000 |
commit | 5812fde75ad2f703dcf52cb09137e5b0d52c1d88 (patch) | |
tree | 4487116bc90a758e65b2f1c90f09df84bacce3a7 | |
parent | 11fa13ae84f14ca55bb0d671ba4391fc29f96f89 (diff) | |
download | mongo-5812fde75ad2f703dcf52cb09137e5b0d52c1d88.tar.gz |
SERVER-49280 Investigate issues with ocspValidationRefreshPeriodSecs
(cherry picked from commit add2cc96db696e9295e3dc7a56337b28e13fd0a8)
-rw-r--r-- | jstests/ocsp/ocsp_server_refresh.js | 43 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_openssl.cpp | 45 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_parameters.idl | 2 |
3 files changed, 64 insertions, 26 deletions
diff --git a/jstests/ocsp/ocsp_server_refresh.js b/jstests/ocsp/ocsp_server_refresh.js index 608d9368c35..a8870895b5f 100644 --- a/jstests/ocsp/ocsp_server_refresh.js +++ b/jstests/ocsp/ocsp_server_refresh.js @@ -98,4 +98,47 @@ assert.doesNotThrow(() => { }); MongoRunner.stopMongod(conn); + +// Make sure that the refresh period is set to a very large value so that we can +// make sure that the period defined by the mock OCSP responder overrides it. +let ocsp_options_high_refresh = { + sslMode: "requireSSL", + sslPEMKeyFile: OCSP_SERVER_CERT, + sslCAFile: OCSP_CA_PEM, + sslAllowInvalidHostnames: "", + setParameter: { + "ocspEnabled": "true", + "ocspStaplingRefreshPeriodSecs": 300000, + }, +}; + +mock_ocsp = new MockOCSPServer("", 10); +mock_ocsp.start(); + +assert.doesNotThrow(() => { + conn = MongoRunner.runMongod(ocsp_options); +}); + +// Kill the ocsp responder, start it with cert revoked, and wait 20 seconds +// so the server refreshes its stapled OCSP response. +mock_ocsp.stop(); +mock_ocsp = new MockOCSPServer(FAULT_REVOKED, 100); +mock_ocsp.start(); + +sleep(20000); + +// By asserting here that a new connection cannot be established to the +// mongod, we prove that the server has refreshed its stapled response sooner +// than the refresh period indicated. +assert.throws(() => { + new Mongo(conn.host); +}); + +MongoRunner.stopMongod(conn); + +// The mongoRunner spawns a new Mongo Object to validate the collections which races +// with the shutdown logic of the mock_ocsp responder on some platforms. We need this +// sleep to make sure that the threads don't interfere with each other. +sleep(1000); +mock_ocsp.stop(); }()); diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp index 269dcf083df..674717a2a72 100644 --- a/src/mongo/util/net/ssl_manager_openssl.cpp +++ b/src/mongo/util/net/ssl_manager_openssl.cpp @@ -543,6 +543,16 @@ struct OCSPFetchResponse { return Milliseconds(0); } + // If the setParameter for OCSPStaplingRefreshPeriodSecs is too high, we want to + // make sure that we are never left without a stapled OCSP response because we + // were not refreshing fast enough. + if (kOCSPStaplingRefreshPeriodSecs != -1 && + kOCSPStaplingRefreshPeriodSecs < + durationCount<Seconds>(timeBeforeNextUpdate - + Seconds(60 + gTLSOCSPStaplingTimeoutSecs))) { + + return Milliseconds(Seconds(kOCSPStaplingRefreshPeriodSecs)); + } return timeBeforeNextUpdate / 2; } @@ -1875,6 +1885,14 @@ Status OCSPFetcher::start(SSL_CTX* context, bool asyncOCSPStaple) { return Status::OK(); } +Milliseconds getPeriodForStapleJob(StatusWith<Milliseconds> swDuration) { + if (!swDuration.isOK()) { + return kOCSPUnknownStatusRefreshRate; + } else { + return swDuration.getValue(); + } +} + void OCSPFetcher::startPeriodicJob(StatusWith<Milliseconds> swDurationInitial) { stdx::lock_guard<Latch> lock(_staplingMutex); @@ -1886,24 +1904,11 @@ void OCSPFetcher::startPeriodicJob(StatusWith<Milliseconds> swDurationInitial) { return; } - // determine the OCSP validation refresh period - Milliseconds duration; - if (swDurationInitial.isOK()) { - // if the validation refresh period was set manually, use it - if (kOCSPStaplingRefreshPeriodSecs != -1) { - duration = Seconds(kOCSPStaplingRefreshPeriodSecs); - } else { - duration = swDurationInitial.getValue(); - } - } else { - duration = kOCSPUnknownStatusRefreshRate; - } - _ocspStaplingAnchor = getGlobalServiceContext()->getPeriodicRunner()->makeJob(PeriodicRunner::PeriodicJob( "OCSP Fetch and Staple", [this, sm = _manager->shared_from_this()](Client* client) { doPeriodicJob(); }, - duration)); + getPeriodForStapleJob(swDurationInitial))); _ocspStaplingAnchor.start(); } @@ -1917,17 +1922,7 @@ void OCSPFetcher::doPeriodicJob() { return; } - if (!swDuration.isOK()) { - this->_ocspStaplingAnchor.setPeriod(kOCSPUnknownStatusRefreshRate); - return; - } else { - // if the validation refresh period was set manually, use it - if (kOCSPStaplingRefreshPeriodSecs != -1) { - this->_ocspStaplingAnchor.setPeriod(Seconds(kOCSPStaplingRefreshPeriodSecs)); - } else { - this->_ocspStaplingAnchor.setPeriod(swDuration.getValue()); - } - } + this->_ocspStaplingAnchor.setPeriod(getPeriodForStapleJob(swDuration)); }); } diff --git a/src/mongo/util/net/ssl_parameters.idl b/src/mongo/util/net/ssl_parameters.idl index e920f358f08..42aad75dc4a 100644 --- a/src/mongo/util/net/ssl_parameters.idl +++ b/src/mongo/util/net/ssl_parameters.idl @@ -75,7 +75,7 @@ server_parameters: ocspStaplingRefreshPeriodSecs: description: "Interval at which the OCSP response will be refreshed" set_at: startup - cpp_vartype: int + cpp_vartype: long long deprecated_name: ocspValidationRefreshPeriodSecs default: -1 cpp_varname: "kOCSPStaplingRefreshPeriodSecs" |