How to bypass Proxy server and log real visitor’s IP address
This article shows how to log the real visitor’s IP address into the Event log events, instead of the proxy server’s IP address.
As you know, one piece of information contained in the log in the Event log module, is IP address. This IP address belongs to the user who performed a given action. If blank, the event was not raised by a user action, but was raised by the system itself. This problem may occur when the application is running beyond a proxy server. In this case, the entire event's in the Event log may being logged with the proxy server’s IP address, instead of real visitor’s IP address.
One way how to log the real client’s IP address is using the code below in the BeforeRequestBegin event defined in the App_Code/Application/CMSAppBase.cs file:
using System;
using System.Collections.Specialized;
using System.Web;
using CMS.GlobalHelper;
using CMS.SettingsProvider;
[PcsCustomRequestEventHandler]
public partial class CMSModuleLoader
{
/// <summary>
/// Attribute class that ensures the loading of custom handlers
/// </summary>
private class PcsCustomRequestEventHandlerAttribute : CMSLoaderAttribute
{
/// <summary>
/// Called automatically when the application starts
/// </summary>
public override void Init()
{
// Assigns custom handlers to the appropriate events
CMSRequestEvents.Begin.Before += new EventHandler<EventArgs>(SetClientAddress);
}
void SetClientAddress(object sender, EventArgs e)
{
string sClientAddress = null;
NameValueCollection oColl = null;
if ((HttpContext.Current != null) && (HttpContext.Current.Request != null))
{
oColl = HttpContext.Current.Request.Headers;
foreach (string sKey in new string[] { "CLIENT-IP", "X-FORWARDED-FOR" })
{
sClientAddress = oColl[sKey];
if ((sClientAddress != null) && (sClientAddress == "::1"))
{
sClientAddress = null;
}
else if (!String.IsNullOrWhiteSpace(sClientAddress))
{
break;
}
}
if (String.IsNullOrWhiteSpace(sClientAddress))
{
oColl = HttpContext.Current.Request.ServerVariables;
foreach (string sKey in new string[] { "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR" })
{
sClientAddress = oColl[sKey];
if ((sClientAddress != null) && (sClientAddress == "::1"))
{
sClientAddress = null;
}
else if (!String.IsNullOrWhiteSpace(sClientAddress))
{
break;
}
}
}
}
if (!String.IsNullOrWhiteSpace(sClientAddress))
{
RequestStockHelper.Add("UserHostAddress", sClientAddress);
}
}
}
}
For Kentico 8 you need to replace part of the code with this:
//old code
// if (!String.IsNullOrWhiteSpace(sClientAddress))
//{
// RequestStockHelper.Add("UserHostAddress", sClientAddress);
//}
//new code
if (!String.IsNullOrWhiteSpace(sClientAddress))
{
RequestContext.UserHostAddress = sClientAddress;
}
Please note - you may need to configure your proxy server to pass the real client IP through to the web server in proper server variables or request headers. There is no standard for what the variable/header name will be, but the "client ip" and "x forwarded for" seem to be the most common names.
-rm-
See also: Event log
Applies to: Kentico 7.x, for Kentico 8.x please see this Q&A thread