Nginx – Prefer IPv4 incoming connections over IPv6

ipv4ipv6nginx

We run a social/local service that benefits from geolocating the IP of users. The problem is that with IPv6, geolocation is quite a bit spottier than with IPv4.

Is there a way to prefer incoming connections over IPv6, on a Ubuntu host with nginx? The config looks like this:

server {
    listen 80 default_server;
    listen [::]:80 ipv6only=off default_server;
}

Best Answer

IPv6/IPv4 preference is determined by the initiator of a connection, i.e. the web browser. The address selection rules are defined in RFC 6724. While these can be overridden, it is only by the user reconfiguring their operating system.

The only way you can force someone to use IPv4 is to not offer IPv6 at all. Obviously this is not a practical solution even in the medium term...

So, let's go back to the original problem: Geolocation for IPv6 is "quite a bit spottier than with IPv4."

In part this is very dependent on where you get your geolocation data. Maxmind for instance only gives my IPv6 address as "United States" with no city at all and an interesting set of coordinates, while Google at least correctly identifies the metropolitan area they are still about 50 miles off. Both Maxmind and Google allow for reporting corrections, and at least for Maxmind anyone can do this for any IP address.

I would not expect this situation to last very long. As IPv6 usage continues to expand, users of such geolocation services will demand greater accuracy for IPv6 addresses, and they will have to deliver it eventually, at least for paying customers, lest those customers go elsewhere.

In the meantime, you should be sure that your application has other ways to locate users. If they logged in, you could read their existing account for clues as to their location. You could ask the user to explicitly select a country. And so on...

One other thing you can do is to provide an IPv4-only subdomain and an IPv6-only subdomain of your web site, each of which your pages attempt to load. You can then correlate them client side and report back to the server. Not coincidentally Maxmind is already doing this on their own web site.

Related Topic