When using Dns.GetHostAddresses("fred") it returns only IPv4 addresses in response. How to get the IPv6 addresses as well? Is there different method I shall use?
Socket.OSSupportsIPv6 returns true and IPv6 connections work fine. The OS is Windows 2008 R2, .Net version is 3.5.
IPv6 still uses DNS to resolve addresses so in order for this to work you will need to add an IPv6 entry to your zone file for this domain name. It'll then resolve properly.
I suspect that Ping will fall back to IPv4 if an IPv6 is not available, not exactly what you'd hope once you've specified the '-6' flag.
In case anyone is still having this problem in 2021, the System.Net.Dns class has an undocumented behavior: it filters addresses it thinks are unreachable when your only IPv6 address besides loopback is link-local. This filtering is performed even if the domain name exclusively resolves to a v6 address (you can try with v6.localhost.ayra.ch), in which case an exception is thrown.
If you're located in an IPv4 only network but want the ability to resolve v6 addresses in .NET, you can cheat your way around this problem by manually assigning your device a custom IP. Assign your device the IPv6 address 2001:db8::1 with a prefix length of 32 and no default gateway. I haven't found anything that stopped working so far because of this, and .NET will now resolve IPv6.
Note that the suggested IPv6 address and range is reserved for use in documentations, which means you should never encounter this range on the internet at all. If you want to make sure your choice doesn't conflicts with the address of someone else that follows this instruction, I suggest you use your mac address for the last 3 address segments.
I made a page that generates these address either with your MAC or randomly: https://cable.ayra.ch/docmac/
Related
What I Do
I am issuing a HTTP request from a remote client on the same IPv4 local network as a .NET Core ASP server. This server is configured to authenticate requests with a subclass of AuthenticationHandler that accesses the remote IP address through Context.Connection.RemoteIPAddress.
What I Expect
When the application is running on a Unixy system, Context.Connection.RemoteIPAddress returns an IPAddress that is represented as the expected "192.168.1.12".
What Happens
When the application is running on a Windows system, Context.Connection.RemoteIPAddress returns an IPAddress that is represented as "::ffff:192.168.1.12".
Problem
I want to compare the return value of RemoteIPAddress to another IPAddress value, that, however, is represented as the plain "192.168.1.12". Thus, the two addresses compare as unequal, even though they are (or should be!) the same.
Non-Solutions
This is an IPv4-only network, so there's been no point in trying to block IPv6 traffic.
I also don't want to do some sort of fuzzy string comparison; even though it would work and I can't see any problem with it, I have a sense there's a better solution out there.
Question
I can see two possible solutions, but I'm not sure how to achieve them:
There could be a way to ensure that RemoteIPAddress returns the remote IP address in the IPv4 shape that I expect.
It might be possible to always convert all IP addresses to this faux-IPv6 format, and if that conversion is idempotent, it would be a reasonable way to normalise all IP addresses before comparison.
How would I approach either of these solutions?
Is one objectively better than the other? (This should be an allowed question, because I'm not asking for personal opinions!)
Turns out option 2 was very simple: simply run .MapToIPv6() on both addresses before comparing. I think this might be the best solution, for the simple reason that it clearly will not cause any issues when/if this is used with IPv6 addresses too!
I am trying to retrieve a file on a network location - actually a NAS with fixed IP address.
Using File.Exists(#"//myserver/myfile.txt") works just fine, unfortunately, File.Exists(#"//192.168.1.101/myfile.txt") doesn't (of course, I made sure ping myserver returns 192.168.1.101).
I couldn't find any reasonable explanation as to why using DNS names would work but not IP address. Is this a known issue or is it possibly an issue with my network? I'd really get it to work with IP address, but is it possible?
I am trying to convert a VBScript COM component based Reverse/Forward IP checking system to C#.
This system was created to prevent the banning of SERPs like Googlebot using what was back then (becoming) the standard way of checking an IP was who it said it belonged to e.g a reverse/forward DNS check.
Although we have lists of SERP IP Ranges so we don't ban them if they come in - even with hack vectors - we cannot keep up with new ranges being added all the time.
The process is based around this short example.
It is explained simply here > http://ipadmin.junkemailfilter.com/rdns.php
This has been working fine for ages in VBScript but now I am converting to .NET I am having issues where people have set their IP to resolve to "localhost" like this one 113.168.154.182 as you just get back your own DNS server, Virgin media, or if I run it from my PC with c# I get my own computer name. The IP is from Vietnam > http://www.geoiptool.com/en/?ip=113.168.154.182
Now I am trying to use .NET and this code.
But as I am using this code to do get the hostname
IPHostEntry DNSHostIP = Dns.GetHostEntry("113.168.154.182");
hostname = DNSHostIP.HostName;
When I output the value of hostname I get my own computers name e.g std36w7.metal.mycompany.co.uk not localhost.
Then when I try and do a forward DNS check to get the list of IP addresses with this hostname I get my own IP addresses (one IPv6 one IPv4).
If I could get back "localhost" then I could have a check to skip it as a spoof along with anything starting with 10 or 192 etc.
However at the moment I cannot do this.
What is the best way of doing reverse/forward DNS checks which I thought was becoming the standard way of checking for spoofers nowadays in .NET?
And how can I handle people who have set (or some mistake might be causing it) their IP to be localhost.
Thanks
Simple. Your LOCAL DNS (guessing your router unless you have your own DNS server) is resolving it - upstream to it's INTERNET DNS server. Also if you really want it to return LOCALHOST, you'd have to literally edit your local HOSTS file and add an entry since no system ever returns the name LOCALHOST when you look up your ip even from a local DNS server. I believe the ONLY example is if you completely eliminate a DNS server to fallback on your local HOSTS file.
Problem: there's an input field in an application where the user can enter either a host name or an IP address. I need to tell if the entered address corresponds to a real host.
I'm not talking about a simple regular expression check or an IPAddress.TryParse or Uri.CheckHostName. I don't have difficulty with checking a hostname: if it cannot be resolved to an IP address, then Dns.GetHostEntry will throw an exception. That's a piece of cake.
However. If I get an IP address input, then if I make a Dns.GetHostAddresses call it'll always succeed, even if I enter a stupid IP, like "1.1.1.1" ("1.1.1.1" is an IANA reserved IP address, our DNS server reports "non existent host/domain"). The Dns.GetHostAddresses immediately just spits back the IP I just passed in like everything would be all right whatsoever.
I cannot use the Dns.GetHostEntry either, because there are some IP addresses (like my virtual machines on the local network) which don't have any DNS host names associated with them, but they still have valid IP addresses, and Dns.GetHostEntry would throw exception to those (I guess it tries to resolve a hostname for them?).
I need a method call which actually tells me if it is a bogus IP or not, even if it looks like good IP address (by Uri.CheckHostName), but it doesn't have corresponding DNS host name.
The only reasonably check you can make is if IP is some sort of reserved IP. Otherwise there is not much you can do - even lack of "ping" (ICMP) responses and lack of responses on well-known ports (like HTTP - 80) means nothing.
Reserved as in:
127.0.0.0/8 - loopback (may or may not be considered "valid host")
224.0.0.0 - 239.255.255.255 - multicast (unlikely to be considered "valid host")
all zeros/all ones in subnet (i.e. 192.168.1.0 and 192.168.1.255 for 192.168.1.0/24 subnet) are all/broadcast - clearly not associated with particular how.
Check IP4 subnetting and linked RFCs for more info on special ranges/IPs.
If Request.ServerVariables["HTTP_X_FORWARDED_FOR"] returns multiple ip's, which one do I take and how would I do it in c#? It is my understanding that if it is blank or null, then the client computer is not going through a proxy and I can just get their ip from Request.ServerVariables["REMOTE_ADDR"]. Is this a correct statement?
By "which one do I take", I mean do I take the first IP in the list or the last IP and is all I have to do is just split it into an array and take the one I want. I am not really sure how HTTP_X_FORWARDED_FOR works.
According to this, the format of X-Forwarded-For HTTP header is:
X-Forwarded-For: client1, proxy1, proxy2, ...
So the IP address of the client that you want should be the first one in the list
A further note on the reliability subject:
Anyone can forge HTTP_X_FORWARDED_FOR by using a tool such as the Firefox plugin "Tamper Data" or their own local proxy (e.g. Privoxy). This means that the entire string might be fake, and REMOTE_ADDR is the actual original host. It might also mean that the first "client1" address is faked, and then the client connected through a proxy, resulting in proxy1 being the client's IP address and REMOTE_ADDR being the single proxy used.
If you are looking to deny access based on IP, I would suggest checking every IP address in the XFF header as well as REMOTE_ADDR.
If you're looking to grant access based on the region of an IP, I'd suggest allowing access only if XFF is blank and the IP is from the proper area.
As Mastermind already noted, however, there are proxies which will hide the chain of proxies. For instance, the Tor network will make a request appear as if it came from the final proxy machine, rather than the original IP. Anonymizing proxies will often claim they are forwarding for the same IP as reported in REMOTE_ADDR.
IP based filtering is generally a pretty crude, last-resort mechanism of access control.
I asked some time ago a very similar question.
Getting the client IP address: REMOTE_ADDR, HTTP_X_FORWARDED_FOR, what else could be useful?
As correctly pointed out, you can take the first value considering it to be the client's IP address. But it may as well be company gateway IP.
And anonymous proxies will wipe out information in this header anyway, so it is useful but not reliable.
The actual client IP should be the left-most IP address in the header value. You can extract it into an environment variable using a regex:
SetEnvIf X-Forwarded-For "^(\d{1,3}+\.\d{1,3}+\.\d{1,3}+\.\d{1,3}+).*" XFFCLIENTIP=$1
Note the use of $1 to set the XFFCLIENTIP environment variable to hold the contents of the first group in the regex (in the parentheses).
As an example of using this, you can define a log format that uses the variable: this example is one we use internally at nearmap.com, so it logs extra information, but the bit you want is the %{XFFCLIENTIP}e at the beginning. Note the env=XFFCLIENTIP at the end of the line, which means this format is only used if the environment variable is set.
CustomLog /var/log/apache2/access.log "%{XFFCLIENTIP}e \"%{session}C\" \"%{nearmapuid}C\" %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" env=XFFCLIENTIP