Неожиданности IPv6, или почему тупят Instagram и WhatsApp через прокси и VPN

Специальный корреспондент
Собака

Собака

Пресс-служба
Команда форума
Private Club
Регистрация
13/10/15
Сообщения
55.044
Репутация
62.840
Реакции
277.292
RUB
0
Довольно часто в последнее время на разных форумах и чатах люди жалуются, что когда они пользуются VPN или прокси, то у них после подключения на устройствах как-то странно начинают работать некоторые приложения. Например, не приходят сообщения в WhatsApp, не загружаютя сторис в Instagram, и другие подобные вещи. Причем нередко проблема чинится сама по себе спустя 10-15 минут после подключения, но после переподключения или переоткрытия клиента начинается снова. Иные жалобы состоят в том, что не смотря на то, что пользователь выходит в интернет через VPN или прокси, некоторые заблокированные сервисы и сайты у него все равно не открываются. И в том и в том обычно винят баги прокси/VPN-клиентов, администраторов серверов, и кого угодно еще. И я вам скажу: зря. Все гораздо проще и гораздо сложнее одновременно.

Давайте начнем с основ. Современный интернет построен на протоколе связи, который так и называется, Internet Protocol, сокращенно IP. В настоящее время используются две его версии, IPv4 из 70-х годов, и более современная IPv6. Основная разница между ними - в длине адреса, и соответственно, в максимальном количестве возможных IP-адресов. IPv6, собственно, и появился, когда стало ясно, что устройств, подключенных к интернету, в мире становится сильно больше, чем доступных адресов, а городить костыли в виде NAT'а бесконечно не получится и надо что-то с этим делать. IPv6 поддерживается уже многими популярными сервисами и сайтами, и активно распространяется по всему миру, что явно видно, например, из статистики Google:

0fabde232ad3a79d1c17bfbf124c3b0e.png

Россия, к сожалению, довольно серьезно отстает от других стран в этом плане, но даже в РФ некоторые мелкие и крупные операторы связи предоставляют своим клиентам IPv6-связность.

Как все это работает на деле? Когда ваш браузер, мессенджер или клиент какого-нибудь сервиса хочет соединиться с сервером, он в большинстве случаев делает это по доменному имени. Клиент обращается к DNS-серверу с просьбой сообщить ему IP-адреса, закрепленные за данным доменом. Сервер возвращает ему записи типа A (содержащие IPv4-адреса) и AAAA (IPv6-адреса). Если у удаленного сервера есть IPv6-адрес, а на устройстве, где работает клиент, на сетевых интерфейсах есть назначенный IPv6-адрес и IPv6-маршруты, то в большинстве случаев клиент пытается подключиться сначала по IPv6.

Мы же рассматриваем случай с VPN или с прокси, и тут возможных вариантов может быть гораздо больше. Когда вы подключаетесь к VPN-серверу или к прокси-серверу (в режиме TUN, он практически всегда используется, например, в мобильных клиентах), клиент создает в системе так называемый TUN-интерфейс, виртуальный сетевой адаптер. Через какой именно сетевой интерфейс пойдет трафик в другие сети (например в интернет) определяют маршруты в системе. Например, маршрут 0.0.0.0/0 буквально означает "до всех IPv4-адресов иди через отсюда". Изначально у вас на устройстве есть Ethernet- или WiFi-интерфейс, и чаще всего маршрут по умолчанию (тот самый "до всего") настроен через него (ваше устройство получает его от роутера или сразу от провайдера). Когда VPN-клиент или прокси-клиент-с-TUN-режимом поднимает в системе свой виртуальный интерфейс, он должен добавить маршруты через него с более высоким приоритетом, чтобы весь трафик шел в интернет не напрямую, а через прокси/VPN. И вот тут есть важная деталь: маршруты для IPv4 и IPv6 задаются по-отдельности. В итоге с VPN/прокси у нас может быть довольно много разных комбинаций. IPv6 может быть или не быть на клиентском устройстве от оператора связи. IPv6 может быть или не быть на VPN/прокси сервере. IPv6 может быть или не быть включен в прокси/VPN-клиенте. Могут быть еще разные вариации, например, IPv6-адрес выдается устройству роутером, но реальной IPv6-связности с интернетом нет. И так далее. Что же будет в каждом из этих случаев? Давайте рассмотрим варианты.

1. У провайдера нет IPv6 и VPN/прокси-клиент не добавляет IPv6-маршруты = весь трафик идет на прокси/VPN, всё неплохо, приложения даже не пытаются никуда идти по IPv6, а сразу идут куда им надо по IPv4;

2. Не важно, есть ли у провайдера IPv6, VPN/прокси-клиент добавляет IPv6-маршруты и на сервере есть IPv6-связность = весь трафик идет на прокси/VPN, всё отлично, даже если у вас не было IPv6, теперь он есть, все работает как надо и даже лучше, весь трафик идет через прокси/VPN;

3. Не важно, есть ли у провайдера IPv6, VPN/прокси-клиент добавляет IPv6-маршруты, но на сервере нет IPv6-связности = весь трафик идет на прокси/VPN, но при попытке соединиться с IPv6-серверами ничего хорошего не выйдет;

4. Провайдер/роутер дает вам IPv6-адрес и маршруты, но реальной связности нет, VPN/прокси-клиент не добавляет IPv6-маршруты = то же самое как в прошлом пункте, при попытке соединиться с IPv6-серверами ничего не выйдет;

5. У провайдера есть IPv6 и VPN/прокси-клиент не добавляет IPv6-маршруты = ваш IPv4-трафик пойдет через прокси/VPN, а вот трафик до IPv6-серверов пойдет напрямую;

Итак. Варианты 1 и 2 самые хорошие - никаких проблем, все работает как надо. Вариант 5 довольно опасный - часть ресурсов у вас открывается через прокси/VPN, а к части ресурсов трафик пойдет напрямую без прокси/VPN. В итоге, если вы пытаетесь подключиться к заблокированному сайту/сервису, то вам не дадут это сделать фильтры Роскомнадзора, и что еще хуже - если вы, используя прокси/VPN рассчитываете скрыть свой настоящий IP-адрес, например, оставляя сообщения на каких-либо форумах или в комментариях, то в этом случае есть риск засветить ваш настоящий IP от провайдера или мобильного оператора.

Варианты 3 и 4, казалось бы, не должны повлечь ничего ужасного. Для таких случаев существует так называемый механизм fallback. Когда клиент, например, браузер, пытается подключиться к удаленному серверу по IPv6, если подключение не было успешно установлено за определенное время (например, 500 миллисекунд), то клиент пробует подключиться еще раз, но через IPv4 вместо IPv6. Но есть одно но. Приготовьтесь... В Instagram и WhatsApp сломан механизм IPv6-fallback! Наглухо сломан. Если вы наберёте в Гугле "instagram IPv6 problem", то найдете огромное количество обсуждений не эту тему. Судя по всему, глюк есть только в версиях для iOS (по крайней мере, большинство жалоб именно от пользователей Apple). Учитывая, что оба приложени разработатываются одной компанией, весьма вероятно что там используется одна и та же библиотека или один и тот же код, и в нем есть этот баг. Проявляется он просто: при наличии IPv6-адреса в системе, но отсутствии реальной связности по IPv6, WhatsApp и Instagram не откатываются сразу же на IPv4, а начинают отчаянно тупить. В Whatsapp не доходят сообщения, в Instagram не грузятся сторис и фотографии, и т.д. Минут через 10-15 до них все-таки доходит, что связности нет, они наконец-то переключаются на IPv4, и все начинает работать как надо... до следущего переподключения или перезапуска приложения.

Да, и ещё важно сказать, что вышеперечисленные проблемы можно словить даже если вы в прокси-приложении настроите routing (иногда ещё называется split tunneling) чтобы, например, трафик до WhatsApp шел напрямую. Почему? Потому что все равно сначала все подключения прилетят по дефолтному маршруту на TUN-интерфейс, а уже потом клиент будет из разгуливать в соответствии с правилами, что-то отправляя на прокси, а что-то пропуская напрямую. IPv6 на TUN-интерфейсе есть, а реальной связности (у провайдера) нет - WhatsApp будет тупить.

Что же со всем этим можно сделать?
Если у вас или ваших клиентов тупит инстаграм/ватсап, или каким-то из онлайновых сервисов проверки IPv6-адреса вы видите айпишник из диапазона своего провайдера даже когда вы подключены к прокси/VPN, то нужно что-то делать.

Для VPN и для прокси рекомендации будут немного различаться, поэтому я разделю их на две части.

Для VPN.

Вариант 0
, наиболее правильный. Настройте IPv6-связность на сервере, выдавайте клиентам IPv6-адреса и default route IPv6.

Иногда начинающие админы начинают читать документацию и советы про IPv6 и утопают в его глубинах. Мол, если мы получаем от хостера префикс, то надо и каждому клиенту раздавать индивидуальные адреса из этого префикса, и тому подобное. После настройки, как правило, ничего не работает, потому что у хостеров обычно не-routed префиксы и нужно использовать что-то типа radvd ndppd.

Это все не обязательно! Меня сейчас наверное побьют в комментах, но я скажу страшную вещь - если вам просто надо, чтобы у ваших клиентов была IPv6-связность с минимальными усилиями, простой настройте такой же NAT для IPv6, как вы это делали для IPv4, и пусть они все выходят в интернет с одного адреса (это называется NAT6). Да, не красиво, да, не используются все возможности, но оно настраивается одной командой и сразу работает.

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

Вариант 2, замудренный. Иногда у хостеров не бывает IPv6 на сервере (бегите от таких!), например, есть баг ломающий IPv6 в известной платформе виртуализации OpenVZ. Тогда можно сделать так: установить на сервер DNS-сервер (например, dnsmasq), и настроить в нем, чтобы он выдавал только A-записи, без AAAA. И присылайте его в параметрах подключениях своим VPN-клиентам. Тогда проблемные приложения типа Instagram и Whatsapp просто не будут знать, что у их серверов есть IPv6-адреса, и не будут пытаться их использовать. Останется только проблема с DNS-кэшем (если AAAA-записи прилетели еще когда юзер не был подключен к вам).

Для прокси (сервера Shadowsocks, XRay, Sing-box, клиенты Streisand, v2rayNG, Nekobox, Hiddify-Next и другие)

Тут все немного отличается от VPN, потому что галочка "Use IPv6" в разных клиентах может обозначать разное. В каких-то случаях оно означает, назначить ли клиент IPv6-адрес и маршруты на свой TUN-интерфейс, а в каких-то случаях он это делает всегда, а галочка тупо режет IPv6-связность, либо определяет, будет ли встроенный DNS-клиент воспринимать AAAA-записи.

Вариант 0, наиболее правильный. Настройте IPv6-связность на сервере, включите IPv6 в прокси-клиенте. На сервере, как только у вас появился IPv6-адрес и ходят пинги, даже больше настраивать ничего скорее всего не надо будет.

Вариант 1. Выключить в прокси-клиенте все что связано с IPv6 (иногда этот режим называется IPv4-only). Если прокси-клиент достаточно умный, то он заодно будет перехватывать DNS-запросы и выдавать только A-записи вместо AAAA, либо будет делать сниффинг (об этом чуть позже), и в том и в том случае Инстаграм и Ватсап будут счастливы. И если клиент достаточно умный, он все равно назначит IPv6 на TUN-интерфейс, и у вас ничего не утечет напрямую. И то и то нужно внимательно проверить.
Если клиент тупой и отключение IPv6 в настройках не назначает его на интерфейс, то возможна утечка трафика, придется отключить IPv6 в системе на клиенте где только можно. Недостатки в этом случае будут те же, что и в пункте 0 для VPN, см. выше

Вариант 2. Если нет IPv6 на сервере, трюк с DNS как для VPN, но немного другой. Рассмотрим его на примере популярного сервера XRay. У него есть встроенный DNS-сервер, настроим его в конфиге:

{
...
"dns": {
"servers": [
"1.1.1.1",
"9.9.9.9",
],
"queryStrategy": "UseIPv4",
"tag": "dns"
},
...
}
Обратите внимание на опцию "UseIPv4", она означает то, что встроенный DNS будет оперировать только A-записями, а не AAAA, то есть только IPv4-адресами.

Далее, в "routing" в начале списка добавим правило, что все, что от клиента идет куда угодно на 53 порт (и TCP, и UDP), мы перехватим и перешлем на встроенный сервер, который обработает наш запрос, но вернет клиенту только IPv4-адрес домена, а не IPv6:

"routing":
{
"rules": [
...
{
"type": "field",
"inboundTag": [...],
"port": 53,
"outboundTag": "dns"
},
...
]
}
И в заключение, для каждого (если их несколько, надо продублировать) вашего inbound'а включим sniffing вот таким образом:

"inbounds":
[
...
{
...
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls",
"quic"
]
}
...
}
...
]
Это нужно на случай, когда клиент получил IPv6-адрес нужного ему сервера каким-то еще образом (достав из кэша или через DoH, который мы не можем перехватить). XRay-сервер "подслушает" имя хоста (для голого HTTP) или поле SNI для TLS/HTTPS/QUIC, еще раз отрезолвит нужный домен и отправит подключение не туда, куда хочет клиент (IPv6), а туда, куда посчитает правильным (IPv4, у нас так настроен встроенный DNS).

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

Вариант 3. Примерно то же самое что и вариант 2, но на клиенте.

Тут у каждого клиента пусть будет свой, но общий принцип такой же - включить в настройках Sniffing, включить его как "Sniff for destination", "Override destination" или что-то в этом роде, и в настройках локального DNS выбрать что-то типа UseIPv4 (или просто отключить IPv6 везде). Короче, нужно экспериментировать.

В некоторых клиентах вы получите то же самое сделав вариант 1.

Заключение

Теперь, если ы увидите, что кто-то жалуется на тупняк Instagram/WhatsApp через прокси/VPN, или на то, что у него через прокси/VPN по-прежнему не открываются заблокированные сайты, скиньте ему ссылку на эту статью.







 
  • Теги
    instagram vpn whatsapp
  • Сверху Снизу