Come vengono determinate le porte di origine e come posso forzare a utilizzare una porta specifica


26

Quando mi collego a https://www.google.co.uk, questo cambia in 216.58.198.228:443. Quindi una connessione a me si apre su [Il mio indirizzo IP]: 63998.

La mia domanda è: come viene scelta la porta 63998 e c'è un modo per forzarla a 63999.


9
c'è un modo per costringerlo a essere 63999 Hai qualche motivo per provare a farlo?
AL

1
Se stai scrivendo un'applicazione, puoi aprire qualsiasi porta di origine (non utilizzata) che desideri. Ma non è una buona idea e non è chiaro perché lo desideri?
pjc50,

6
@ pjc50 In effetti, questa domanda sembra avere un problema XY .
Dev

1
Ho inviato una modifica per cambiare il titolo in modo da dire "origine" anziché "locale", poiché i numeri delle porte di destinazione sono "locali" per la macchina di destinazione, ma l'origine del pacchetto TCP SYN iniziale è inequivocabilmente quella dell'iniziatore di la connessione
Monty Harder,

Risposte:


39

Come vengono determinate le porte locali

Il numero di porta viene scelto dal software di implementazione TCP da un intervallo di numeri di porta chiamati Porte effimere .

L'esatto meccanismo per la scelta del numero di porta e dell'intervallo da utilizzare dipende dal sistema operativo.


C'è un modo per costringerlo a essere 63999.

Questo può essere fatto modificando la configurazione del software di implementazione TCP.

Le istruzioni per la configurazione della gamma di porte effimere per una varietà di diversi sistemi operativi sono disponibili in Modifica della gamma di porte effimere .

  • Le istruzioni per Linux e Windows sono incluse in questa risposta come riferimento.

Tuttavia, non è una buona idea limitare l'intervallo a una singola porta, ad esempio 63999.

  • In effetti su Windows ciò non è possibile in quanto:

    L'intervallo minimo di porte che è possibile impostare è 255.


La gamma di porte effimere

Una connessione TCP / IPv4 è composta da due endpoint e ciascun endpoint è costituito da un indirizzo IP e un numero di porta. Pertanto, quando un utente client si connette a un computer server, una connessione stabilita può essere considerata come la 4 tupla di (IP server, porta server, IP client, porta client).

Solitamente tre dei quattro sono prontamente noti: la macchina client utilizza il proprio indirizzo IP e quando si collega a un servizio remoto, sono richiesti l'indirizzo IP e la porta del servizio della macchina server.

Ciò che non è immediatamente evidente è che quando viene stabilita una connessione che il lato client della connessione utilizza un numero di porta. A meno che un programma client non richieda esplicitamente un numero di porta specifico, il numero di porta utilizzato è un numero di porta temporaneo.

Le porte temporanee sono porte temporanee assegnate dallo stack IP di una macchina e vengono assegnate da un intervallo designato di porte a tale scopo. Al termine della connessione, la porta temporanea è disponibile per il riutilizzo, sebbene la maggior parte degli stack IP non riutilizzerà quel numero di porta fino a quando non sarà stato utilizzato l'intero pool di porte temporanee.

Quindi, se il programma client si riconnette, gli verrà assegnato un numero di porta temporaneo diverso per il suo lato della nuova connessione.

Fonte La portata effimera della porta


Modifica dell'intervallo di porte effimere

Linux:

Linux ti consente di visualizzare e modificare l'intervallo di porte temporanee semplicemente usando il file /proc/sys/net/ipv4/ip_local_port_range. Ad esempio, questo mostra la configurazione predefinita su un sistema kernel 2.2:

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

Per cambiarlo nell'intervallo preferito, potresti fare (come superutente):

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

Nota che dovrai farlo ogni volta che il sistema si avvia, quindi assicurati di aggiungere una linea a uno script di avvio del sistema in /etc/rc.local modo tale che il tuo intervallo sia sempre usato.

Si noti inoltre che il kernel Linux 2.4 imposterà automaticamente l'intervallo compreso tra 32768 e 61000 se è disponibile una memoria del kernel adeguata, quindi la modifica dell'intervallo potrebbe non essere necessaria sui sistemi Linux più recenti.

Infine, tieni presente che potresti essere in grado di utilizzare l' sysctlinterfaccia per modificare le impostazioni anziché utilizzare il /procfilesystem. Il nome del sysctlparametro è "net.ipv4.ip_local_port_range". Modificare il /etc/sysctl.conffile, se presente, oppure fare in modo che uno script di avvio esegua il sysctlcomando manualmente se si desidera modificare questo parametro utilizzando sysctl.

Windows Vista / Windows Server 2008 e versioni successive:

A partire da Windows Vista e Windows Server 2008, Windows utilizza ora un ampio intervallo (49152-65535) per impostazione predefinita, in base all'articolo della Microsoft Knowledge Base 929851 . Lo stesso articolo mostra anche come modificare l'intervallo se lo si desidera, ma l'intervallo predefinito è ora sufficiente per la maggior parte dei server.

Sorgente Modifica dell'intervallo di porte effimere

È possibile visualizzare l'intervallo di porte dinamiche su un computer che esegue Windows Vista o Windows Server 2008 utilizzando i netshcomandi seguenti :

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

Gli appunti:

  • L'intervallo è impostato separatamente per ciascun trasporto e per ciascuna versione di IP.
  • L'intervallo di porte è ora veramente un intervallo con un punto iniziale e un punto finale.
  • I clienti Microsoft che distribuiscono server che eseguono Windows Server 2008 potrebbero avere problemi con la comunicazione RPC tra server se i firewall vengono utilizzati sulla rete interna.
  • In questi casi, si consiglia di riconfigurare i firewall per consentire il traffico tra i server nell'intervallo di porte dinamico di 49152 through 65535.
  • Questa gamma si aggiunge alle porte ben note utilizzate dai servizi e dalle applicazioni.
  • In alternativa, l'intervallo di porte utilizzato dai server può essere modificato su ciascun server.

Puoi regolare questo intervallo usando il netshcomando, come segue:

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

Questo comando imposta l'intervallo di porte dinamiche per TCP. La porta iniziale è il numero e il numero totale di porte è intervallo. I seguenti sono comandi di esempio:

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

Questi comandi di esempio impostano l'intervallo di porte dinamiche per iniziare dalla porta 10000 e per terminare alla porta 10999(1000 porte).

Gli appunti:

  • L'intervallo minimo di porte che è possibile impostare è 255.
  • La porta iniziale minima che può essere impostata è 1025.
  • La porta di estremità massima (in base all'intervallo da configurare) non può superare 65535.
  • Per duplicare il comportamento predefinito di Windows Server 2003, utilizzare 1025come porta iniziale, quindi utilizzare 3976come intervallo per TCP e UDP. Ciò comporta una porta iniziale di 1025e una porta finale di 5000.

Articolo della Microsoft Knowledge Base 929851 di origine :

Windows XP e precedenti:

Per i sistemi operativi Windows precedenti (Windows XP e precedenti), Windows utilizza l'intervallo BSD tradizionale da 1024 a 4999 per l'intervallo di porte temporanee. Sfortunatamente sembra che sia possibile impostare solo il limite superiore dell'intervallo di porte effimere. Ecco le informazioni estratte dall'articolo della Microsoft Knowledge Base 196271 :

  • Avviare l'Editor del Registro di sistema ( Regedt32.exe).
  • Individua la seguente chiave nel registro:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  • Dal menu "Modifica", fai clic su "Aggiungi valore", quindi aggiungi il seguente valore di registro:

    Nome valore: MaxUserPortTipo di dati: REG_DWORDValore: 65534(ad esempio)

    Intervallo valido: 5000-65534(decimale) Impostazione predefinita: 0x1388(5000 decimale)

    Descrizione: questo parametro controlla il numero di porta massimo utilizzato quando un'applicazione richiede qualsiasi porta utente disponibile dal sistema. Normalmente, le porte effimere (cioè di breve durata) sono allocate tra i valori di 1024e 5000inclusivo.

  • Chiudi l'editor del registro.

Nota: esiste un altro articolo KB pertinente ( 812873 ) che afferma di consentire all'utente di impostare un intervallo di esclusione, il che potrebbe significare che è possibile escludere le porte 1024-9999(ad esempio) per avere l'intervallo di porte temporaneo 10000-65534. Tuttavia, non siamo riusciti a farlo funzionare (dall'ottobre 2004).

Sorgente Modifica dell'intervallo di porte effimere


1
Perlomeno Windows sembra che sia possibile restringere il range di porte a livello di sistema. Nella maggior parte dei casi questa è probabilmente una cattiva idea, in particolare limitarla a una porta sarebbe: Vedi KB 929851 , i comandi elencati funzionano almeno su Windows 7.
Seth

@ Seth Sì. Ero riluttante a menzionarlo poiché l'OP non ha menzionato il suo sistema operativo e non volevo espandere la risposta per coprire N sistemi operativi ...
DavidPostill

Hai ragione a riguardo. Dopotutto ci sono molti sistemi operativi. È solo qualcosa in cui mi sono imbattuto mentre originariamente cercavo di rispondere a questa domanda. Dato che la tua risposta è stata più veloce, ho pensato di aggiungerla. È una risposta davvero ben scritta! :) L'ho appena aggiunto come suggerimento che a volte è sufficiente cambiare la configurazione piuttosto che riprogrammare (forse la mia comprensione è solo diversa - per me sembra simile a ricompilare).
Seth,

1
In effetti, anche in Linux è molto semplice: basta fare eco "49152 65535"> / proc / sys / net / ipv4 / ip_local_port_range . È così semplice che può essere fatto su una base per comando .
MariusMatutiae,

2
Piuttosto che cambiare l'intervallo di porte effimere sarebbe molto meglio che l'applicazione chiamasse la bindchiamata di sistema prima che chiami connect. Alcune applicazioni hanno un'opzione per farlo, altre no.
Kasperd,

9

La risposta di David Postill è perfettamente giusta. Vorrei solo aggiungere ad esso, sottolineando che cambiare l'intervallo di porte effimere in Linux è così semplice, che l'OP ha una risposta affermativa.

Si modifica l'EPR come segue:

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

e puoi selezionare la porta 50000 (come esempio) con il seguente script:

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 

Un avvertimento qui: poiché esiste una singola porta nell'intervallo, un'altra applicazione potrebbe strappartela via tra l'esecuzione della terza e la quarta riga sopra; inoltre, anche se non ci sono condizioni di gara, paralizzerai tutte le altre applicazioni fino a quando non ripristinerai un EPR di grandi dimensioni, motivo per cui ho ripristinato la gamma originale il prima possibile.

Pertanto, se il sistema operativo dei PO fosse stato Linux, la risposta sarebbe stata che poteva essere fatto facilmente.

Sorprendentemente, questo non è così semplice su BSD, alcuni dei quali non hanno nemmeno un'impostazione del kernel di runtime per EPR. MacOS X, FreeBSD e OpenBSD richiedono la modifica del file /etc/sysctl.conf , ma hanno scelte diverse per l'EPR.

Indipendentemente da quanto sopra e dal sistema operativo, il fatto che qualcosa possa essere fatto non significa che debba essere fatto: perché mai hai bisogno di questo? Non riesco a pensare a un singolo caso d'uso.


Per Linux esempio +1.
DavidPostill

Hehe. BSD / OS richiede la ricompilazione del kernel :)
DavidPostill

1
@DavidPostill Questo è un grande peccato.
MariusMatutiae,

C'è un difetto nell'esempio di codice. Il tuo cast di tipo è molto fuori luogo. Inoltre, sarebbe una buona idea rendere BIND_PORTfacoltativo, in modo tale che il codice possa ancora essere utilizzato esattamente allo stesso modo dell'originale. Penso che htons(bind_port_env ? atoi(bind_port_env) : 0)farebbe la cosa giusta.
Kasperd,

1

Vale la pena aggiungere che ha anche il kernel Linux

net.ipv4.ip_local_reserved_ports

manopola che fa un po 'l'opposto ma tuttavia potrebbe essere molto utile perché in questo modo puoi "fare un buco" per i servizi che aprono una o più porte specifiche in un intervallo di porte altrimenti effimero.

Breve estratto dai documenti :

Specificare le porte riservate alle applicazioni di terze parti conosciute. Queste porte non verranno utilizzate dalle assegnazioni automatiche delle porte (ad es. Quando si chiama connect () o bind () con il numero di porta 0). Il comportamento esplicito nell'allocazione delle porte è invariato.

Il formato utilizzato sia per l'input che per l'output è un elenco di intervalli separato da virgole (ad es. "1,2-4,10-10" per le porte 1, 2, 3, 4 e 10). La scrittura nel file cancellerà tutte le porte precedentemente riservate e aggiornerà l'elenco corrente con quello indicato nell'input.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.