When a HTTP request is relayed by proxy servers, the end web server cannot obtain the IP address of the originating client through usual means. The industry de-facto standard X-Forwarded-For HTTP request header is often injected by the proxy servers to convey the information, so that the web server can perform IP address based services such as geolocation or filtering.

LineRate provides two methods for X-Forwarded-For injection: the Client-IP-Header command and the request.addHeader Node.js function. Either works fine, but you need to use only one: otherwise, you will have the same IP address twice in the header field.

While it is an administrator’s duty ensuring no duplication, you may want to guarantee it programmatically. You can achieve this goal easily by programming a script not to execute addHeader when the Client-IP-Header is configured. The Client-IP-Header in the currently running LineRate configuration is accessible via the REST API path /config/app/proxy/virtualServer/<virtual server name>/serviceHttp/clientIpHeader. LineRate’s Node.js module, managementRest, helps you query any object. You can also program the script to periodically check the status using the Node.js timer module.

Not to mention, you can download free trial LineRate (starter edition) from the URL below. Register now!

https://linerate.f5.com/try

Here is the script:

'use strict';
var vsm = require('lrs/virtualServerModule');
var mgmt = require('lrs/managementRest');
var header = 'X-Forwarded-For';
var regexp = new RegExp(header, "i");
var uid = {'username': 'admin', 'password': 'changeme'};
var period = 5 * 1000;  // milli-seconds
var path = '/config/app/proxy/virtualServer/VSOID/serviceHttp/clientIpHeader';
var state = false;

/* Timer checking the running-config periodically */
function timer(arg) {
    isClientIpHeader();
}

/* Set 'state' to true if client-ip-header is set to 'header'
 * Otherwise false */
var isClientIpHeader = function() {
    var client = new mgmt.Client();
    client.on('loginFailure', function(resp, body) {
        console.log('Failed to login REST: ' + resp.statusCode);
        return;
    });
    client.on('login', function() {
        var body = '';
        client.getJSON(path, function(response) {
            response.on('data', function(chunk) {
                body += chunk;
            });
            response.on('end', function() {
                var obj = JSON.parse(body);
		state = false;
                if (regexp.test(obj[path]['data'])) {
                    state = true;
                }
		client.logOut();
		return;
            });
        });
    });
    client.logIn(uid);
}

/* Header injection */
vsm.on('exist', 'vs1', function(vso) {
    path = path.replace('VSOID', vso.id);
    isClientIpHeader();
    setInterval(timer, period);
    vso.on('request', function(servReq, servResp, cliReq) {
        if (state == false) {
            servReq.addHeader(header, servReq.connection.remoteAddress);
        }
        cliReq();
    });
});