Skip to content
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

bf: ARSN-57 log correct client ip #1693

Merged
merged 1 commit into from
Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/policyEvaluator/requestUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const ipCheck = require('../ipCheck');
* @return {string} - returns client IP from the request
*/
function getClientIp(request, s3config) {
const clientIp = request.socket.remoteAddress;
const requestConfig = s3config ? s3config.requests : {};
const remoteAddress = request.socket.remoteAddress;
const clientIp = requestConfig ? remoteAddress : request.headers['x-forwarded-for'] || remoteAddress;
if (requestConfig) {
const { trustedProxyCIDRs, extractClientIPFromHeader } = requestConfig;
/**
Expand Down
13 changes: 10 additions & 3 deletions lib/s3routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const routeOPTIONS = require('./routes/routeOPTIONS');
const routesUtils = require('./routesUtils');
const routeWebsite = require('./routes/routeWebsite');

const requestUtils = require('../../lib/policyEvaluator/requestUtils');

const routeMap = {
GET: routeGET,
PUT: routePUT,
Expand Down Expand Up @@ -67,7 +69,8 @@ function checkBucketAndKey(bucketName, objectKey, method, reqQuery,
return undefined;
}

function checkTypes(req, res, params, logger) {
// TODO: ARSN-59 remove assertions or restrict it to dev environment only.
function checkTypes(req, res, params, logger, s3config) {
assert.strictEqual(typeof req, 'object',
'bad routes param: req must be an object');
assert.strictEqual(typeof res, 'object',
Expand Down Expand Up @@ -114,6 +117,9 @@ function checkTypes(req, res, params, logger) {
});
assert.strictEqual(typeof params.dataRetrievalFn, 'function',
'bad routes param: dataRetrievalFn must be a defined function');
if (s3config) {
assert.strictEqual(typeof s3config, 'object', 'bad routes param: s3config must be an object');
}
}

/** routes - route request to appropriate method
Expand All @@ -134,9 +140,10 @@ function checkTypes(req, res, params, logger) {
* values for whether queries are supported
* @param {function} params.dataRetrievalFn - function to retrieve data
* @param {RequestLogger} logger - werelogs logger instance
* @param {String} [s3config] - s3 configuration
* @returns {undefined}
*/
function routes(req, res, params, logger) {
function routes(req, res, params, logger, s3config) {
checkTypes(req, res, params, logger);

const {
Expand All @@ -150,7 +157,7 @@ function routes(req, res, params, logger) {
} = params;

const clientInfo = {
clientIP: req.socket.remoteAddress,
clientIP: requestUtils.getClientIp(req, s3config),
clientPort: req.socket.remotePort,
httpCode: res.statusCode,
httpMessage: res.statusMessage,
Expand Down
49 changes: 38 additions & 11 deletions tests/unit/policyEvaluator/requestUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ describe('requestUtils.getClientIp', () => {
const testClientIp2 = '192.168.104.0';
const testProxyIp = '192.168.100.2';

it('should return client Ip address from header ' +
'if the request comes via proxies', () => {
it('should return client Ip address from header if the request comes via proxies', () => {
const request = new DummyRequest({
headers: {
'x-forwarded-for': [testClientIp1, testProxyIp].join(','),
Expand All @@ -28,13 +27,9 @@ describe('requestUtils.getClientIp', () => {
assert.strictEqual(result, testClientIp1);
});

it('should not return client Ip address from header ' +
'if the request is not forwarded from proxies or ' +
'fails ip check', () => {
it('should return client Ip address from socket info if the request is not forwarded from proxies', () => {
const request = new DummyRequest({
headers: {
'x-forwarded-for': [testClientIp1, testProxyIp].join(','),
},
headers: {},
url: '/',
parsedHost: 'localhost',
socket: {
Expand All @@ -45,12 +40,11 @@ describe('requestUtils.getClientIp', () => {
assert.strictEqual(result, testClientIp2);
});

it('should not return client Ip address from header ' +
'if the request is forwarded from proxies, but the request ' +
it('should not return client Ip address from header if the request is forwarded from proxies, but the request ' +
'has no expected header or the header value is empty', () => {
const request = new DummyRequest({
headers: {
'x-forwarded-for': ' ',
'x-forwarded-for': '',
},
url: '/',
parsedHost: 'localhost',
Expand All @@ -61,4 +55,37 @@ describe('requestUtils.getClientIp', () => {
const result = requestUtils.getClientIp(request, configWithProxy);
assert.strictEqual(result, testClientIp2);
});

it('should return client Ip address from header if the request comes via proxies and ' +
'no request config is available', () => {
const request = new DummyRequest({
headers: {
'x-forwarded-for': testClientIp1,
},
url: '/',
parsedHost: 'localhost',
socket: {
remoteAddress: testProxyIp,
},
});
const result = requestUtils.getClientIp(request, configWithoutProxy);
assert.strictEqual(result, testClientIp1);
});

it('should return client Ip address from socket info if the request comes via proxies and ' +
'request config is available and ip check fails', () => {
const dummyRemoteIP = '221.10.221.10';
const request = new DummyRequest({
headers: {
'x-forwarded-for': testClientIp1,
},
url: '/',
parsedHost: 'localhost',
socket: {
remoteAddress: dummyRemoteIP,
},
});
const result = requestUtils.getClientIp(request, configWithProxy);
assert.strictEqual(result, dummyRemoteIP);
});
});