Grokking NAT и искажение пакетов в Linux ( vivekn.dev )

colmacc 2 часа назад | следующий [–] Существенным недостатком в работе NAT является фрагментация IP. UDP-датаграммы могут быть больше IP-пакета. Когда это происходит, полезная нагрузка разделяется на несколько IP-пакетов, но только первый пакет содержит заголовок UDP. Устройство NAT должно сопоставлять эти пакеты, просматривая идентификаторы фрагментов, а затем перезаписывать IP-адреса в заголовках.
Это само по себе подразумевает второй тип состояния, который нужно поддерживать, но становится еще хуже. Фрагменты могут прибывать не по порядку. Если второй или последующие пакеты прибывают до первого, устройство NAT должно буферизировать эти фрагменты, пока не получит пакет с заголовком UDP.
Это может показаться маловероятным, но это удивительно распространено. Современные протоколы, такие как DNSSEC, требуют фрагментации, и в большой сети со многими путями фрагменты могут в конечном итоге выбирать пути, отличные друг от друга.
Обычно, когда сеть использует несколько ссылок для балансировки нагрузки трафика, маршрутизаторы будут использовать управление потоком. Маршрутизаторы смотрят на заголовок UDP или TCP, создают хэш кортежа соединения/потока, а затем используют этот хэш для выбора используемого канала. Таким образом, все пакеты из одного и того же соединения или потока будут направляться по одному и тому же каналу.
IP-фрагментация нарушает и это. Эти вторые и последующие пакеты не имеют заголовка UDP, поэтому их поток не может управляться без учета состояния. Более умные маршрутизаторы достаточно умны, чтобы понимать это с самого начала датаграммы и использовать только хэш из 3 кортежей (исходный IP, целевой IP, протокол)… поэтому пакеты все равно будут передаваться последовательно. Но многие устройства ошибаются — некоторые просто предполагают, что будет заголовок UDP, и выбирают любые значения, которые там окажутся.
Фрагменты в конечном итоге распределяются по разным путям, и если одно звено более перегружено или достаточно слабое, чем другое, они в конечном итоге прибудут в неупорядоченном виде.
Эта единственная морщинка, вероятно, отвечает за половину сложности в надежной реализации NAT. Представьте себе, что вам нужно решить все это в высокодоступной и транзакционно-реплицируемой реализации, такой как управляемые шлюзы NAT.
Хуже всего то, что всего этого можно было избежать. Если бы датаграммы UDP просто фрагментировались на уровне UDP, и каждый пакет включал заголовок UDP, ничего из этого не было бы нужно. Это, вероятно, худшая ошибка в TCP/IP. Но, очевидно, в целом это был очень удачный дизайн, который привел к появлению Интернета. 
Bluecobra 29 минут назад | родитель | следующий [–] Не уверен, согласен ли я с тем, что это худшая ошибка. Прелесть UDP в его простоте, и вы получаете абсолютный минимум. (И это то, что мне нравится!) Я работал над финансовыми сетями с низкой задержкой, которые маршрутизируют 40+ Гб многоадресной рассылки UDP ежедневно и без ошибок. Никто не фрагментирует пакеты UDP, и большинство размеров пакетов меньше 1000 байт. Все финансовые биржи имеют свой собственный фирменный формат, но все используют порядковые номера в датаграмме для отслеживания пакетов.
EvanAnderson 30 минут назад | родитель | предыдущий | следующий [–] > Это, пожалуй, самая серьезная ошибка в TCP/IP.
Я голосую за то, что TCP/IP не имеет сеансового уровня, как за худшую ошибку. У нас не было бы проблем с мобильностью IP, если бы был явный сеансовый уровень для отделения IP от протоколов верхнего уровня. 
jekwoooooe 41 минут назад | предыдущая | следующая [–] Я помню, как в свое время мне пришлось помогать больнице настраивать какой-то сумасшедший двойной nat Cisco vpn в другую больницу. Старая физическая техника и все такое. Это было так больно
gregw2 2 часа назад | предыдущая | следующая [–] Хорошая статья о различных типах NAT. Я узнал кое-что, спасибо!
Один отзыв; я бы использовал другое слово («wrangling»?) вместо «mangling» в вашем названии. Или упомянул IPv6.
Использование в заголовке слова «искажение» само по себе вызвало воспоминания об отслеживании повреждения контрольной суммы TCP в недорогих домашних маршрутизаторах или об ошибках в сетевых стеках OpenBSD, когда я работал над программным обеспечением для веб-конференций. Я испытываю сочувствие по поводу такого искажения, нажав на вашу ссылку, но вы использовали этот термин скорее для статьи, описывающей NATv4 и утверждающей, что «то, что делает IPv4 NAT, — это хакерское искажение, давайте все использовать IPv6». И при этом выдвигая этот аргумент (который, как ни странно, справедлив), вы также не признаете преимущества NAT для сокращения поверхности атаки входящих пакетов из несанкционированных источников и/или не объясняете, почему это не имеет значения, если вместо этого вы используете надлежащую защиту с помощью IPv6. И когда будет желателен IPv6 Npt (сетевой /префиксный/ перевод?)… Но я вижу, что это начинает выходить за рамки вашего предполагаемого аргумента/точки зрения, возможно… 
jeroenhd 58 минут назад | родитель | следующий [–] Я думаю, упоминания о том, что IPv6 делает NAT ненужным для большинства случаев использования, более чем достаточно.
Конечно, NAT все еще существует в IPv6. Возможно, не должен, но такие инструменты, как Docker, назначат полный /64 вашей локальной сети даже на таких системах, как VPS-серверы, где вам доступен только /112 или меньше. Плюс, NPT — это тип NAT, который просто переключает только часть адреса, вам все равно нужно искажать контрольные суммы и тому подобное.
Большинству людей, вероятно, удалось бы обойтись Docker, используя ваш локальный GUA для адресации и проксирования NDP напрямую (какова вероятность, что ваши разработчики на самом деле используют 2^64 адреса?), но из-за того, как Docker взаимодействует с nftables и как работает большинство брандмауэров Linux, использование NAT, вероятно, проще для обеспечения безопасности. 
akerl_ 2 часа назад | родитель | предыдущий | следующий [–] Mangle — это технический термин, используемый ядром для обозначения этих частей процесса.
jxjnskkzxxhx 20 минут назад | предыдущая | следующая [–] OT кто-нибудь еще считает не по теме слово “grokking”? Означает ли это понимание? Нужно ли нам новое слово для этой крайне базовой концепции?
theideaofcoffee 0 минут назад | родитель | следующий [–] Это довольно распространенное, общепринятое использование в хакерском лексиконе. См. Jargon File [0] esr, где, по некоторым источникам [1][2], оно начало использоваться в значении «понимание» в течение сорока с лишним лет с этого момента.
[0] http://www.catb.org/jargon/html/G/grok.html [1] https://books.google.com/books?id=uS4EAAAAMBAJ&pg=PA32#v=one… [2] https://en.wikipedia.org/wiki/Grok#In_computer_programmer_cu… 
GuinansEybrows 1 минуту назад | родитель | предыдущий | следующий [–] «Grok (/ˈɡrɒk/) — неологизм, придуманный американским писателем Робертом А. Хайнлайном для его научно-фантастического романа 1961 года «Чужак в чужой стране». В то время как Оксфордский словарь английского языка суммирует значение слова grok как «понимать интуитивно или с помощью эмпатии, устанавливать связь с» и «сопереживать или общаться с симпатией (с); также испытывать удовольствие», концепция Хайнлайна гораздо более тонка, и критик Иштван Чичери-Роней-младший заметил, что «основную тему книги можно рассматривать как расширенное определение термина». Концепция grok привлекла к себе пристальное внимание критиков в годы после первой публикации книги. Термин и аспекты базовой концепции стали частью таких сообществ, как компьютерная наука.
https://en.wikipedia.org/wiki/Grok 
viveknathani_ 9 часов назад | предыдущая [–] Написал что-то о компьютерных сетях. Захотелось разместить это здесь. Рад услышать твои мысли, HN!

Рассмотрите возможность подачи заявки на набор в YC на осень 2025 года! Заявки принимаются до 4 августа
Source: news.ycombinator.com