Skip to content

Commit f4993b1

Browse files
committed
Authentication for metrics and version endpoint
Signed-off-by: naveenpaul1 <[email protected]>
1 parent c28f4ca commit f4993b1

File tree

4 files changed

+65
-9
lines changed

4 files changed

+65
-9
lines changed

docs/NooBaaNonContainerized/ConfigFileCustomizations.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
449449
"LOG_TO_STDERR_ENABLED": false
450450
3. systemctl restart noobaa
451451
```
452-
### 30. Notification log directory
452+
### 31. Notification log directory
453453
* <u>Key</u> `NOTIFICATION_LOG_DIR`
454454
* <u>Type</u> String
455455
* <u>Default</u> empty
@@ -462,7 +462,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
462462
"NOTIFICATION_LOG_DIR": "/etc/notif"
463463
3. systemctl restart noobaa
464464
465-
### 31. Prometheus HTTP enable flag -
465+
### 32. Prometheus HTTP enable flag -
466466
* <u>Key</u>: `ALLOW_HTTP_METRICS`
467467
* <u>Type</u>: Boolean
468468
* <u>Default</u>: true
@@ -476,7 +476,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
476476
3. systemctl restart noobaa
477477
```
478478
479-
### 32. Prometheus HTTPS enable flag -
479+
### 33. Prometheus HTTPS enable flag -
480480
* <u>Key</u>: `ALLOW_HTTPS_METRICS`
481481
* <u>Type</u>: Boolean
482482
* <u>Default</u>: true
@@ -490,7 +490,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
490490
3. systemctl restart noobaa
491491
```
492492
493-
### 33. Notification space monitor frequency flag -
493+
### 34. Notification space monitor frequency flag -
494494
* <u>Key</u>: `NOTIFICATION_REQ_PER_SPACE_CHECK`
495495
* <u>Type</u>: Positive integer
496496
* <u>Default</u>: 0
@@ -504,7 +504,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
504504
3. systemctl restart noobaa
505505
```
506506
507-
### 34. Notification space monitor threshold flag -
507+
### 35. Notification space monitor threshold flag -
508508
* <u>Key</u>: `NOTIFICATION_SPACE_CHECK_THRESHOLD`
509509
* <u>Type</u>: Number
510510
* <u>Default</u>: 0.1
@@ -518,7 +518,7 @@ Warning: After setting this configuration, NooBaa will skip schema validations a
518518
3. systemctl restart noobaa
519519
```
520520
521-
### 34. Dynamic supplemental groups allocation flag -
521+
### 36. Dynamic supplemental groups allocation flag -
522522
* <u>Key</u>: `NSFS_ENABLE_DYNAMIC_SUPPLEMENTAL_GROUPS`
523523
* <u>Type</u>: boolean
524524
* <u>Default</u>: true

src/server/analytic_services/prometheus_reporting.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const stats_aggregator = require('../system_services/stats_aggregator');
1313
const AggregatorRegistry = require('prom-client').AggregatorRegistry;
1414
const aggregatorRegistry = new AggregatorRegistry();
1515
const http_utils = require('../../util/http_utils');
16+
const jwt_utils = require('../../util/jwt_utils');
1617

1718
// Currenty supported reprots
1819
const reports = Object.seal({
@@ -69,6 +70,21 @@ async function start_server(
6970
return;
7071
}
7172
const metrics_request_handler = async (req, res) => {
73+
// TODO: This is a temporary condition to avoid the token authentication for metrics,
74+
// Need to add authentication for NSFS NC also after confirming flow with the Scale team
75+
if (!process.env.NC_NSFS_NO_DB_ENV) {
76+
try {
77+
jwt_utils.authenticate_jwt_token(req);
78+
} catch (err) {
79+
res.writeHead(403, { 'Content-Type': 'text/plain' });
80+
const reply = JSON.stringify({
81+
error: 'AccessDenied',
82+
message: 'Access Denied',
83+
}, null, 2) + '\n';
84+
res.end(reply);
85+
return;
86+
}
87+
}
7288
// Serve all metrics on the root path for system that do have one or more fork running.
7389
if (fork_enabled) {
7490
// we would like this part to be first as clusterMetrics might fail.

src/server/web_server.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const addr_utils = require('../util/addr_utils');
3434
const kube_utils = require('../util/kube_utils');
3535
const http_utils = require('../util/http_utils');
3636
const server_rpc = require('./server_rpc');
37+
const jwt_utils = require('../util/jwt_utils');
3738

3839
const rootdir = path.join(__dirname, '..', '..');
3940
const dev_mode = (process.env.DEV_MODE === 'true');
@@ -218,6 +219,17 @@ async function get_log_level_handler(req, res) {
218219
}
219220

220221
async function get_version_handler(req, res) {
222+
try {
223+
jwt_utils.authenticate_jwt_token(req);
224+
} catch (err) {
225+
res.writeHead(403, { 'Content-Type': 'text/plain' });
226+
const reply = JSON.stringify({
227+
error: 'AccessDenied',
228+
message: 'Access Denied',
229+
}, null, 2) + '\n';
230+
res.end(reply);
231+
return;
232+
}
221233
const { status, version } = await getVersion(req.url);
222234
if (version) res.send(version);
223235
if (status !== 200) res.status(status);

src/util/jwt_utils.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,38 @@ function make_internal_auth_token(object = {}, jwt_options = {}) {
2727
return make_auth_token(object, jwt_options);
2828
}
2929

30-
function authorize_jwt_token(token) {
30+
/**
31+
* authorize jwt token. Validate the jwt token inside passed validate_jwt method
32+
* @param {string} token
33+
* @param {Function} validate_jwt_func
34+
*/
35+
function authorize_jwt_token(token, validate_jwt_func = undefined) {
36+
if (token && token.includes('Bearer ')) {
37+
token = token.split(' ')[1];
38+
}
39+
return jwt.verify(token, get_jwt_secret(), validate_jwt_func);
40+
}
41+
42+
/**
43+
* autheticate jwt token for prometheus metrics and version request
44+
* @param {nb.S3Request} req
45+
*/
46+
function authenticate_jwt_token(req) {
47+
const token = req.headers.authorization;
3148
try {
32-
return jwt.verify(token, get_jwt_secret());
49+
if (!token) {
50+
throw new Error('Missing authorization header');
51+
}
52+
authorize_jwt_token(token, function(err, decoded) {
53+
if (err) {
54+
throw err;
55+
}
56+
if (decoded.role !== "metrics-auth") {
57+
throw new Error("Role based authorization failed");
58+
}
59+
});
3360
} catch (err) {
34-
dbg.error('JWT VERIFY FAILED', token, err);
61+
dbg.error('JWT verification failed for token : ', token, err);
3562
throw err;
3663
}
3764
}
@@ -40,3 +67,4 @@ exports.get_jwt_secret = get_jwt_secret;
4067
exports.make_auth_token = make_auth_token;
4168
exports.make_internal_auth_token = make_internal_auth_token;
4269
exports.authorize_jwt_token = authorize_jwt_token;
70+
exports.authenticate_jwt_token = authenticate_jwt_token;

0 commit comments

Comments
 (0)