Problem
I need to get the client IP of a user connected through RDP/TS from an ASP site.
Sample data
The server hosting the site is at 10.1.0.1.
The user's machine is connected to a terminal server whose IP is 10.2.0.1.
The user is at a physical client whose IP is 10.3.0.1.
Attempted solutions
I have tried pulling the data from headers.
Request.ServerVariables["REMOTE_HOST"] 10.2.0.1
Request.ServerVariables["HTTP_X_FORWARDED_FOR"] [blank]
Request.ServerVariables["REMOTE_ADDR"] 10.2.0.1
Request.UserHostAddress 10.2.0.1
I also tried these methods.
public static string getIP()
{
string ips = string.Empty;
string hostName = HttpContext.Current.Request.UserHostAddress.ToString();
IPAddress[] ipAddresses = Dns.GetHostAddresses(hostName);
foreach (IPAddress ipAddress in ipAddresses)
{
ips += ipAddress + "<br />";
}
return ips;
}
Returns 10.2.0.1.
public static string GetIPAddress()
{
string ipAddress = "";
string Hostname = Environment.MachineName;
IPHostEntry Host = Dns.GetHostEntry(Hostname);
foreach (IPAddress IP in Host.AddressList)
{
if (IP.AddressFamily == AddressFamily.InterNetwork)
{
ipAddress= Convert.ToString(IP);
}
}
return ipAddress;
}
Returns 10.1.0.1.
Question
Is it possible to get 10.3.0.1 returned since there is an extra hop from the user's physical client through the TS to the web server? Is this possible with another language--e.g., PHP?
Before anything I know this question is duplicated but let me tell about my prob
As This Link demonstrated the Request.UserHostAddress only captures the IP address of the proxy server or router
for this reason I have used this code to return users IP Address :
string ip = String.IsNullOrEmpty(Request.ServerVariables["HTTP_X_FORWARDED_FOR"]) ? Request.ServerVariables["REMOTE_ADDR"] : Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(',')[0];
but it always return 172.30.1.1 when I connect with my PC,
in the other side my Phone is connected to Telecommunication 3G network
when I connected by phone that returns 172.30.1.1 again.
I also use this code:
public static string GetIP4Address()
{
string IP4Address = String.Empty;
foreach (IPAddress IPA in Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress))
{
if (IPA.AddressFamily.ToString() == "InterNetwork")
{
IP4Address = IPA.ToString();
break;
}
}
if (IP4Address != String.Empty)
{
return IP4Address;
}
foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (IPA.AddressFamily.ToString() == "InterNetwork")
{
IP4Address = IPA.ToString();
break;
}
}
return IP4Address;
}
but results are same.
so How can I return the real IP address of users?
Thanks in advance.
Edit: Misunderstood the question previously.
This is indeed an incorrect lookup and why it is returning the proxy/router ip addresses Request.ServerVariables("REMOTE_ADDR") is what sites like rapidshare use to limit downloads as a group, and not really useful.
What you want to be doing is comparing the HTTP_X_FORWARDED_FOR variable against it, to check that there isn’t a non-transparent proxy in the way.
Like so:
' Look for a proxy address first
Dim _ip As String = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
' If there is no proxy, get the standard remote address
If (_ip = "" Or _ip.ToLower = "unknown") Then _
_ip = Request.ServerVariables("REMOTE_ADDR")
Some more samples:
C#
// Look for a proxy address first
String _ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
// If there is no proxy, get the standard remote address
If (_ip == "" || _ip.ToLower == "unknown")
_ip = Request.ServerVariables["REMOTE_ADDR"];
ASP/VBScript
ipaddress = Request.ServerVariables("HTTP_X_FORWARDED_FOR")
if ipaddress = "" then
ipaddress = Request.ServerVariables("REMOTE_ADDR")
end if
I need to get the user's local IP for my ASP.NET application and I'm using this method:
protected string GetIPAddress()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split(',');
if (addresses.Length != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
However, when I publish my website I always get 192.168.2.1 no matter where the user is opening the website from.
Does anyone know how to solve this issue?
Some network devices make use of the X-forwarded-for header. You should check if the requests hitting your application have this header.
You can get the client's IP address from HTTP_X_FORWARDED_FOR or REMOTE_ADDR.
var ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(ipAddress ))
{
ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
return ipAddress;
Is there any way that I could get the original IP address of the client coming to the server?
I can use request.getRemoteAddr(), but I always seem to get the IP of the proxy or the web server.
I would want to know the IP address that the client is using to connect to me. Is there anyway that I could get it?
try this:
public static String getClientIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
Why don't use a more elegant solution like this?
private static final List<String> IP_HEADERS = Arrays.asList("X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR");
public static String getClientIpAddr(HttpServletRequest request) {
return IP_HEADERS.stream()
.map(request::getHeader)
.filter(Objects::nonNull)
.filter(ip -> !ip.isEmpty() && !ip.equalsIgnoreCase("unknown"))
.findFirst()
.orElseGet(request::getRemoteAddr);
}
Deduplicate your code!
request.getRemoteAddr() is the way. It appears your proxy changes the source IP. When some proxies do that they add the original IP in some custom http header. Use request.getHeaderNames() and request.getHeaders(name) and print all of them to see if there isn't anything of interest. Like X-CLIENT-IP (made that one up, but they look like this)
As this is usually a deployment concern, rather than an application concern, another approach would be to configure the application container appropriately. Once configured, the container takes care of inspecting the appropriate header and your application continues to use request.getRemoteAddr().
For example, in Tomcat you can use the Remote IP Valve. I would assume most application servers have similar functionality.
The container could also take care of understanding if your front-end load balancer is terminating SSL connections, forwarding the request to the app server over HTTP. This is important when your application needs to generate URLs to itself.
The best solution I've ever used
public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
You cannot do this in a meaningful way.
The proxy may or may not add a proxied-for header, but in many cases this will be an internal only address anyway, so it will be meaningless to you. Most proxies at the edge of an organization are configured to reveal as little as possible about the internals of the network anyway.
What are you intending to use this information for?
"x-forwarded-for" request header contains the original client IP if using a proxy or a load balancer. But I think not all proxies/lb adds this header.
Here some java code to parse the header:
http://www.codereye.com/2010/01/get-real-ip-from-request-in-java.html
If this header is not present then I would proceed as #Bozho suggests
String ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null) {
ipAddress = request.getHeader("X_FORWARDED_FOR");
if (ipAddress == null){
ipAddress = request.getRemoteAddr();
}
}
Why I think we should try to get IP from header 'X-Forwarded-For' first? If you get from request.getRemoteAddr(), it could be client's real ip or last proxy's ip which forwards the request. Thus we can't tell which condition it belongs to. However, if 'X-Forwarded-For' is set into the header, client ip is bound to be the left-most part of what you get from it.
/**
* Try to get real ip from request:
* <ul>
* <li>try X-Forwarded-For</li>
* <li>try remote address</li>
* </ul>
*
* #param request request
* #return real ip or ""
*/
private String tryGetRealIp(HttpServletRequest request) {
// X-Forwarded-For: <client>, <proxy1>, <proxy2>
// If a request goes through multiple proxies, the IP addresses of each successive proxy is listed.
// This means, the right-most IP address is the IP address of the most recent proxy and
// the left-most IP address is the IP address of the originating client.
String forwards = request.getHeader("X-Forwarded-For");
if (StringUtils.isNotBlank(forwards)) {
// The left-most IP must be client ip
String ip = StringUtils.substringBefore(forwards, ",");
return ip;
} else if (StringUtils.isNotBlank(request.getRemoteAddr())) {
// this could be real client ip or last proxy ip which forwards the request
return request.getRemoteAddr();
}
return "";
}
request.getHeader("True-Client-IP")
it will return the client IP address
InetAddress inetAddress = InetAddress.getLocalHost();
String ip = inetAddress.getHostAddress();
Please let me know how to get the client IP address,
I have tried all of the below things , but I am getting the same output: 127.0.0.1
string strClientIP;
strClientIP = Request.UserHostAddress.ToString();
string strHostName = System.Net.Dns.GetHostName();
string clientIPAddress = System.Net.Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
string ipaddress = string.Empty ;
ipaddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (ipaddress == "" || ipaddress == null)
ipaddress = Request.ServerVariables["REMOTE_ADDR"];
How can I get the correct IP?
You are on the right track with REMOTE_ADDR, but it might not work if you are accessing the site locally, it will show local host.
REMOTE_ADDR is the header that contains the clients ip address you should check that first.
You should also check to for the HTTP_X_FORWARDED header in case you're visitor is going through a proxy. Be aware that HTTP_X_FORWARDED is an array that can contain multiple comma separated values depending on the number of proxies.
Here is a small c# snippet that shows determining the client's ip:
string clientIp = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if( !string.IsNullOrEmpty(clientIp) ) {
string[] forwardedIps = clientIp.Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
clientIp = forwardedIps[forwardedIps.Length - 1];
} else {
clientIp = context.Request.ServerVariables["REMOTE_ADDR"];
}
If you connect via the localhost address, then your client address will also report as localhost (as it will route through the loopback adapter)