Wie werden Quellports ermittelt und wie kann ich die Verwendung eines bestimmten Ports erzwingen?

26

Wenn ich eine Verbindung zu https://www.google.co.uk herstelle, ändert sich dies zu 216.58.198.228:443. Dann öffnet sich eine Verbindung zu mir unter [Meine IP-Adresse]: 63998.

Meine Frage ist, wie 63998 Port gewählt wird und gibt es eine Möglichkeit, ihn zu 63999 zu zwingen.

TheGathron
quelle
9
Gibt es eine Möglichkeit, 63999 zu erzwingen? Haben Sie einen Grund, dies zu versuchen?
AL
1
Wenn Sie eine Anwendung schreiben, können Sie einen beliebigen (nicht verwendeten) Quellport öffnen. Aber es ist keine gute Idee und nicht klar, warum Sie das wollen?
PJC50
6
@ pjc50 In der Tat scheint diese Frage ein XY-Problem zu haben .
Dev
1
Ich habe eine Bearbeitung eingereicht, um den Titel so zu ändern, dass er "source" statt "local" lautet, da die Zielportnummern für den Zielcomputer "local" sind, aber die Quelle des anfänglichen TCP-SYN-Pakets eindeutig die des Initiators von Die Verbindung
Monty Harder

Antworten:

39

Wie werden lokale Ports bestimmt?

Die Portnummer wird von der TCP-Implementierungssoftware aus einem Bereich von Portnummern ausgewählt, die als Ephemere Ports bezeichnet werden .

Der genaue Mechanismus zur Auswahl der Portnummer und des zu verwendenden Bereichs hängt vom Betriebssystem ab.


Gibt es eine Möglichkeit, 63999 zu erzwingen?

Dies kann durch Ändern der Konfiguration der TCP-Implementierungssoftware erfolgen.

Anweisungen zum Konfigurieren des Bereichs für kurzlebige Ports für eine Vielzahl verschiedener Betriebssysteme finden Sie unter Ändern des Bereichs für kurzlebige Ports .

  • Anweisungen für Linux und Windows finden Sie in dieser Antwort.

Es ist jedoch keine gute Idee, den Bereich beispielsweise auf einen einzelnen Port zu beschränken 63999.

  • Tatsächlich ist dies unter Windows nicht möglich, da:

    Es können mindestens 255 Ports eingestellt werden.


Die kurzlebige Port Range

Eine TCP / IPv4-Verbindung besteht aus zwei Endpunkten, und jeder Endpunkt besteht aus einer IP-Adresse und einer Portnummer. Wenn ein Client-Benutzer eine Verbindung zu einem Server-Computer herstellt, kann eine hergestellte Verbindung daher als 4-Tupel von (Server-IP, Server-Port, Client-IP, Client-Port) betrachtet werden.

In der Regel sind drei der vier bekannt - der Client-Computer verwendet seine eigene IP-Adresse, und beim Herstellen einer Verbindung zu einem Remotedienst sind die IP-Adresse und die Service-Portnummer des Server-Computers erforderlich.

Was nicht sofort ersichtlich ist, ist, dass beim Herstellen einer Verbindung die Clientseite der Verbindung eine Portnummer verwendet. Sofern ein Client-Programm nicht ausdrücklich eine bestimmte Portnummer anfordert, handelt es sich bei der verwendeten Portnummer um eine kurzlebige Portnummer.

Temporäre Ports sind temporäre Ports, die vom IP-Stack eines Computers zugewiesen werden und für diesen Zweck aus einem festgelegten Bereich von Ports zugewiesen werden. Wenn die Verbindung getrennt wird, kann der kurzlebige Port erneut verwendet werden, obwohl die meisten IP-Stacks diese Portnummer erst wieder verwenden, wenn der gesamte Pool kurzlebiger Ports verwendet wurde.

Wenn sich das Client-Programm erneut verbindet, wird ihm für seine Seite der neuen Verbindung eine andere temporäre Portnummer zugewiesen.

Quelle Die kurzlebige Port Range


Ändern des kurzlebigen Anschlussbereichs

Linux:

Mit Linux können Sie den kurzlebigen Portbereich anzeigen und ändern, indem Sie einfach die Datei verwenden /proc/sys/net/ipv4/ip_local_port_range. Dies zeigt zum Beispiel die Standardkonfiguration auf einem Kernel 2.2-System:

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

Um dies auf den bevorzugten Bereich zu ändern, können Sie (als Superuser) Folgendes tun:

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

Beachten Sie, dass Sie dies jedes Mal tun müssen, wenn das System hochfährt. Fügen Sie daher dem Startskript des Systems eine Zeile hinzu, /etc/rc.local sodass Ihr Bereich immer verwendet wird.

Beachten Sie auch, dass der Linux 2.4-Kernel standardmäßig den Bereich von 32768 bis 61000 verwendet, wenn ausreichend Kernel-Speicher verfügbar ist, sodass eine Änderung des Bereichs auf neueren Linux-Systemen möglicherweise nicht erforderlich ist.

Beachten Sie außerdem, dass Sie möglicherweise die sysctlBenutzeroberfläche verwenden können, um die Einstellungen zu ändern, anstatt das /procDateisystem zu verwenden. Der Name des sysctlParameters lautet "net.ipv4.ip_local_port_range". Bearbeiten Sie die /etc/sysctl.confDatei, wenn Sie sie haben, oder lassen Sie den sysctlBefehl von einem Startskript manuell ausführen, wenn Sie diesen Parameter mit ändern möchten sysctl.

Windows Vista / Windows Server 2008 und neuer:

Ab Windows Vista und Windows Server 2008 verwendet Windows laut Microsoft Knowledgebase-Artikel 929851 standardmäßig einen großen Bereich (49152-65535) . In demselben Artikel wird auch beschrieben, wie Sie den Bereich bei Bedarf ändern können. Der Standardbereich ist jedoch für die meisten Server jetzt ausreichend.

Quelle Ändern des kurzlebigen Portbereichs

Mit den folgenden netshBefehlen können Sie den dynamischen Portbereich auf einem Computer anzeigen, auf dem Windows Vista oder Windows Server 2008 ausgeführt wird :

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

Anmerkungen:

  • Der Bereich wird für jeden Transport und für jede IP-Version separat festgelegt.
  • Der Portbereich ist nun wirklich ein Bereich mit einem Startpunkt und einem Endpunkt.
  • Microsoft-Kunden, die Server mit Windows Server 2008 bereitstellen, haben möglicherweise Probleme mit der RPC-Kommunikation zwischen Servern, wenn im internen Netzwerk Firewalls verwendet werden.
  • In diesen Fällen wird empfohlen, die Firewalls so zu konfigurieren, dass der Datenverkehr zwischen den Servern im dynamischen Portbereich von 49152 bis möglich ist 65535.
  • Dieser Bereich gilt zusätzlich zu bekannten Ports, die von Diensten und Anwendungen verwendet werden.
  • Oder der von den Servern verwendete Portbereich kann auf jedem Server geändert werden.

Sie passen diesen Bereich mit dem netshBefehl wie folgt an:

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

Dieser Befehl legt den dynamischen Portbereich für TCP fest. Der Startport ist die Nummer und die Gesamtzahl der Ports ist der Bereich. Folgendes sind Beispielbefehle:

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

Mit diesen Beispielbefehlen wird der dynamische Portbereich so festgelegt, dass er an Port 10000 beginnt und an Port 10999(1000 Ports) endet .

Anmerkungen:

  • Der minimale Bereich von Ports, die eingestellt werden können, ist 255.
  • Der minimale Startport, der eingestellt werden kann, ist 1025.
  • Der maximale Endport (basierend auf dem zu konfigurierenden Bereich) kann nicht überschritten werden 65535.
  • Verwenden Sie 1025als den Startport und dann 3976als den Bereich für TCP und UDP , um das Standardverhalten von Windows Server 2003 zu duplizieren . Dies ergibt einen Startport von 1025und einen Endport von 5000.

Quell-Microsoft Knowledgebase-Artikel 929851 :

Windows XP und älter:

Für ältere Windows-Betriebssysteme (Windows XP und älter) verwendet Windows den traditionellen BSD-Bereich von 1024 bis 4999 für seinen kurzlebigen Portbereich. Leider scheint es, dass Sie nur die Obergrenze des kurzlebigen Portbereichs festlegen können. Hier sind Informationen aus dem Microsoft Knowledgebase-Artikel 196271 :

  • Starten Sie den Registrierungseditor ( Regedt32.exe).
  • Suchen Sie den folgenden Schlüssel in der Registrierung:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • Klicken Sie im Menü "Bearbeiten" auf "Wert hinzufügen", und fügen Sie den folgenden Registrierungswert hinzu:

    Wertname: MaxUserPortDatentyp: REG_DWORDWert: 65534(zum Beispiel)

    Gültiger Bereich: 5000-65534(dezimal) Standard: 0x1388(5000 dezimal)

    Beschreibung: Dieser Parameter steuert die maximale Portnummer, die verwendet wird, wenn eine Anwendung einen verfügbaren Benutzerport vom System anfordert. Normalerweise werden kurzlebige Ports zwischen den Werten von 1024und 5000einschließlich zugewiesen .

  • Beenden Sie den Registrierungseditor.

Hinweis: Es gibt einen anderen relevanten KB-Artikel ( 812873 ), der angibt , dass Sie einen Ausschlussbereich festlegen können. Dies kann 1024-9999beispielsweise bedeuten, dass Sie Ports ausschließen können , um den kurzlebigen Portbereich zu erhalten 10000-65534. Es ist uns jedoch nicht gelungen, dies zum Laufen zu bringen (Stand Oktober 2004).

Quelle Ändern des kurzlebigen Portbereichs

DavidPostill
quelle
1
Zumindest für Windows scheint es möglich zu sein, den Portbereich systemweit einzuschränken. In den meisten Fällen ist dies wahrscheinlich eine schlechte Idee, insbesondere wenn die Beschränkung auf einen Port erfolgt: Siehe KB 929851 , die aufgeführten Befehle funktionieren mindestens unter Windows 7.
Seth
@Seth Ja. Ich wollte das nur ungern erwähnen, da das OP sein Betriebssystem nicht erwähnte und ich die Antwort nicht auf N Betriebssysteme ausweiten wollte ...
DavidPostill
Da hast du recht. Immerhin gibt es viele Betriebssysteme. Es ist nur etwas, worüber ich gestolpert bin, als ich ursprünglich versucht habe, diese Frage zu beantworten. Da Ihre Antwort schneller war, dachte ich nur, ich würde es hinzufügen. Es ist eine wirklich gut geschriebene Antwort! :) Fügte es nur als Hinweis hinzu, dass manchmal das Ändern der Konfiguration ausreicht, anstatt sie neu zu programmieren (vielleicht verstehe ich das nur anders - für mich klingt das ähnlich wie Neukompilieren).
Seth
1
Tatsächlich ist es auch unter Linux sehr einfach: Geben Sie einfach "49152 65535"> / proc / sys / net / ipv4 / ip_local_port_range ein . Es ist so einfach, dass es auf Befehlsbasis ausgeführt werden kann.
MariusMatutiae
2
Anstatt den kurzlebigen Portbereich zu ändern, ist es viel besser, wenn die Anwendung den bindSystemaufruf aufruft, bevor er aufruft connect. Einige Anwendungen haben die Möglichkeit, dies zu tun, andere nicht.
Kasperd
9

Die Antwort von David Postill ist vollkommen richtig. Ich möchte nur hinzufügen, indem ich betone, dass das Ändern des kurzlebigen Portbereichs unter Linux so einfach ist, dass das OP eine positive Antwort hat.

Sie ändern den EPR wie folgt:

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

und Sie können Port 50000 (als Beispiel) mit dem folgenden Skript auswählen:

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 

Eine Einschränkung hier: Da es einen einzelnen Port in dem Bereich gibt, könnte eine andere Anwendung ihn zwischen der Ausführung der dritten und der vierten Zeile oben von Ihnen wegreißen. Auch wenn keine Racebedingung vorliegt, werden Sie alle anderen Anwendungen lahmlegen, bis Sie einen großen EPR wiederherstellen. Aus diesem Grund habe ich den ursprünglichen Bereich so schnell wie möglich wiederhergestellt.

So , wenn das Betriebssystem OPs hatte Linux gewesen, wäre die Antwort gewesen , dass es leicht getan werden könnte.

Erstaunlicherweise ist dies nicht so einfach für BSDs, von denen einige nicht einmal eine Laufzeit-Kernel-Einstellung für den EPR haben. Für MacOS X, FreeBSD und OpenBSD muss die Datei /etc/sysctl.conf geändert werden , für den EPR stehen jedoch unterschiedliche Optionen zur Verfügung.

Unabhängig von der von oben und von der OS, die Tatsache , dass etwas kann getan werden , bedeutet nicht , es sollte getan werden: warum auf der Erde brauchen Sie das? Mir fällt kein einziger Anwendungsfall ein.

MariusMatutiae
quelle
Für Linux Beispiel +1.
DavidPostill
Hehe BSD / OS erfordert das Neukompilieren des Kernels :)
DavidPostill
1
@ DavidPostill Das ist eine große Enttäuschung.
MariusMatutiae
In Ihrem Codebeispiel liegt ein Fehler vor. Ihr Typ Cast ist sehr verlegt. Zusätzlich wäre es eine gute Idee, BIND_PORToptional zu machen , so dass der Code immer noch genauso wie das Original verwendet werden kann. Ich denke, ich htons(bind_port_env ? atoi(bind_port_env) : 0)würde das Richtige tun.
Kasperd
1

Es lohnt sich hinzuzufügen, dass der Linux-Kernel auch hat

net.ipv4.ip_local_reserved_ports

Knopf, der etwas entgegengesetzt funktioniert, aber dennoch sehr nützlich sein kann, da Sie auf diese Weise ein Loch für Dienste schlagen können, die bestimmte Ports in einem ansonsten kurzlebigen Bereich von Ports öffnen.

Kurzer Auszug aus den Dokumenten :

Geben Sie die Ports an, die für bekannte Anwendungen von Drittanbietern reserviert sind. Diese Ports werden nicht von automatischen Portzuweisungen verwendet (z. B. beim Aufrufen von connect () oder bind () mit Portnummer 0). Das explizite Portzuweisungsverhalten bleibt unverändert.

Das Format, das sowohl für die Eingabe als auch für die Ausgabe verwendet wird, ist eine durch Kommas getrennte Liste von Bereichen (z. B. "1,2-4,10-10" für die Ports 1, 2, 3, 4 und 10). Durch das Schreiben in die Datei werden alle zuvor reservierten Ports gelöscht und die aktuelle Liste mit der in der Eingabe angegebenen Liste aktualisiert.

Poige
quelle