Как определяются исходные порты и как я могу заставить его использовать определенный порт

26

Когда я подключаюсь к https://www.google.co.uk, это меняется на 216.58.198.228:443. Затем соединение со мной открывается на [Мой IP-адрес]: 63998.

Мой вопрос: как выбрать порт 63998 и есть ли способ заставить его быть 63999.

TheGathron
источник
9
Есть ли способ заставить его быть 63999 Есть ли у вас какие-либо причины для попытки сделать это?
AL
1
Если вы пишете приложение, вы можете открыть любой (неиспользуемый) порт источника, который вам нужен. Но это не очень хорошая идея и непонятно, зачем ты этого хочешь?
pjc50
6
@ pjc50 Действительно, кажется, что этот вопрос может иметь проблему с XY .
Дев
1
Я отправил правку, чтобы изменить заголовок на «исходный», а не «локальный», так как номера портов назначения являются «локальными» для машины назначения, но источником исходного пакета TCP SYN однозначно является источник инициатора связь
Монти Хардер

Ответы:

39

Как определяются локальные порты

Номер порта выбирается программным обеспечением реализации TCP из диапазона номеров портов, называемых эфемерными портами .

Точный механизм выбора номера порта и используемого диапазона зависит от операционной системы.


Есть ли способ заставить его быть 63999.

Это можно сделать, изменив конфигурацию программного обеспечения реализации TCP.

Инструкции по настройке диапазона эфемерных портов для различных операционных систем можно найти в разделе Изменение диапазона эфемерных портов .

  • Инструкции для Linux и Windows включены в этот ответ ниже для справки.

Однако не стоит ограничивать диапазон, например, одним портом 63999.

  • На самом деле в Windows это невозможно, так как:

    Минимальный диапазон портов, который можно установить, составляет 255.


Эфемерный Порт Порт

Соединение TCP / IPv4 состоит из двух конечных точек, и каждая конечная точка состоит из IP-адреса и номера порта. Поэтому, когда пользователь клиента подключается к компьютеру-серверу, установленное соединение может рассматриваться как набор из 4 (IP-адрес сервера, порт сервера, IP-адрес клиента, клиентский порт).

Обычно три из четырех общеизвестны - клиентский компьютер использует свой собственный IP-адрес, и при подключении к удаленному сервису требуются IP-адрес серверного компьютера и номер порта сервиса.

Что не сразу видно, так это то, что когда соединение установлено, клиентская сторона соединения использует номер порта. Если клиентская программа явно не запрашивает конкретный номер порта, используемый номер порта является эфемерным номером порта.

Эфемерные порты - это временные порты, назначаемые IP-стеком машины, и назначаются для этого назначенным диапазоном портов. Когда соединение завершается, эфемерный порт доступен для повторного использования, хотя большинство IP-стеков не будет повторно использовать этот номер порта, пока не будет использован весь пул эфемерных портов.

Таким образом, если клиентская программа переподключается, ей будет назначен другой временный номер порта для ее стороны нового соединения.

Источник Эфемерный Порт Порт


Изменение диапазона эфемерного порта

Linux:

Linux позволяет просматривать и изменять диапазон временных портов, просто используя файл /proc/sys/net/ipv4/ip_local_port_range. Например, здесь показана конфигурация по умолчанию в системе с ядром 2.2:

$ cat /proc/sys/net/ipv4/ip_local_port_range 
1024 4999

Чтобы изменить это на предпочтительный диапазон, вы можете сделать (как суперпользователь):

# echo "49152 65535" > /proc/sys/net/ipv4/ip_local_port_range 

Обратите внимание, что вам придется делать это каждый раз при загрузке системы, поэтому обязательно добавьте строку в скрипт запуска системы, например, /etc/rc.local чтобы всегда использовался ваш диапазон.

Также обратите внимание, что ядро ​​Linux 2.4 будет иметь диапазон по умолчанию от 32768 до 61000, если доступно достаточное количество памяти ядра, поэтому изменение диапазона может не потребоваться в новых системах Linux.

Наконец, также обратите внимание, что вы можете использовать sysctlинтерфейс для изменения настроек, а не использовать /procфайловую систему. Имя sysctlпараметра - «net.ipv4.ip_local_port_range». Отредактируйте /etc/sysctl.confфайл, если он у вас есть, или запустите скрипт запуска, запустите sysctlкоманду вручную, если вы хотите изменить этот параметр, используя sysctl.

Windows Vista / Windows Server 2008 и новее:

В Windows Vista и Windows Server 2008 в настоящее время Windows использует большой диапазон (49152-65535) по умолчанию, в соответствии со статьей 929851 базы знаний Майкрософт . В той же статье также показано, как вы можете изменить диапазон при желании, но диапазон по умолчанию теперь достаточен для большинства серверов.

Источник Изменение диапазона эфемерных портов

Вы можете просмотреть динамический диапазон портов на компьютере под управлением Windows Vista или Windows Server 2008, используя следующие netshкоманды:

netsh int ipv4 show dynamicport tcp
netsh int ipv4 show dynamicport udp
netsh int ipv6 show dynamicport tcp
netsh int ipv6 show dynamicport udp 

Заметки:

  • Диапазон устанавливается отдельно для каждого транспорта и для каждой версии IP.
  • Диапазон портов теперь действительно является диапазоном с начальной точкой и конечной точкой.
  • У клиентов Microsoft, которые развертывают серверы под управлением Windows Server 2008, могут возникнуть проблемы с RPC-связью между серверами, если во внутренней сети используются брандмауэры.
  • В этих случаях мы рекомендуем вам переконфигурировать межсетевые экраны , чтобы трафик между серверами в пределах динамического порта 49152 через 65535.
  • Этот диапазон дополняет известные порты, которые используются службами и приложениями.
  • Или диапазон портов, используемый серверами, можно изменить на каждом сервере.

Вы настраиваете этот диапазон с помощью netshкоманды следующим образом:

netsh int <ipv4|ipv6> set dynamic <tcp|udp> start=number num=range

Эта команда устанавливает динамический диапазон портов для TCP. Начальный порт - это номер, а общее количество портов - это диапазон. Ниже приведены примеры команд:

netsh int ipv4 set dynamicport tcp start=10000 num=1000
netsh int ipv4 set dynamicport udp start=10000 num=1000
netsh int ipv6 set dynamicport tcp start=10000 num=1000
netsh int ipv6 set dynamicport udp start=10000 num=1000

Эти примеры команд устанавливают динамический диапазон портов, начиная с порта 10000 и заканчивая портом 10999(1000 портов).

Заметки:

  • Минимальный диапазон портов , которые могут быть установлены вне 255.
  • Минимальный стартовый порт , который может быть установлен в 1025.
  • Максимальный конечный порт (в зависимости от настраиваемого диапазона) не может превышать 65535.
  • Чтобы продублировать поведение по умолчанию в Windows Server 2003, используйте 1025в качестве начального порта, а затем используйте 3976в качестве диапазона для TCP и UDP. Это приводит к начальному порту 1025и конечному порту 5000.

Источник Статья 929851 базы знаний Майкрософт :

Windows XP и старше:

В более старых операционных системах Windows (Windows XP и более ранних) Windows использует традиционный диапазон BSD от 1024 до 4999 для своего эфемерного диапазона портов. К сожалению, похоже, что вы можете установить только верхнюю границу диапазона эфемерного порта. Вот информация, взятая из статьи базы знаний Microsoft 196271 :

  • Запустите редактор реестра ( Regedt32.exe).
  • Найдите следующий ключ в реестре:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • В меню «Редактировать» нажмите «Добавить значение», а затем добавьте следующее значение реестра:

    Имя значения: MaxUserPortТип данных: REG_DWORDЗначение: 65534(например)

    Допустимый диапазон: 5000-65534(десятичный) По умолчанию: 0x1388(5000 десятичный)

    Описание: Этот параметр управляет максимальным номером порта, используемым, когда приложение запрашивает любой доступный пользовательский порт из системы. Обычно эфемерные (то есть недолговечные) порты распределяются между значениями 1024и 5000включительно.

  • Закройте редактор реестра.

Примечание. Существует другая соответствующая статья базы знаний ( 812873 ), в которой утверждается, что вы можете установить диапазон исключения, что может означать, что вы можете исключить порты 1024-9999(например), чтобы иметь диапазон эфемерного порта 10000-65534. Однако мы не смогли заставить это работать (по состоянию на октябрь 2004 года).

Источник Изменение диапазона эфемерных портов

ДэвидПостилл
источник
1
По крайней мере, Windows, кажется, можно ограничить диапазон портов системы. В большинстве случаев это, вероятно, плохая идея, особенно если ограничить ее одним портом: см. KB 929851 , команды, перечисленные по крайней мере, работают в Windows 7.
Сет
@ Сидит Да. Я не хотел упоминать об этом, поскольку ОП не упомянул свою ОС, и я не хотел расширять ответ, чтобы охватить N операционных систем ...
DavidPostill
Вы правы в этом. Ведь существует множество операционных систем. Я просто наткнулся на это, пытаясь ответить на этот вопрос. Поскольку ваш ответ был быстрее, я просто подумал добавить его. Это действительно хорошо написанный ответ! :) Просто добавил, что намек на то, что иногда достаточно изменить конфигурацию, а не перепрограммировать (возможно, мое понимание просто другое - для меня это звучит как перекомпиляция).
Сет
1
На самом деле, в Linux это тоже очень просто: просто сделайте echo "49152 65535"> / proc / sys / net / ipv4 / ip_local_port_range . Это так просто, что это можно сделать для каждой команды .
MariusMatutiae
2
Вместо того, чтобы изменять диапазон временных портов, было бы намного лучше, чтобы приложение вызывало bindсистемный вызов перед вызовом connect. Некоторые приложения имеют возможность сделать это, другие приложения нет.
Касперд
9

Ответ Дэвида Постила совершенно верный. Я хотел бы просто добавить к этому, подчеркивая, что изменить диапазон временных портов в Linux настолько просто, что у ОП есть утвердительный ответ.

Вы меняете EPR следующим образом:

echo "40000 60000" > /proc/sys/net/ipv4/ip_local_port_range 

и вы можете выбрать порт 50000 (в качестве примера) с помощью следующего скрипта:

OLD_RANGE=$(cat /proc/sys/net/ipv4/ip_local_port_range)
MY_PORT=50000
echo "$MY_PORT $MY_PORT" > /proc/sys/net/ipv4/ip_local_port_range
sudo -u SomeUser SomeApplication  & 
echo $OLD_RANGE" > /proc/sys/net/ipv4/ip_local_port_range 

Одно предостережение: поскольку в диапазоне есть один порт, другое приложение может отхватить его от вас между выполнением третьей и четвертой строк выше; Кроме того, даже если нет условий гонки, вы будете парализовать все остальные приложения, пока не восстановите большой EPR, поэтому я восстановил исходный диапазон как можно скорее.

Таким образом, если бы операционная система OP была Linux, ответ был бы таков: это легко сделать.

Удивительно, но это не так просто на BSD, некоторые из которых даже не имеют настройки ядра времени выполнения для EPR. MacOS X, FreeBSD и OpenBSD требуют изменения файла /etc/sysctl.conf , но у них есть разные варианты для EPR.

Независимо от вышесказанного и ОС, тот факт, что что-то может быть сделано, не означает, что это должно быть сделано: зачем, черт возьми, это нужно? Я не могу думать об одном случае использования.

MariusMatutiae
источник
Для Linux пример +1.
ДэвидПостилл
Хехе. BSD / OS требует перекомпиляции ядра :)
DavidPostill
1
@DavidPostill Это большой облом.
MariusMatutiae
В вашем примере кода есть недостаток. Ваш тип актерского состава очень неуместен. Кроме того, было бы неплохо сделать BIND_PORTнеобязательным, чтобы код по-прежнему можно было использовать точно так же, как и оригинал. Я думаю, htons(bind_port_env ? atoi(bind_port_env) : 0)что сделал бы правильную вещь.
Касперд
1

Стоит добавить, что ядро ​​Linux также имеет

net.ipv4.ip_local_reserved_ports

ручка, которая работает несколько наоборот, но тем не менее это может быть очень полезно, потому что таким образом вы можете «пробить дыру» для сервисов, которые открывают определенные порты в других эфемерных диапазонах портов.

Краткая выдержка из документов :

Укажите порты, которые зарезервированы для известных сторонних приложений. Эти порты не будут использоваться для автоматического назначения портов (например, при вызове connect () или bind () с номером порта 0). Явное поведение при распределении портов не изменяется.

Формат, используемый для ввода и вывода, представляет собой список диапазонов через запятую (например, «1,2-4,10-10» для портов 1, 2, 3, 4 и 10). Запись в файл очистит все ранее зарезервированные порты и обновит текущий список тем, который указан во входных данных.

poige
источник