1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
define_tag('client_real_ip',
-priority='replace');
// Transform the client request header to a pair array
local('h'=client_headers -> split('\r\n'),
'temp'=null,
'ip'=string);
iterate(#h, local('r'));
#temp=#r -> split(':') -> first;
#r -> removeleading(#temp + ':') & trim;
#temp = pair(#temp = #r);
#r=#temp;
/iterate;
// look for forwarded IP from proxy, firewall or load balancer
/* TODO: disregard pripvate IPs, i.e. 10.*, 192.168.* or 172.16.* 172.31.*
Possible other headers:
HTTP_PRAGMA, HTTP_XONNECTION, HTTP_CACHE_INFO, HTTP_XPROXY, HTTP_PROXY, HTTP_PROXY_CONNECTION, HTTP_CLIENT_IP, HTTP_VIA, HTTP_X_COMING_FROM, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_COMING_FROM, HTTP_FORWARDED_FOR, HTTP_FORWARDED, ZHTTP_CACHE_CONTROL
*/
if(#h >> 'client-ip');
#ip = #h -> find('client-ip') -> first -> value;
else(#h >> 'X-Forwarded-For');
// de facto standard for proxies, http://en.wikipedia.org/wiki/X-Forwarded-For
// can also return "unknown"
#ip = #h -> find('X-Forwarded-For') -> first -> value;
#ip -> trim;
else(#h >> 'PC-Remote-Addr');
// for server side cache, like Performace Cache
#ip = #h -> find('PC-Remote-Addr') -> first -> value;
else;
#ip = string(client_ip);
/if;
#ip = #ip -> split(',') -> first; // needed to get the actual client ip for x-forwarded-for, instead of the entire proxy chain
#ip -> trim;
return(@#ip);
/define_tag;
|