Was ist der einfachste Weg, um einen ungenutzten lokalen Port zu finden?
Momentan verwende ich etwas Ähnliches:
port=$RANDOM
quit=0
while [ "$quit" -ne 1 ]; do
netstat -a | grep $port >> /dev/null
if [ $? -gt 0 ]; then
quit=1
else
port=`expr $port + 1`
fi
done
Es fühlt sich schrecklich rund an, also frage ich mich, ob es einen einfacheren Weg gibt, wie zum Beispiel einen eingebauten, den ich verpasst habe.
shell
networking
shell-script
netstat
mybuddymichael
quelle
quelle
-n
zu Netstat und einem selektiveren Grep). Versuchen Sie, einen Port in dem von Ihnen benötigten Modus zu öffnen, und versuchen Sie es mit einem anderen, falls dieser nicht verfügbar ist.ssh -D
als SOCKS-Server verwendet werden kann.Antworten:
Wenn Ihre Anwendung dies unterstützt, können Sie versuchen, Port 0 an die Anwendung zu übergeben. Wenn Ihre Anwendung dies an den Kernel weiterleitet, wird der Port zum Zeitpunkt der Anforderung dynamisch zugewiesen und wird garantiert nicht verwendet (die Zuordnung schlägt fehl, wenn alle Ports bereits verwendet werden).
Andernfalls können Sie dies manuell tun. Das Skript in Ihrer Antwort weist eine Race-Bedingung auf. Sie können dies nur vermeiden, indem Sie atomar überprüfen, ob es geöffnet ist, indem Sie versuchen, es zu öffnen. Wenn der Port verwendet wird, sollte das Programm beendet werden, wenn der Port nicht geöffnet werden kann.
Angenommen, Sie versuchen, mit GNU Netcat zuzuhören.
quelle
$port
im eigentlichen Programm wie in verwenden würdenwhile ...; done; program --port $port
.Meine Lösung besteht darin, an Port 0 zu binden, der den Kernel auffordert, einen Port aus dessen ip_local_port_range zuzuweisen. Schließen Sie dann den Socket und verwenden Sie diese Portnummer in Ihrer Konfiguration.
Dies funktioniert, weil der Kernel die Portnummern erst wiederzuverwenden scheint, wenn dies unbedingt erforderlich ist. Nachfolgende Bindungen an Port 0 weisen eine andere Portnummer zu. Python-Code:
Dies gibt nur eine Nummer eines Ports, z.
60123
.Führen Sie dieses Programm 10 000 Mal aus (Sie sollten es gleichzeitig ausführen), und Sie erhalten 10 000 verschiedene Portnummern. Daher denke ich, dass es ziemlich sicher ist, die Ports zu verwenden.
quelle
python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'
{ 1: 7006, 2: 1249, 3: 151, 4: 8, 5: 1, 6: 1}
ruby -e 'puts Addrinfo.tcp("", 0).bind { |s| s.local_address.ip_port }'
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):
Zeile für Zeile
comm
ist ein Dienstprogramm, das Zeilen in zwei Dateien vergleicht, die alphabetisch sortiert angezeigt werden müssen. 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-23
unterdrü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 habecomm
hier davon erfahren .Die erste Datei ist der Portbereich, aus dem wir auswählen können.
seq
Erzeugt eine sortierte Folge von Zahlen von$FROM
bis$TO
. Das Ergebnis wird alphabetisch (anstatt numerisch) sortiert undcomm
als erste Datei mithilfe der Prozessersetzung weitergeleitet .Die zweite Datei ist die sortierte Liste von Ports, dass wir durch den Aufruf den erhaltenen
ss
Befehls (mit-t
Bedeutung TCP - Ports,-a
alle Bedeutung - etabliert und zuhören - und-n
numerisch - versuchen Sie nicht zu lösen, sagen sie,22
zussh
). Wir wählen dann nur die vierte Spalte mit ausawk
, die die lokale Adresse und den Port enthält. Wir verwendencut
, um Adresse und Port mit dem:
Trennzeichen zu teilen und nur das letztere zu behalten (-f2
).ss
gib auch einen Header aus, den wir loswerden, indem wirgrep
nach nicht leeren Zahlenfolgen pingen, die nicht länger als 5 sind. Wir erfüllen dann diecomm
Anforderung, indem wirsort
ohne Duplikate arbeiten-u
.Jetzt haben wir eine sortierte Liste der offenen Ports, dass wir
shuf
fle , um dann die ersten greifen"$HOWMANY"
mit Einsenhead -n
.Beispiel
Besorgen Sie sich die drei zufällig geöffneten Ports im privaten Bereich (49152-65535)
könnte zum Beispiel zurückkehren
Anmerkungen
-t
mit-u
inss
, um stattdessen freie UDP-Ports zu erhalten.shuf
durch,sort -n
wenn Sie verfügbare Ports nicht zufällig, sondern numerisch sortiert erhalten möchtenquelle
Dank an Chris Down
quelle
Anscheinend können TCP-Verbindungen als Dateideskriptoren unter Linux ab mit in bash / zsh verwendet werden. Die folgende Funktion verwendet diese Technik und sollte schneller sein als der Aufruf von netcat / telnet.
Verwendungsanweisungen: Binden Sie die Ausgabe an eine Variable und verwenden Sie sie in Skripten. Getestet unter Ubuntu 16.04
quelle
ksh93
.$[$LPORT + ($RANDOM % ($UPORT-$LPORT))]
.\n
an jeden Abhörport gesendet :) Ich würde vorschlagen, dies hinzuzufügen-n
. Dadurch wird weiterhin versucht, eine Verbindung herzustellen, es wird jedoch nichts gesendet, sondern die Verbindung sofort getrennt.Hier ist ein plattformübergreifender, effizienter "Oneliner", der alle in Verwendung befindlichen Ports aufnimmt und Ihnen den ersten verfügbaren ab 3000 bereitstellt:
Sie können einfach alle Zeilen verbinden, um sie in einer Zeile zu haben. Wenn Sie den ersten von einer anderen Portnummer abrufen möchten, ändern Sie die Zuordnung zu
i
in derfor
Schleife.Es funktioniert sowohl auf Mac als auch auf Linux, weshalb der
[:.]
reguläre Ausdruck benötigt wird.quelle
-a
und nicht-t
nur auf TCP (6) Sockets schauen?ss -Htnl
besser (und schneller! - nicht, dass mir das etwas ausmacht: P) sein.-t
zumindest nicht das , mit dem Apple ausgeliefert wird, undss
ist auch nicht auf macOS vorhanden.netstat -aln
funktioniert sogar unter Solaris.Unter Linux können Sie Folgendes tun:
So finden Sie den ersten freien Port über 1080. Beachten Sie, dass
ssh -D
dies die Loopback-Schnittstelle beeinträchtigen würde. Theoretisch könnten Sie also Port 1080 wiederverwenden, wenn ein Socket eine Bindung an eine andere Adresse hat. Ein anderer Weg wäre, es tatsächlich zu versuchen und zu binden:quelle
ssh -D
, ich kann keine bessere Option sehen. Die-O forward
Option vonssh
gibt keinen Fehler zurück, wenn die Weiterleitung fehlschlägt.Dies ist die Version, die ich benutze:
Der Befehl
shuf -n 1 -i 49152-65535
gibt Ihnen einen "zufälligen" Port im Dynamikbereich. Wenn es bereits verwendet wird, wird ein anderer Port in diesem Bereich ausprobiert.Der Befehl
netstat -atun
listet alle (-a) TCP (-t) - und UDP (-u) -Ports auf, ohne Zeit für die Ermittlung der Hostnamen (-n) zu verschwenden.quelle
Dies ist Teil einer Funktion in meinem .bashrc, die dynamisch SSH-Tunnel erstellt und versucht, einen beliebigen Port in einem Bereich zu verwenden:
YMMV
quelle
Noch ein Lauf auf diesem alten Steckenpferd:
Dieser Code macht rein mobilen Einsatz von
netstat
,egrep
,awk
, & al. Beachten Sie, dass nur externe Befehle aufgerufen werden, um am Anfang eine Liste der belegten Ports zu erhalten. Man kann einen oder mehrere freie Ports anfordern:und starte an einem beliebigen Port:
quelle
Meine Kombination aus anderen Antworten oben. Kapiert:
Mit shuf -n1 nehmen wir eine Zufallszahl aus dem Bereich (-i) in / proc / sys / net / ipv4 / ip_local_port_range. Benötigen Sie die Syntax mit Bindestrich, so verwenden wir tr, um die Registerkarte in einem Bindestrich zu ändern.
Als nächstes zeigen wir uns mit netstat alle (-a) tcp und udp (-u -t) Verbindungen in Zahlen (-n), wenn wir unseren zufälligen Port $ port darin finden (beginnen mit a: und enden mit w whitespace ( \ s) dann brauchen wir einen anderen Port und fahren so fort. Andernfalls (grep -q hat einen Returncode> 0, wir haben die while-Schleife verlassen und $ port ist gesetzt.
quelle
Wenn Sie Python herumliegen haben, würde ich dies tun:
quelle
Ich habe dieses kleine Python2 / 3-Skript geschrieben, das Ihnen beim nächsten Mal helfen könnte:
https://github.com/sdenel/find-unused-local-port
quelle
Meine Meinung dazu ... die Funktion versucht,
n
aufeinanderfolgende freie Ports zu finden :quelle