
Я изучаю частные/публичные IP-адреса, переадресацию портов и NAT, но все еще не вижу ответа на простой вопрос:
Предположим, что два пользователя в одной сети общаются с одним сервером за пределами своей сети (скажем, я и моя жена отправляем http-запросы на yahoo.com). Сервер видит обоих пользователей как один публичный ip-адрес, и часто — как в этом случае — общающихся на одном и том же порту. Как маршрутизатор маршрутизирует пакеты в соответствии с двумя разными соединениями? Есть ли какая-либо информация о маршрутизации внутри пакета помимо ip/port? Ведется ли где-то некая «таблица сеансов»? Кем и что именно она включает?
решение1
Внутри компьютера, между процессами
Сначала давайте посмотрим, какодинокийкомпьютер различает одновременные соединения.
Большинство транспортных протоколов, таких как TCP, UDP, SCTPиспользоватьдвапорты, источник и пункт назначения– т.е. один на каждом конце соединения. То есть пакетынепросто пройти «сквозь» порт; вместо этого они путешествуютотпорт Xкпорт Y.
Theместо назначенияПорт обычно хорошо известен (80 для HTTP, 53 для DNS…), ноисточникПорт обычно выбирается случайным образом самой ОС, что также гарантирует уникальность комбинации src/dst.
Поэтому, когда ваш браузер устанавливает несколько подключений «к порту Yahoo 80», все они на самом деле имеют разныеисходные порты, а ОС хранит таблицу сокетов, например:
PROCESS PROTO LOCAL REMOTE STATE
9894/firefox tcp 192.168.6.175:39163 google.server:80 established
9894/firefox tcp 192.168.6.175:52909 yahoo.server:80 established
17463/chrome tcp 192.168.6.175:64981 yahoo.server:80 established
9894/firefox udp 192.168.6.175:4984 8.8.8.8:53 --
Таким образом, когда ОС получает TCP-пакет с yahoo.server:80
локального порта 52909, она может сопоставить его с определенным соединением, созданным Firefox.
Важно отметить, что это не имеет ничего общего с NAT.еще, и происходит то же самое, даже если вы подключены напрямую. (Хотя NAT будет использовать это.)
(Эту таблицу можно просмотреть с помощью netstat -n
, или различных графических инструментов в Windows. Часто «локальные/удалённые» обозначаются как «источник/назначение», хотя это не совсем точно.)
В сети с NAT, между компьютерами
Ответ на ваш вопрос о NAT очень похож, только все делается в большем масштабе.
Маршрутизатор, выполняющий NAT, хранит таблицу "state", содержащую как внутренние, так и внешние адреса и порты. Например, если ваши два HTTP-запроса использовали отдельные TCP-соединения, они могут отслеживаться как:
PROTO ORIG-SRC ORIG-DST REPLY-SRC REPLY-DST
6/tcp 192.168.6.42:52909 yahoo.server:80 yahoo.server:80 your.public.ip.addr:52909
6/tcp 192.168.6.175:39163 yahoo.server:80 yahoo.server:80 your.public.ip.addr:39163
6/tcp 192.168.6.175:52909 yahoo.server:80 yahoo.server:80 your.public.ip.addr:28330
17/udp 192.168.6.175:4984 8.8.8.8:53 8.8.8.8:53 your.public.ip.addr:4984
Когда маршрутизатор получает пакет от REPLY-SRC (Yahoo), адресованный REPLY-DST (ваш публичный IP-адрес), он знает, чтонастоящийДля отмены NAT необходимо взять пункт назначения из столбца ORIG-SRC.
(Если совпадающего состояния нет, то обрабатываются вручную настроенные правила переадресации портов. Если по-прежнему нет ни одного соответствия, то пакет на самом деле предназначался для самого маршрутизатора.)
Обратите внимание, что таблица состояний содержитадресаипорты, что позволяет различать несколько подключений к одному и тому же серверу по комбинации портов. В моем примере два компьютера случайно использовали одну и ту же комбинацию портов, поэтому порты второго подключения также были переведены.
(На самом деле, некоторые NAT выглядяттолько(На порту и полностью игнорируйте исходный адрес; это уменьшает количество возможных подключений, но значительно упрощает для одноранговых программ выполнение «пробивания дыр NAT».)
Такое состояние сохраняется даже для протоколов без установления соединения, таких как UDP или ICMP, поэтому записи устаревают после некоторого интервала бездействия, даже если нет явного пакета «закрытия соединения». (Таблица состояний на самом деле является частью брандмауэра, поэтому даже если NAT не выполняется, маршрутизатор все равно может использовать ее для различения «активных» соединений и случайных пакетов.)
(Если ваш маршрутизатор работает на базе Linux, conntrack -L
или cat /proc/net/nf_conntrack
отобразит эту таблицу. Для OpenBSD или pfSense попробуйте pfctl -s state
.)