ASP.Net Core Detect real client IP - c#

I've got an ASP.NET Core app hosting on IIS, the server with which is behind the router. I need to detect real clients IPs. From the local network context.HttpContext.Connection.RemoteIpAddress returns correct IP, but from the outside it is always 127.0.0.1.
Also I tried to look at X-Original-For header which locally gives 127.0.0.1 and nothing form the outside.
I tried UseForwardedHeaders (https://stackoverflow.com/a/41450563/4801505) middleware but as I got it the middleware is already used by UseIISIntegration (https://github.com/aspnet/Docs/issues/2384) so there is no sense using it twice.
So, can I achieve the thing at all in my circumstances? Maybe some IIS config required?

Use the external link to get ip address.
I end up using
var httpClient = new HttpClient();
var ip = await httpClient.GetStringAsync("https://api.ipify.org");
If you are using any language other than C# refer to website ipify

Related

How do you set the base address of your API without hardcoding it?

I'm using HttpClientFactory to make API calls in a client application.
The API and the client app are both in the same Visual Studio solution. When executing my solution both apps are running on localhost on different ports. When creating an HttpClient instance I set the baseaddress uri like this httpClient.BaseAddress = new Uri("https://localhost:7854");.
With "not hardcoding it" I mean: I don't want to put the Uri in any code or config or json file or Azure Key Vault or whatever.
I want to avoid hardcoding the address and find an easier way since both Apps are in the same solution. Is there a way to achieve what I want?

Configure ASP.NET Core to work with proxy servers and load balancers

I have followed all steps explained on this Microsoft's documents page to be able to obtain remote client's IP address in an IIS-hosted app by calling HttpContext.Connection.RemoteIpAddress , but I keep getting the loopback IP address of ::1. There is only one weird scenario that gets me the remote client's IP address and that's by the service configuration code below where ForwardedForHeaderName is initialized by X-Forwarded-For-Custom-Header-Name which does not make any sense to me!
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardLimit = 2;
options.ForwardedForHeaderName = "X-Forwarded-For-Custom-Header-Name";
});
The full source code is found in this github repo and I'd like to know what exact change must be done to obtain the remote IP address successfully by removing "X-Forwarded-For-Custom-Header-Name" and why such a string gets me the IP address!
The idea is that X-Forwarded-For-Custom-Header-Name is meant to be replaced with a custom header name in case your proxy / load balancer doesn't use the standard X-Forwarded-For header but something different.
While X-Forwarded-For is the de-facto standard here, some proxies / load balancers use another header. In this case you would set it to the value used by your it, for examle X-Real-IP.
In your case, you will have to look at which headers are used in your setup and then configure your application accordingly.
When hosting in IIS using the default hosting model (dotnet publish should generate the appropriate web.config file), the forwarding is already set up and handled by the IIS middleware.
Unless you expect proxy to forward the original IP address in a header that is different from the usual X-Forwarded-For you don't have to specify ForwardedForHeaderName, instead configure it as:
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

Equivalent for Request.UserHostName in OWIN/Nancy

I am trying to return the users host name (not address) in owin. I am running nancy on top of this. I know I can use this.Request.UserHostAddress to get the IP but I need the name. I have looked through the API's goggled and I ma struggling to find this information.
The only way I can determine to do this is use the ASP.NET HttpContext.Current.Request.UserHostName but this won't work when we self host owin and writing code to determine this information depending on how OWIN is hosted seems to defeat the object of OWIN.
From an IP address, you can use Dns.GetHostEntry (or moral equivalents) to get a IPHostEntry object that has a HostName property.
That's all that UserHostName was doing for you anyway (a DNS lookup):
Gets the DNS name of the remote client.

How do I stop other domains from pointing to my domain?

I recently found out that there are other domain names pointing to my website (that don't belong to me) and I was wondering how people can stop/prevent this from happening. I'm hosting this on peer1 using IIS and I'm using ASP.NET C#.
Can I use an HttpModule or some other code to reject domain names that aren't mine?
Is there a better way?
You should activate name-based virtual hosting and only show your real website for the desired domain names. For all other names, you can display a suitable error message.
Details: Your webserver is contacted by its IP address. There is nothing you can do to stop that. Anyone can say, "connect to that IP address". For instance, anyone can register new domain names to point to your server's IP address. However, inside the request, there is a field Host with a name like www.example.com.
Upon receiving the request, your server may choose to inspect the Host field and deliver different content depending on that value. In the simplest case, the server ignores the field entirely and always prints out the same content. But in a more sophisticated set-up, so called "name-based (virtual) hosting", the server chooses the content depending on the hostname.
This is how shared webhosts work: There's a single server, but depending on the requested hostname it spits out a different website for each name.
Therefore, if you want to tie your server content to your hostname, you have to tell your server to produce your website only for your desired name, and to produce a different (error) website for all other cases.
In Apache this is trivial to configure, just check their documentation; for IIS I wouldn't know but I imagine it's equally simple.
If your hosting environment is IIS and you have admin access to it. Set your default website to show an error page and then create a new site with the host header matching your domain to point to your website.
This is my solution. It really works fast and solved my problem.
Insert this code in your .htacces
RewriteCond %{HTTP_HOST} !^www.higueyrd.com$
RewriteRule ^/?(.*) http://www.higueyrd.com/$1 [QSA,R=301,L]
Just put your domain.
In IIS there is a setting called bindings that allows you to select which hostnames your website will respond to. This feature allows an instance of IIS to host mulitple websites on a single IP address.
If you want your site to only work for http://example.com/ and http://www.example.com/, you should set the bindings to only work for "example.com" and "www.example.com".
The exception here is if you are using SSL. If you are, IIS cannot determine the hostname and you will most likely have to use a dedicated IP address for your site. In that scenario, user608576's solution will work. Although, I would put that code in your Global.asax file:
<%# Application Language="C#" %>
<script runat="server">
void Application_BeginRequest(Object sender, EventArgs args)
{
HttpRequest request = HttpContext.Current.Request;
HttpResponse response = HttpContext.Current.Response;
if( (request.Url.Host != "example.com") && (request.Url.Host != "www.example.com") )
{
response.Clear();
response.Write("Unauthorized domain name: " + request.Url.Host);
response.End();
}
}
</script>
As a temporary fix you can do this . May be on home page load or BeginRequest .
if(!Request.Url.Host.ToLower().contains("mysite.com")){
Response.Redirect("error.html");
}
If i remember right when i last check my sites cpanel i saw a feature that stopped redirections to my domain if checked. I´m using Hostso as my host so check their test cpanel for it.
Hope it helps alittle atleast :)
Fredrik wirth
if you want to handle in code then do it in Global.asax in BeginRequest as below
void Application_BeginRequest(object sender, EventArgs e)
{
if (!context.Request.Url.Host.ToLower().Equals("www.mydomain.com"))
{
context.Rewritepath("/invalidpage.aspx");
}
}
The other simple way is to specify a host headers in IIS for your website.
http://technet.microsoft.com/en-us/library/cc753195(v=ws.10).aspx
Note: I am writing through my mobile so consider spelling mistakes

How to simulate a Host file for the time of one request

I need to access simultaniously multiple instances of a web services with the following Url. The web services is hosted in IIS and has SSL enabled.
https://services.mysite.com/data/data.asmx
Usually, when we do this process manually, we go one by one and update the Windows host file (c:\Windows\System32\drivers\etc\hosts) like this :
192.1.1.100 services.mysite.com
I would like to automate the process and do it with some multithreading. So I cannot change the Host file. Is there a way to simulate a host file when we do a HTTP request in C#?
Thanks!
If you know the IP address of the server's SSL endpoint (which isn't necessarily the same as the server's default IP address), then you could just aim you web-service at that? Obviously the SSL check will fail, but you can disable that through code...
ServicePointManager.ServerCertificateValidationCallback += delegate
{
return true; // you might want to check some of the certificate detials...
};
I think you get the same effect by setting the proxy server of that specific request to the IP address of the actual Web server you want to send the request to.
You can change the URL that your request is hitting at runtime, something like this:
svc.Url = "http://firstServer.com";
So if you create a program that loops through each of your desired servers, just update the URL property directly (that example is taken from WSE 3 based web services).

Categories

Resources