Як визначаються порти джерела та як змусити його використовувати певний порт


26

Коли я підключаюсь до https://www.google.co.uk, ці зміни змінюються на 216.58.198.228:1043. Тоді відкриється з'єднання зі мною [My IP Address]: 63998.

Моє запитання полягає в тому, як обирається порт 63998 і чи є спосіб примусити його бути 63999.


9
чи є спосіб змусити це бути 63999 Чи є у вас якісь причини для цього?
AL

1
Якщо ви пишете заявку, ви можете відкрити будь-який (невикористаний) вихідний порт, який потрібно. Але це не гарна ідея і не зрозуміло, чому ви цього хочете?
pjc50

6
@ pjc50 Дійсно, це питання здається, що у нього може бути проблема XY .
Дев

1
Я подав редагування, щоб змінити назву, щоб сказати "джерело", а не "локальне", оскільки номери портів призначення "локальні" для машини призначення, але джерело початкового пакета TCP SYN недвозначно, як ініціатор з'єднання.
Monty Harder

Відповіді:


39

Як визначаються місцеві порти

Номер порту вибирається програмним забезпеченням для реалізації TCP з діапазону номерів портів під назвою Ephemeral Ports .

Точний механізм вибору номера порту та діапазону, який буде використовуватися, залежить від операційної системи.


Чи є спосіб примусити його бути 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 бази знань Microsoft . Ця ж стаття також показує, як можна змінити діапазон за бажанням, але діапазон за замовчуванням зараз достатній для більшості серверів.

Джерело Зміна діапазону ефемерних портів

Ви можете переглянути динамічний діапазон портів на комп'ютері, на якому працює комп'ютер під керуванням 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 для діапазону ефемерних портів. На жаль, здається, що ви можете встановити лише верхню межу діапазону ефемерних портів. Ось інформація, витягнута зі статті знань Майкрософт 196271 :

  • Запустіть редактор реєстру ( Regedt32.exe).
  • Знайдіть у реєстрі такий ключ:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • У меню "Редагувати" натисніть "Додати значення", а потім додайте таке значення реєстру:

    Значення Назва: MaxUserPortТип даних: REG_DWORDЗначення: 65534(наприклад)

    Дійсний діапазон: 5000-65534(десяткові) За замовчуванням: 0x1388(5000 десятків)

    Опис: Цей параметр контролює максимальний номер порту, який використовується, коли програма вимагає від системи будь-якого доступного порту користувача. Зазвичай ефемерні (тобто нетривалі) порти розподіляються між значеннями 1024та 5000включно.

  • Вийдіть з редактора реєстру.

Примітка. Є ще одна відповідна стаття KB ( 812873 ), яка стверджує, що дозволяє встановити діапазон виключення, що може означати, що ви можете виключити порти 1024-9999(наприклад), щоб діапазон ефемерних портів був 10000-65534. Однак нам не вдалося змусити це працювати (станом на жовтень 2004 р.).

Джерело Зміна діапазону ефемерних портів


1
Принаймні, Windows виглядає так, що можливо обмежити систему діапазону портів у широкому масштабі. У більшості випадків це, мабуть, погана ідея, особливо обмеженням цього одного порту було б: Дивіться KB 929851 , перераховані команди принаймні працюють у Windows 7.
Сет

@Seth Так. Я неохоче згадував це, оскільки ОП не згадував про його ОС, і я не хотів розгортати відповідь на N операційних систем ...
DavidPostill

Ви маєте рацію з цього приводу. Адже є безліч операційних систем. Це просто те, на що я натрапив, спочатку намагаючись відповісти на це питання. Оскільки ваша відповідь була швидшою, я просто подумав, що додам її. Це дійсно добре написана відповідь! :) Просто додав це як натяк на те, що іноді зміна конфігурації є достатньою, а не перепрограмуванням (можливо, моє розуміння просто інше - для мене це звучить схоже на перекомпіляцію).
Сет

1
Насправді в Linux теж дуже просто: просто зробіть відлуння "49152 65535"> / proc / sys / net / ipv4 / ip_local_port_range . Це настільки просто, що це можна робити за командою .
MariusMatutiae

2
Замість того, щоб змінювати діапазон ефемерних портів, було б набагато краще, щоб програма викликала bindсистемний виклик перед тим, як викликати connect. У деяких додатках є можливість зробити це, в інших - немає.
kasperd

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, саме тому я відновив початковий діапазон якнайшвидше.

Таким чином, якби операційна система ОП була Linux, відповідь мала б, що це можна було легко зробити.

Дивно, але це не так просто на BSD, деякі з яких навіть не мають налаштування ядра часу виконання для EPR. MacOS X, FreeBSD і OpenBSD вимагають змінити файл /etc/sysctl.conf , але вони мають різні варіанти для EPR.

Незалежно від того, вище , і ОС, той факт , що що - то може бути зроблено , не означає , що має бути зроблено: чому на Землі вам це потрібно? Я не можу придумати жодного випадку використання.


Для прикладу Linux +1.
DavidPostill

Хе-хе. BSD / OS вимагає перекомпіляції ядра :)
DavidPostill

1
@DavidPostill Це головний облом.
MariusMatutiae

У вашому прикладі коду є недолік. Ваш тип акторської ролі дуже непомітний. Крім того, було б непогано зробити BIND_PORTнеобов'язковим такий, що код все-таки можна використовувати точно так само, як оригінал. Я думаю htons(bind_port_env ? atoi(bind_port_env) : 0), зробив би правильно.
kasperd

1

Варто додати, що ядро ​​Linux також є

net.ipv4.ip_local_reserved_ports

ручка, яка робить дещо навпаки, але, тим не менш, вона може бути дуже корисною, оскільки таким чином ви можете "пробити дірку" для служб, які відкривають конкретні порти в інакше ефемерному діапазоні портів.

Короткий уривок із документів :

Вкажіть порти, які зарезервовані для відомих сторонніх додатків. Ці порти не використовуватимуться для автоматичного призначення портів (наприклад, при виклику connect () або bind () з номером порту 0). Явна поведінка розподілу портів не змінюється.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.