summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShreyas Kalyan <shreyas.kalyan@10gen.com>2020-11-05 13:04:51 -0800
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-01-25 19:32:21 +0000
commit5812fde75ad2f703dcf52cb09137e5b0d52c1d88 (patch)
tree4487116bc90a758e65b2f1c90f09df84bacce3a7
parent11fa13ae84f14ca55bb0d671ba4391fc29f96f89 (diff)
downloadmongo-5812fde75ad2f703dcf52cb09137e5b0d52c1d88.tar.gz
SERVER-49280 Investigate issues with ocspValidationRefreshPeriodSecs
(cherry picked from commit add2cc96db696e9295e3dc7a56337b28e13fd0a8)
-rw-r--r--jstests/ocsp/ocsp_server_refresh.js43
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp45
-rw-r--r--src/mongo/util/net/ssl_parameters.idl2
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"