Назад | Перейти на главную страницу

Предпочитать входящие соединения IPv4 над IPv6

Мы запускаем социальную / локальную службу, которая извлекает выгоду из геолокации IP-адресов пользователей. Проблема в том, что с IPv6 геолокация немного более неоднородна, чем с IPv4.

Есть ли способ предпочесть входящие соединения IPv6 на хосте Ubuntu с nginx? Конфигурация выглядит так:

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

Предпочтение IPv6 / IPv4 определяется инициатором соединения, то есть веб-браузером. Правила выбора адреса определены в RFC 6724. Хотя их можно переопределить, это может сделать только пользователь, изменив конфигурацию своей операционной системы.

Единственный способ вы можете сила кто-то использует IPv4 - это вообще не предлагает IPv6. Очевидно, это не практическое решение даже в среднесрочной перспективе ...

Итак, давайте вернемся к исходной проблеме: геолокация для IPv6 «немного более неоднородна, чем с IPv4».

Частично это очень зависит от того, где вы получаете данные о геолокации. Maxmind, например, дает мой IPv6-адрес только как "Соединенные Штаты" без города и интересный набор координат, хотя Google, по крайней мере, правильно определяет мегаполис, до них все еще около 50 миль. И Maxmind, и Google позволяют вносить исправления в отчеты, по крайней мере, для Maxmind любой может сделать это для любого IP-адреса.

Я не ожидал, что такая ситуация продлится очень долго. Поскольку использование IPv6 продолжает расширяться, пользователи таких служб геолокации будут требовать большей точности для адресов IPv6, и в конечном итоге им придется предоставлять ее, по крайней мере, для платящих клиентов, чтобы эти клиенты не ушли в другое место.

А пока вы должны быть уверены, что у вашего приложения есть другие способы поиска пользователей. Если они вошли в систему, вы можете прочитать их существующую учетную запись, чтобы узнать их местонахождение. Вы можете попросить пользователя явно выбрать страну. И так далее...

Еще одна вещь, которую вы можете сделать, - это предоставить субдомен только для IPv4 и субдомен только для IPv6 вашего веб-сайта, каждый из которых ваши страницы будут пытаться загружать. Затем вы можете сопоставить их на стороне клиента и отправить отчет на сервер. Не случайно Maxmind уже делает это на своем собственном веб-сайте.

Такие предпочтения можно выразить с помощью записей SRV. К сожалению, они не поддерживаются для HTTP. Таким образом, вы остаетесь в ситуации, когда клиент в одиночку делает выбор между IPv4 и IPv6.

Многие клиенты используют время передачи SYN + SYN-ACK туда и обратно, чтобы решить, какой из двух вариантов использовать. Таким образом, замедляя отправку пакета SYN-ACK на IPv6, вы можете заставить большинство клиентов предпочитать IPv4. Но намеренное замедление работы вашего сайта - ужасный подход.

Вместо этого я бы сделал шаг назад и посмотрел на проблему. Вам нужны более точные данные о геолокации. Каждый раз, когда посетитель заходит на ваш сайт, вы сразу узнаете один из его IP-адресов. Будет ли это адрес IPv4 или IPv6, зависит от того, какой браузер предпочитает общаться с вашим сервером.

На своей странице вы можете использовать запрос AJAX, чтобы узнать другой IP-адрес. Для клиентов, использующих IPv4, отправьте запрос AJAX в домен только для IPv6, для клиентов, использующих IPv6, отправьте запрос AJAX в домен только для IPv4.

Как только запрос AJAX поступает на сервер, вы знаете как IPv4-, так и IPv6-адреса пользователя. Зная это соответствие, вы сможете выполнять геолокацию лучше, чем если бы вы знали только одно из двух.

Вы часто будете видеть случаи, когда запрос AJAX никогда не поступает на сервер. Для этих пользователей вам нужно будет выполнить геолокацию, поскольку вы можете сделать это лучше всего на основе только одного IP-адреса. Но до тех пор, пока ответ на этот запрос AJAX не используется ни для чего на стороне клиента, пользователь даже не заметит те, которые не выполняют запросы AJAX. Таким образом, запросы AJAX не будут вызывать видимого замедления или неустойчивого поведения.