Linux Kommando holt unbenutzten Port

20

Ich suche nach einem Befehl oder Skript, das einen nicht verwendeten Port auf meinem Ubuntu-Linux-System zurückgibt. Ich habe im Internet nachgesehen und das einzige, was ich finde, ist der verwendete / Listen-Port mit dem nestat-Befehl. Anscheinend funktioniert etwas mit dem Befehl netstat, weiß aber nicht genau was. Irgendeine Idee wie?

Vielen Dank.

user2429082
quelle
1
Warum müssen Sie das genau tun? Wenn Sie einen Server entwickeln, können Sie eine Bindung zu Port 0 herstellen, und das Betriebssystem weist Ihnen einen freien Port zu. Sie müssen nichts suchen. Andernfalls ist das Suchen und dann das Binden für die Rennbedingungen anfällig. Siehe zum Beispiel stackoverflow.com/questions/1365265/… oder stackoverflow.com/questions/1075399/…
Patrick Mevzek

Antworten:

14

netstat -latGibt die vollständige Liste der empfangsbereiten und eingerichteten Ports an.

Wenn sich kein Port in einem dieser Zustände befindet, existiert für das System kein Befehl, der die Liste der nicht verwendeten Ports anzeigt.

Denken Sie daran, dass es 65535 Ports gibt, also ist alles, was nicht aktiviert netstat -latist, ein unbenutzter Port.

Das folgende Bash-Skript führt einen einfachen Scan der TCP- Ports durch und teilt Ihnen mit, welche geöffnet und welche geschlossen sind :

#!/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

Wenn Sie es als speichern portscan.sh dann muss es laufen als ./portscan.sh IP first_port last_port , zum Beispiel: ./portscan 127.0.0.1 20 135die lokale Ausrüstung von Häfen 20-135 scannen

jcbermu
quelle
7

Ruby 2.x (Einzeiler):

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

Auf meinem Computer, auf dem gerade gedruckt wurde:

42644

Ein nachfolgender Aufruf wurde gedruckt:

36168

Diese Technik bewirkt, dass der aktuelle Benutzer einen nicht verwendeten Port anfordert (an Port "0" binden) und dann die vom Betriebssystem bereitgestellte Portnummer ausgibt. Und da der aktuelle Benutzer fragt, werden Ports unter 1024 nicht zurückgegeben (es sei denn, der aktuelle Benutzer ist root).

Kredit wo Kredit fällig ist - diese Lösung stammt aus einem Kommentar von Franklin Yu auf unix.stackexchange.com .

G. Sylvie Davies
quelle
Wie kann ich das Ergebnis einer Variablen in einem Bash-Skript zuweisen?
Neil Stevens
export PORT = $ (ruby -e 'require "socket"; setzt Addrinfo.tcp ("", 0) .bind {| s | s.local_address.ip_port}')
G. Sylvie Davies
3

Kurzes Bash-Skript, das zufällig eine Zahl zwischen 1025 und 60000 generiert und eine Schleife durchläuft, bis diese Zahl nicht mehr in der Liste der verwendeten Ports gefunden wird. Dies ist eine schnelle und schmutzige Lösung, die sich auf größere Ports konzentriert:

CHECK="do while"

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

echo $PORT
Taras
quelle
Überprüfen Sie Ihren grep-Befehl, siehe Kommentar zu adarshr Antwort
Nick
2

Einzeiler

Ich habe einen netten Einzeiler zusammengestellt, der schnell seinen Zweck erfüllt und es ermöglicht, eine beliebige Anzahl von Ports in einem beliebigen Bereich zu erfassen (hier ist er zur besseren Lesbarkeit in 4 Zeilen unterteilt):

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"

Zeile für Zeile

commist ein Dienstprogramm, das sortierte Zeilen in zwei Dateien vergleicht. Es gibt drei Spalten aus: Zeilen, die nur in der ersten Datei erscheinen, Zeilen, die nur in der zweiten erscheinen, und gemeinsame Zeilen. Durch die Angabe -23unterdrücken wir letztere Spalten und behalten nur die erste. Wir können dies verwenden, um die Differenz zweier Mengen zu erhalten, ausgedrückt als eine Folge von Textzeilen. Ich habe comm hier davon erfahren .

Die erste Datei ist der Portbereich, aus dem wir auswählen können. seqErzeugt eine sortierte Folge von Zahlen von $FROMbis $TO. Das Ergebnis wird commmithilfe der Prozessersetzung als erste Datei weitergeleitet .

Die zweite Datei ist die sortierte Liste von Ports, dass wir durch den Aufruf des erhaltenen ssBefehls (mit -tBedeutung TCP - Ports, -aalle Bedeutung - etabliert und zuhören - und -nnumerisch - versuchen Sie nicht zu lösen, sagen sie, 22zu ssh). Wir wählen dann nur die vierte Spalte mit aus awk, die die lokale Adresse und den Port enthält. Wir verwenden cut, um Adresse und Port mit dem :Trennzeichen zu teilen und nur das letztere zu behalten ( -f2). ssgib auch einen Header aus, den wir loswerden, indem wir grepnach nicht leeren Zahlenfolgen pingen, die nicht länger als 5 sind. Wir erfüllen dann die commAnforderung, indem wir sortnumerisch ( -n) und Duplikate mit loswerden uniq.

Jetzt haben wir eine sortierte Liste der offenen Ports, dass wir shuffle , um dann die ersten greifen "$HOWMANY"mit Einsen head -n.

Beispiel

Besorgen Sie sich die drei zufällig geöffneten Ports im privaten Bereich (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

könnte zum Beispiel zurückkehren

54930
57937
51399

Anmerkungen

  • wechseln Sie -tmit -uin ss, um stattdessen freie UDP-Ports zu erhalten.
  • Lassen shufSie es fallen, wenn Sie nicht an einem zufälligen Port interessiert sind
stefanobaghino
quelle
1
Ich mag deinen Einzeiler, diese Version parst IPv6 richtig, zB [:: 1]: 52792 und benutze die Option --no-header anstelle von grep. gist.github.com/fstefanov/ff4dcec7ded59514421bf944d1bb9a6f
Filip Stefanov
1

Ich musste nur einen zufälligen unbenutzten Port finden und keine Liste von ihnen drucken. Hier ist meine Bash-Lösung.

#/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

Und nutzen Sie es durch Beschaffung

$ . ./random_unused_port.sh; echo $RANDOM_PORT
adarshr
quelle
Ich mag die Idee hier, aber Ihr grep-Befehl wird nicht zurückgeben, was Sie beabsichtigen. Das Gute ist, dass es konservativ sein wird, aber wenn der nächste zufällige Port 2000 ist und Port 2000 offen ist, Port 20000 jedoch verwendet wird, wird es weiter suchen, sodass das Ergebnis nicht der vollständige Bereich der verfügbaren Ports ist.
Nick
1

Vielleicht eine andere Lösung basierend auf der Liste der verwendeten Ports:

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)

Der netstatBefehl generiert eine Liste aller offenen Ports. Der sedBefehl extrahiert die verwendeten Portnummern und das sort/ uniq-Konstrukt gibt eine eindeutige Liste der offenen Ports zurück. Der zweite Schritt besteht darin, eine Liste von Portnummern zu erstellen, die bei 1 beginnen und bei 1000 enden (reservierte Ports), sowie eine zusätzliche Liste aller Portnummern, die bei 1 bis 65535 beginnen. Die endgültige Liste enthält alle verfügbaren Ports nur einmal und uniq -uextrahiert sie . Zuletzt shuf -n 1wählt der einen zufälligen Port aus der vollständigen Liste der verfügbaren Ports aus. Trotzdem wird es eine Rennbedingung geben, bevor man den Hafen reservieren kann.

Frank Förster
quelle
1

Ich musste den nächsten offenen Port ausgehend von einer Portnummer finden. Hier ist mein Versuch, die @ Taras-Lösung zu verwenden.

_check="placeholder"
START_FROM=1900
PORT=$(( ( "$RANDOM" % 1000 ) + $START_FROM ))
while [[ ! -z "${_check}" ]]; do
    ((PORT++))
    _check=$(ss -tulpn | grep ":${PORT}")
done
Alberto Chiusole
quelle
0

Wenn 54321 Ihr Port ist, führen Sie Folgendes aus:

sudo netstat -ap |grep 54321

Einige Variationen der Verwendung von netstat finden Sie hier .

Overmind
quelle
Dieser Befehl zeigt mir nur, ob der Port 54321 verwendet wird oder nicht. Was ich finden möchte ist, ist unbenutzter Port.
user2429082
Unbenutzt ist mehrdeutig. Sie möchten überprüfen, welche Ports zum Abhören verfügbar sind? Oder mit welchem ​​Port kann eine Verbindung hergestellt werden? Alle nicht verwendeten sind verfügbar. Als Benutzer können Sie die über 1024 verwenden, als root auch die unter 1024.
Overmind