I have a service that is running in Amazon Ec2. The service exposes both a http endpoint and a https endpoint. I am doing some geo lookup on the user IP address when I log the data. Everything works just fine on requests coming into the http endpoint. I have to grab the X-Forwarded-For header so that I do not take the Amazon Load Balancer UP Address and I am always able to get what I need. However on requests that come in on the https endpoint all of the IP addresses are the same.
In order to pull the IP address I am using the following C# code:
public static string FetchClientIp(HttpRequest req)
{
var value = req.Headers["X-Forwarded-For"];
return string.IsNullOrEmpty(value) ? req.UserHostAddress : value;
}
I can't find anything else that I need to do that is specific to https requests so I'm hoping someone here has run into this before. I'm going to spin up a test on this to try to better isolate the problem.
Thanks
It depends how you have your ELB set up.
If you're terminating SSL on the ELB (new feature as of October 2010), then the client IP address will be in "X-Forwarded-For".
HttpContext.Current.Request.Headers["X-Forwarded-For"]
It sounds like you're terminating SSL on your web servers, then ELB can't decrypt the traffic and add the "X-Forwarded-For" header to the HTTP request. So the client IP address in the header "REMOTE_ADDR" (which is the header returned by HttpRequest.UserHostAddress) is the IP of the last hop -- in this case the internal IP address of the ELB.
Keep in mind, "X-Forwared-For" may contain multiple IP addresses as described at http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/index.html?SvcIntro.html#X-Forwarded-For. In that case, you're probably most interested in the first address listed.
Related
I am trying to retrieve the client's IP address in my .net backend, which is running in Docker.
With the code snippet below, I would expect to get the IP address of the client but I get 172.17.0.1 instead, which is some local IP address (Docker probably).
public async Task Invoke(HttpContext context)
{
var clientIpContext = context.Connection.RemoteIpAddress?.MapToIPv4().ToString();
...
await _next(context);
}
I hope someone can help :)
I'm not too familiar with docker, but most proxies forwarding on HTTP requests will populate the X-Forwarded-For header with the original originating IP address.
You could check the incoming request for that header to see if your client IP address is there.
I am trying to make a Soap call to a webservice hosted by business partner. The problem I am having is that our client is hosted on a virtual PC with multiple IPs. I would like to call the hosted webservice with a different (not default) IP address. Why is that? There is VPN connection between our client application and hosted webservice but it is set up LAN2LAN between two IPs. Now I have to change local source IP address to match with the VPN requirements.
I have tried using SoapHttpClientProtocol's WebProxy, setting its value to the new IP but it does not seem to work. I am getting HTTP 404 error.
Here is some of the code:
//soapApiClient is typeof SoapHttpClientProtocol
//endpoint url -> webservice, url from appSettings
var url = SettingsProvider.ClientSapGetUserDataUrl;
soapApiClient.Url = url;
//proxy settings -> setting new IP, defined in appSettings
var proxy = SettingsProvider.ClientProxyAddress;
soapApiClient.Proxy = new WebProxy(proxy);
//credentials
soapApiClient.Credentials = GetCredentials();
I HTTP post user code and return value should be user data from SAP, currently I am getting 404 http error code. For comparison, it works like a charm from SoapUI. Maybe setting proxy is not what I am looking for? Any help would be much appreciated.
EDIT: To be more clear
Currently, by default service is called from default ip 91.185.201.88. Service's IP is 10.67.145.70. I want to change it like so: service is called from 192.168.4.2 to service's 10.67.145.70.
I finally managed to make it work. If anyone else will have problem with this, just follow these instructions.
Before calling remote service, you have to find service point for it. This is done via ServicePointManager like so
Example:
var servicePointUserReader = ServicePointManager.FindServicePoint(new Uri(FULLY QUALIFIED REMOTE SERVICE URL));
servicePointUserReader.BindIPEndPointDelegate = (sp, remote, retryCount) => new IPEndPoint(IPAddress.Parse(SOURCE IP FROM WHICH YOU WANT TO SEND REQUEST), 0);
In my example, fully qualified remote service url was something like http://65.145.63.71:8010/sapService (this is the one we are trying to call). Then I wanted to make a call from a different IP on our virtual PC which has many IPs addressed to it. You just need to input desired IP as shown in the second line of the code, for example 192.168.5.1.
Make sure you use "http://" when calling FindServicePoint with new Uri() constrcutor otherwise it will not work!
After that just proceed with the call to the service. Two lines of code, that's all you need. :)
I have my .net core api that wants to access a service which is hosted on another server. My current working connection string is:
"AuthorityUrl": "https://identity.test.company.eu/"
The https://identity.test.company.eu is a website listening on a Server whose address is 192.168.41.2 . This website is hosted on IIS and listening to all unassigned ip with hostname in the bindings set to identity.test.company.eu . This means that IIS redirects the call towards this specific website. How does it do it? It reads that the incoming http call has hostname header equals to identity.test.company.eu and therefore is able to route the call.
Now, let's say that I don't have access to the DNS mapping and that I have to set manually in my connection string that I want to send a request to the 192.168.41.2 server and include in the call the hostname header identity.test.company.eu . In such a way IIS on the server redirects the call towards the right website. How can I do this?
Thansk!
I'm trying to access websites via the ip address rather than http address. I am trying out a number of well know sites such as microsoft and google and getting their ip address by pinging them. For instance 184.87.106.199 is microsoft and 216.58.221.68 is google.
async Task<HttpStatusCode> RequestPage(string url, HttpClient client) {
var request = new HttpRequestMessage();
try {
var response = await client.GetAsync("http://" + url);
Console.WriteLine(string.Format("{0} - {1}", url, response.StatusCode.ToString()));
return response.StatusCode;
} catch (TaskCanceledException) {
Console.WriteLine(string.Format("{0} - Timeout", url));
return HttpStatusCode.GatewayTimeout;
}
}
However it does not appear to work for every site. google works fine if i request http://216.58.221.68 but microsoft returns a bad request status.
what am i missing?
You cannot reliably visit a website based on the IP address. Often a server is configured to host multiple websites on a single IP address, and based on the URL it will serve the correct website.
When you make an HTTP request to a website with your browser, the browser itself will do the lookup for IP address and then connect. However, your browser will send something like this:
GET http://stackoverflow.com/ HTTP/1.1
Host: stackoverflow.com
This means the remote end knows which website to send you to as the server could be hosting many sites, particularly in a shared hosting environment.
Also, to complicate matters even further, some websites will have multiple IP address.
I recently wrote an application for our company to process newsletter signup requests via signup emails sent to an inbox on our Exchange 2003 servers using WebDAV. This all works fine.
Now we've realized that for auditing purposes, we need to capture the ip address of where the signup request originated. My question is, is there a way to request the original ip address of the originator of the email with my WebDAV request?
I've browsed through the urn:schemas:mailheader: and the urn:schemas:httpmail: documentation and didn't see a field you can request with this data besides maybe urn:schemas:mailheader:path. But when I make a request to our exchange server with the path in the request, the status for that property comes back 404 not found.
It looks like http://schemas.microsoft.com/cdo/smtpenvelope has a clientipaddress property that would have this information, but that is only applicable to messages still in transit.
Has anyone had to do this before and figured out a way to snag the ip address of the user who originated the email? It probably isn't helpful to the question, but the format of my WebDAV request is below:
string webdav =
#"
<?xml version=""1.0""?>
<D:searchrequest xmlns:D = ""DAV:"">
<D:sql>
SELECT
""DAV:displayname"",
""urn:schemas:httpmail:fromemail"",
""urn:schemas:mailheader:subject"",
""urn:schemas:httpmail:textdescription"",
""urn:schemas:mailheader:date""
FROM
SCOPE('shallow traversal of ""{0}""')
WHERE
""DAV:isfolder"" = false AND
""urn:schemas:httpmail:read"" = false
</D:sql>
</D:searchrequest>
";
This comes back to SMTP more than it comes to Exchange/WebDAV. It really depends on which email service the end user is using. SMTP can pass an email around multiple times before it ends up at the destination. Normally, each hop adds a Received: from header, with some additional information like an IP address.
But, some services, like Google, don't count the user sending the email has a hop, and the originating IP address is a Google SMTP server. So you'll never know the end user IP address from the email. Then, other services may count the end user's public IP address as the first hop. And some other services may add a special header like X-Sender-IP or X-Originating-IP to the message.
So, there isn't a guaranteed way to obtain that information. Part of it has to do with the distributed nature of SMTP, the prevalence of webmail and some privacy concerns. If this information is critical to your auditing, you may want to setup a simple webform which could send an email to this inbox, and then you could add additional information like an IP address to the body of the email.