Il comando Linux ottiene la porta non utilizzata


19

Sto cercando un comando o uno script che restituisca una porta inutilizzata sul mio sistema Ubuntu Linux. Ho cercato su internet e l'unica cosa che trovo riguarda la porta used / Listen con il comando nestat. Apparentemente qualcosa con il comando netstat funzionerà ma non so cosa esattamente. Qualche idea su come?

Grazie.



Perché hai bisogno di farlo esattamente? Se stai sviluppando un server, puoi collegarti alla porta 0 e il sistema operativo assegnerà una porta libera per te, non hai nulla da cercare. Altrimenti, la ricerca e quindi l'associazione è soggetta alle condizioni di gara. Si veda ad esempio stackoverflow.com/questions/1365265/... o stackoverflow.com/questions/1075399/...
Patrick Mevzek

Risposte:


14

netstat -latfornisce l'elenco completo delle porte di ascolto e stabilite .

Quando una porta non si trova su nessuno di questi stati non esiste per il sistema, quindi non troverai un comando che mostri l'elenco delle porte non utilizzate.

Tieni presente che ci sono 65535 porte, quindi tutto ciò che non netstat -latè acceso è una porta inutilizzata.

Il seguente script bash eseguirà una semplice scansione delle porte tcp e ti farà sapere quali sono aperti e quali sono chiusi :

#!/bin/bash
IP=$1
first_port=$2
last_port=$3
function scanner

{
for ((port=$first_port; port<=$last_port; port++))
        do
                (echo >/dev/tcp/$IP/$port)> /dev/null 2>&1 && echo $port open || echo "$port closed"
        done
}

scanner

Se lo si salva come doorscan.sh , deve essere eseguito come ./portscan.sh IP first_port last_port , ad esempio: ./portscan 127.0.0.1 20 135eseguirà la scansione dell'apparecchiatura locale dalle porte 20 a 135


7

Ruby 2.x (one-liner):

ruby -e 'require "socket"; puts Addrinfo.tcp("", 0).bind {|s| s.local_address.ip_port }'

Sulla mia macchina in questo momento che ha stampato:

42644

Una successiva invocazione stampata:

36168

Questa tecnica fa sì che l'utente corrente richieda una porta non utilizzata (associa alla porta "0"), quindi stampa il numero di porta fornito dal sistema operativo. E poiché l'utente corrente è quello che chiede, le porte inferiori a 1024 non verranno restituite (a meno che l'utente corrente = root).

Credito dove il credito è dovuto - questa soluzione deriva da un commento di Franklin Yu su unix.stackexchange.com Qual è il modo più semplice per trovare un porto locale inutilizzato?


Come potrei assegnare il risultato di questo a una variabile in uno script bash?
Neil Stevens,

export PORT = $ (ruby -e 'richiede "socket"; mette Addrinfo.tcp ("", 0) .bind {| s | s.local_address.ip_port}')
G. Sylvie Davies,

2

One-liner

Ho messo insieme un bel one-liner che serve rapidamente allo scopo, consentendo di afferrare un numero arbitrario di porte in un intervallo arbitrario (qui è diviso in 4 righe per la leggibilità):

comm -23 \
<(seq "$FROM" "$TO") \
<(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep '[0-9]\{1,5\}' | sort -n | uniq) \
| shuf | head -n "$HOWMANY"

Linea per linea

commè un'utilità che confronta le righe ordinate in due file. Produce tre colonne: linee che appaiono solo nel primo file, linee che appaiono solo nel secondo e linee comuni. Specificando -23sopprimiamo le ultime colonne e conserviamo solo la prima. Possiamo usarlo per ottenere la differenza di due insiemi, espressa come una sequenza di righe di testo. Ho imparato comm qui .

Il primo file è l'intervallo di porte che possiamo selezionare. seqproduce una sequenza ordinata di numeri da $FROMa $TO. Il risultato viene reindirizzato al commprimo file utilizzando la sostituzione del processo .

Il secondo file è l'elenco ordinato delle porte, che otteniamo chiamando il sscomando (con -tsignificato porte TCP, che -asignifica tutto - stabilito e in ascolto - e -nnumerico - non tentare di risolvere, diciamo, 22a ssh). Selezioniamo quindi solo la quarta colonna con awk, che contiene l'indirizzo e la porta locali. Usiamo cutper dividere indirizzo e porta con il :delimitatore e mantenere solo quest'ultimo ( -f2). ssemette anche un'intestazione, di cui ci sbarazziamo tramite grepping per sequenze di numeri non vuote che non sono più lunghe di 5. Rispettiamo quindi commil requisito sortinserendo numericamente ( -n) e sbarazzandoci dei duplicati uniq.

Ora abbiamo un elenco ordinato di porte aperte, che possiamo shufFLE per poi afferrare i primi "$HOWMANY"quelli con head -n.

Esempio

Prendi le tre porte aperte casuali nell'area privata (49152-65535)

comm -23 <(seq 49152 65535) <(ss -tan | awk '{print $4}' | cut -d':' -f2 | grep "[0-9]\{1,5\}" | sort | uniq) | shuf | head -n 3

potrebbe tornare ad esempio

54930
57937
51399

Gli appunti

  • passare -tcon -uin ssper ottenere invece le porte UDP gratuite.
  • rilasciare shufse non sei interessato ad afferrare una porta casuale

1
Mi piace il tuo one-liner, questa versione analizza correttamente IPv6, ad esempio [:: 1]: 52792 e usa l'opzione --no-header invece di grep. gist.github.com/fstefanov/ff4dcec7ded59514421bf944d1bb9a6f
Filip Stefanov

1

Breve script bash che genera casualmente un numero compreso tra 1025 e 60000 e scorre fino a quando quel numero non viene trovato nell'elenco delle porte utilizzate. Questa è una soluzione rapida e sporca che ha una propensione per le porte più grandi:

CHECK="do while"

while [[ ! -z $CHECK ]]; do
    PORT=$(( ( RANDOM % 60000 )  + 1025 ))
    CHECK=$(sudo netstat -ap | grep $PORT)
done

echo $PORT

Controlla il tuo comando grep, vedi commento sulla risposta di Adarshr
Nick,

1

Avevo bisogno di trovare una sola porta casuale inutilizzata e non stamparne un elenco. Ecco la mia soluzione bash.

#/bin/bash

function random_unused_port {
    local port=$(shuf -i 2000-65000 -n 1)
    netstat -lat | grep $port > /dev/null
    if [[ $? == 1 ]] ; then
        export RANDOM_PORT=$port
    else
        random_unused_port
    fi
}

random_unused_port

E usalo acquistandolo

$ . ./random_unused_port.sh; echo $RANDOM_PORT

Mi piace l'idea qui, tuttavia il tuo comando grep non restituirà ciò che intendi. La cosa buona è che sarà conservativa, ma se la prossima porta casuale è 2000 e la porta 2000 è aperta, ma la porta 20000 è in uso, continuerà a cercare, quindi il risultato non sarà l'intera gamma di porte disponibili.
Nick,

1

Forse un'altra soluzione basata sull'elenco delle porte utilizzate:

function random_unused_port {
   (netstat --listening --all --tcp --numeric | 
    sed '1,2d; s/[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*[[:space:]]*[^[:space:]]*:\([0-9]*\)[[:space:]]*.*/\1/g' |
    sort -n | uniq; seq 1 1000; seq 1 65535
    ) | sort -n | uniq -u | shuf -n 1
}

RANDOM_PORT=$(random_unused_port)

Il netstatcomando genera un elenco di tutte le porte aperte. Il sedcomando estrae i numeri di porta che sono in uso e il costrutto sort/ uniqrestituisce un elenco uniq di porte aperte. Il secondo passo è generare un elenco di numeri di porta che iniziano da 1 e finiscono con 1000 (porte riservate) e un elenco aggiuntivo di tutti i numeri di porta che iniziano da 1 fino a 65535. L'elenco finale contiene tutte le porte disponibili una sola volta e le uniq -uestrarrà . Infine, shuf -n 1verrà selezionata una porta casuale dall'elenco completo delle porte disponibili. Tuttavia, ci sarà una condizione di gara, prima che uno possa prenotare il porto.


0

Se 54321 è la tua porta, esegui:

sudo netstat -ap |grep 54321

Alcune varianti dell'uso di netstat sono disponibili qui .


Questo comando mi mostrerà solo se la porta 54321 è in uso o meno. Quello che voglio è trovare una porta inutilizzata.
user2429082

Inutilizzato è ambiguo. Vuoi verificare quali porte sono disponibili per l'ascolto? O a quale porta è disponibile la connessione? Tutti quelli che non sono in uso sono disponibili. Come utente, puoi usare quelli sopra 1024, come root, puoi usare anche quelli sotto 1024.
Overmind
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.