В этом комиксе сама идея, что у обычного человека может быть свой FTP-сервер, отвергается с ходу — и действительно, это редкость. Для среднего пользователя компьютера мысль о том, что кто-то может просто подключиться к его машине, кажется экзотикой или даже угрозой — вспомнить хотя бы распространённый иронический страх перед тем, что кто-то узнает твой IP-адрес.
Если взять человека, который "хорошо разбирается в компьютерах", но не занимается сетями, его мысленная модель интернета скорее всего включает представление о "серверах" или "облаке" как о чём-то принципиально отличном от персонального компьютера. Настоящий пиринг, если о нём вообще заходит речь, воспринимается как отдельное предприятие: WebRTC, STUN, TURN, ICE и всё такое. Учитывая, что мир живёт в условиях NAT, CGNAT и ограничительных политик провайдеров, это не совсем ошибочное представление — но оно ломает изящный изначальный замысел интернета.
Почему у вас нет FTP-сервера
Трансляция сетевых адресов (NAT) была впервые формально предложена в RFC 1631 в 1994 году. В аннотации документа говорится:
Две наиболее острые проблемы, стоящие перед IP-интернетом — это истощение адресного пространства IP и масштабирование маршрутизации. Разрабатываются как долгосрочные, так и краткосрочные решения этих проблем. Краткосрочное решение — CIDR (бесклассовая междоменная маршрутизация). Долгосрочные решения состоят из различных предложений новых интернет-протоколов с более длинными адресами.
Бесклассовая междоменная маршрутизация — не главная тема этого материала, но суть в том, что тогда появилось больше вариантов размеров сетей, и, несмотря на сложность реализации, философски эта идея практически не вызывала возражений.
RFC 1631 предложил и второе краткосрочное решение проблемы истощения IP-адресов и масштабирования маршрутизации: NAT. Это не совсем тот же тип NAT, что стоит сегодня почти в каждом домашнем роутере, но базовая идея та же: он позволяет нескольким устройствам делить один IP-адрес (с точки зрения устройства на другом конце маршрутизации), изменяя информацию о сетевых адресах в заголовках IP-пакетов при прохождении через маршрутизирующее устройство. Позже определённые адреса зарезервировали для частного использования, и в большинстве IP-сетей эти механизмы работают в связке — приватные адреса внутри сети, NAT до одного публичного адреса на роутере. Вот как обычно происходит соединение с внешним сервером через NAT на типичном домашнем роутере1:
-
Компьютер отправляет пакет вида:
Source IP 10.11.70.21 Source Port 50413 Destination IP 67.215.249.229 Destination Port 70 -
Пакет попадает на роутер, который изменяет его так:
Source IP 146.7.15.85 Source Port 60612 Destination IP 67.215.249.229 Destination Port 70 -
Сервер отвечает:
Destination IP 146.7.15.85 Destination Port 60612 -
Роутер переписывает адрес обратно:
Destination IP 10.11.70.21 Destination Port 50413
Если додумать эту логику до конца, возникает вопрос: а что если внешний сервер захочет заговорить первым? Он отправляет пакет на 146.7.15.85, и роутер…
Вот незадача. Роутер понятия не имеет, куда его пересылать.
Как с этим борются
Проблему заметили почти сразу, ведь люди хотели держать игровые серверы, FTP и веб-серверы у себя дома фактически с начала времён. Так вокруг NAT сложилась целая экосистема обходных путей — ни один из которых не восстанавливает изначальный замысел интернета и ни один не работает универсально.
Проброс портов
Самое прямое решение — сказать роутеру: "когда приходит пакет на порт 60612, отправляй его на 10.11.70.21 на порт 50413, без вопросов". Это проброс портов (port forwarding), и это самый известный способ обхода NAT. Концептуальная проблема в том, что один публичный IP+порт может отображаться только на одно устройство одновременно — а значит, два устройства не могут одновременно держать сервис на одном и том же публичном IP+порте. Проблема серьёзнее, чем кажется: в крупных корпоративных или университетских сетях, которые сжимаются до нескольких или даже одного приватного IP, это фактически убивает возможность локального хостинга без ещё более сложных ухищрений. А иногда провайдер прячет за NAT ещё и ваш внешний IP — это называется carrier-grade NAT (CGNAT), — и тогда устройство, выполняющее трансляцию, вам не подконтрольно, так что пробросить порт нельзя вообще. Пользователю достаётся доля от доли IP-адреса.
Ещё одна проблема NAT в том, что никто не хочет с этим возиться — именно поэтому изобрели:
UPnP
UPnP и его современные родственники NAT-PMP и PCP попытались решить проблему "никто не хочет возиться", позволив программам напрямую просить роутер о пробросе портов. Как и ручной проброс, это запрос к вашему роутеру — если провайдер зажимает адреса, это не поможет. UPnP часто отключают из-за неверно понятой безопасности — отчасти из-за пары багов в ранних реализациях, отчасти потому, что сама идея, что кто-то может подключиться к твоему компьютеру, многим кажется экзотичной или опасной. Есть много веских причин хотеть файрвол, но в этом случае стоит осознанно его настроить, а не полагаться на то, что NAT просто не знает, куда слать пакеты.
STUN, TURN и ICE
STUN
Session Traversal Utilities for NAT (STUN), вместо того чтобы договариваться с файрволом, просто спрашивает сервер в публичном интернете: "как выглядит мой пакет к тому моменту, когда доходит до тебя?" STUN-сервер возвращает публичный IP и порт, назначенные NAT — скажем, 146.7.15.85:60612. При "конусном NAT" (cone NAT), когда роутер использует одинаковое внешнее отображение порта для всех исходящих соединений, это отлично работает. Такое отображение можно сообщить пиру, и он сможет отправлять пакеты напрямую. Эта техника называется пробивание отверстий (hole punching). Но при "симметричном NAT" — частом на CGNAT и в институциональных сетях — для каждого отдельного получателя назначается свой публичный порт. В этом случае STUN-отображение бесполезно для соединения с пиром, поскольку тот увидит вас иначе, чем видит STUN-сервер.
TURN: капитуляция
Traversal Using Relays around NAT (TURN) — это просто прогон трафика через ретранслирующий сервер, к которому обе стороны подключаются исходящими соединениями. Работает почти везде, но кто-то должен держать сервер, который в идеале был бы не нужен, а каждый пакет получает дополнительную задержку из-за прохождения через третью сторону — в общем, так себе решение.
ICE: перебор всего подряд
Interactive Connectivity Establishment (ICE) исходит из того, что ни одна техника не надёжна сама по себе, и пробует их все по порядку предпочтения. В расчёт идёт всё: прямое соединение, внешний адрес, найденный через STUN, TURN-ретранслятор — списком обмениваются со второй стороной и перебирают варианты, пока что-нибудь не сработает. Именно так устроен WebRTC, и это лучшее, что можно получить в сегодняшнем интернете. Но простое прямое соединение в итоге заменили, по сути, внешней инфраструктурой.
Долгосрочное решение, которого не случилось
Главным "долгосрочным решением", о котором говорил RFC 1631, был IPv6 — предполагалось, что он всё исправит: даст каждому по-настоящему уникальный глобальный адрес и сделает NAT ненужным. Однако сигмоида внедрения IPv6, похоже, застопорилась слишком рано, и даже там, где протокол внедрён, многие провайдеры и институциональные сети по инерции продолжают заниматься NAT-подобными вещами, руководствуясь всё той же неверно понятой безопасностью: файрволы блокируют входящие соединения просто потому, что к этому привыкли благодаря NAT, а порой и вовсе совершенно излишне применяют настоящий NAT к IPv6 — нередко разворачивая Unique Local Addresses (fc00::/7) точно так же, как приватные адреса RFC1918 в IPv4, что вызывает искреннее недоумение.
Последствия для интернета
В смерти открытого интернета можно винить многое, но NAT, похоже, был одной из самых ранних причин. Когда-то запустить сервер было элементарно: собрал исполняемый файл, сообщил людям адрес — готово. Теперь, если повезёт, придётся настраивать проброс портов, а если сидишь за CGNAT или в институциональной сети — зачастую даже этого сделать нельзя.
NAT также приучил всех считать клиент-серверную модель чем-то естественным. Ощущение "моё устройство говорит с облаком, которое говорит с другими устройствами" кажется нормой, хотя изначально возникло как побочный эффект дефицита адресов. Ещё более иронично, что NAT закрепился в массовом сознании как функция безопасности — "твои устройства скрыты!" — и именно это заставляло людей сопротивляться тому решению, которое реально устранило бы проблему.
NAT, разумеется, не единственная причина, по которой современный интернет превратился в набор централизованных закрытых садов, но он стал первой такой причиной — именно из-за него сложно просто отправить кому-то файл, именно поэтому почту не держат на собственном компьютере, и именно поэтому вообще держать собственные сервисы трудно и часто дорого (если провайдер не даёт пробросить порт, приходится покупать VPS вместо того, чтобы использовать железо, которое уже есть под рукой).