Ich möchte einen offenen Port schließen, der sich im Empfangsmodus zwischen meiner Client- und Serveranwendung befindet.
Gibt es eine manuelle Befehlszeilenoption in Linux, um einen Port zu schließen?
HINWEIS: Ich habe erfahren, dass "nur die Anwendung, die den verbundenen Socket besitzt, diesen schließen sollte, was passieren wird, wenn die Anwendung beendet wird."
Ich verstehe nicht, warum es nur durch die Anwendung möglich ist, die es öffnet ... Aber ich bin immer noch gespannt, ob es eine andere Möglichkeit gibt, dies zu tun.
Antworten:
Ich hatte das gleiche Problem, der Prozess muss am Leben bleiben, aber der Socket muss schließen. Das Schließen eines Sockets in einem laufenden Prozess ist nicht unmöglich, aber schwierig:
Suchen Sie den Prozess:
Sie erhalten eine
source/destination ip:port portstate pid/processname
KarteSuchen Sie dabei den Dateideskriptor des Sockets
Sie erhalten eine Liste: Prozessname, PID, Benutzer, FileDescriptor, ... eine Verbindungszeichenfolge.
Suchen Sie die passende fileDescriptor-Nummer für die Verbindung. Es wird so etwas wie "97u" sein, was "97" bedeutet.
Verbinden Sie nun den Prozess:
Schließen Sie nun die Steckdose:
Beispiel:
Dann trennen Sie gdb:
Und die Steckdose ist geschlossen.
quelle
sudo lsof -np $pid
Gibt mir ungefähr 200 Zeilen und ich bin verwirrt darüber, wie ich den gewünschten FD finde. In meinem Fall handelt es sich um einen Chrome-Tab, und ich versuche, geöffnete Websockets zu schließen ...shutdown
:call shutdown($fileDescriptor, 0)
.Sie stellen hier die falsche Frage. Es ist nicht wirklich möglich, einen Port einfach von außerhalb der Anwendung zu "schließen", die den Socket geöffnet hat, der ihn abhört. Die einzige Möglichkeit, dies zu tun, besteht darin, den Prozess, dem der Port gehört, vollständig zu beenden. In ein oder zwei Minuten ist der Port dann wieder verfügbar. Hier ist, was los ist (wenn es Ihnen egal ist, fahren Sie mit dem Ende fort, wo ich Ihnen zeige, wie Sie den Prozess beenden, der einen bestimmten Port besitzt):
Ports sind Ressourcen, die vom Betriebssystem verschiedenen Prozessen zugewiesen werden. Dies ähnelt dem Auffordern des Betriebssystems nach einem Dateizeiger. Im Gegensatz zu Dateizeigern kann jedoch immer nur EIN Prozess einen Port besitzen. Über die BSD-Socket-Schnittstelle können Prozesse anfordern, einen Port abzuhören, den das Betriebssystem dann gewährt. Das Betriebssystem stellt außerdem sicher, dass kein anderer Prozess denselben Port erhält. Zu jedem Zeitpunkt kann der Prozess den Port freigeben, indem der Socket geschlossen wird. Das Betriebssystem fordert dann den Port zurück. Wenn der Vorgang beendet wird, ohne den Port freizugeben, wird das Betriebssystem den Port schließlich zurückfordern (obwohl dies nicht sofort geschieht: es dauert einige Minuten).
Was Sie jetzt tun möchten (einfach den Port von der Kommandozeile aus schließen), ist aus zwei Gründen nicht möglich. Erstens, wenn es möglich wäre, würde dies bedeuten, dass ein Prozess einfach die Ressource eines anderen Prozesses (den Port) stehlen könnte. Dies wäre eine schlechte Richtlinie, sofern sie nicht auf privilegierte Prozesse beschränkt ist. Der zweite Grund ist, dass unklar ist, was mit dem Prozess geschehen würde, dem der Port gehört, wenn wir ihn weiter laufen lassen. Der Code des Prozesses wird unter der Annahme geschrieben, dass er Eigentümer dieser Ressource ist. Wenn wir es einfach wegnehmen würden, würde es von alleine abstürzen, daher lassen die Betriebssysteme Sie dies nicht zu, selbst wenn Sie ein privilegierter Prozess sind. Stattdessen musst du sie einfach töten.
Wie auch immer, hier erfahren Sie, wie Sie einen Prozess beenden, der einen bestimmten Port besitzt:
Das wird die Zeile ausgeben, die dem Prozesshalteport entspricht, zum Beispiel:
In diesem Fall ist procHoldingPort der Name des Prozesses, der den Port geöffnet hat, 4683 die PID und 8000 (beachten Sie, dass es sich um TCP handelt) die Portnummer, die er enthält.
Dann schauen Sie in die letzte Spalte und Sie werden / sehen. Führen Sie dann Folgendes aus:
Wenn dies nicht funktioniert (Sie können dies überprüfen, indem Sie den Befehl netstat erneut ausführen). Mach das:
Im Allgemeinen ist es besser, das Senden von SIGKILL zu vermeiden, wenn Sie können. Deshalb sage ich dir, dass du es
kill
vorher versuchen sollstkill -9
. Nur mitkill
Sendet der schonendere SIGTERM.Wie gesagt, es wird noch einige Minuten dauern, bis der Hafen wieder geöffnet ist, wenn Sie dies tun. Ich weiß nicht, wie ich das beschleunigen kann. Wenn es jemand anderes tut, würde ich es gerne hören.
quelle
unix.tools.port.close(<my port number>)
ich es nutzen würdeinit 6
.Fixiereinheit kann auch verwendet werden
Hier ist das Protokoll tcp / udp und portno ist die Nummer, die Sie schließen möchten. Z.B
Weitere Informationen finden Sie auf der Manpage von fuser
quelle
fuser
Ausführung neu startet ?fuser
findet der Prozess den Port und tötet sie, aber nicht die Tatsache beheben, dass die Steckdose nicht geschlossen ist. 60 Sekunden und der Kernel erledigt das für mich.Alternativ können Sie auch iptables verwenden:
Im Grunde erreicht es, was Sie wollen. Dadurch wird der gesamte TCP-Verkehr auf Port 80 unterbrochen.
quelle
-j REJECT
TCP-Rücksetzflag zurückgeben, das dann beim Besitzprozess angezeigt wird (aber nur, wenn die andere Seite es versucht etwas senden).Es sollte Ihnen sagen, wenn Sie Apache ausführen, "httpd" (dies ist nur ein Beispiel, verwenden Sie den Port, den Ihre Anwendung verwendet, anstelle von 80).
oder
quelle
Sie könnten wahrscheinlich nur herausfinden, welcher Prozess den Socket geöffnet hat, dem der Port zugeordnet ist, und diesen Prozess beenden.
Aber Sie müssten sich darüber im Klaren sein, dass Sie das erstellt haben, wenn dieser Prozess keinen Handler hat, der alle von ihm verwendeten Daten (offene Dateien, Sockets, Forks, Daten, die nach dem Beenden nicht ordnungsgemäß geschlossen werden) deminitialisiert die Systemleistung beeinträchtigen. Außerdem bleibt der Socket offen, bis der Kernel feststellt, dass der Prozess abgebrochen wurde. Das dauert normalerweise nur ungefähr eine Minute.
Ich nehme an, die bessere Frage wäre: Welchen (zu welchem Prozess gehörenden) Port möchten Sie anhalten?
Wenn Sie versuchen, eine von Ihnen gefundene Hintertür oder einen Virus zu beenden, sollten Sie zumindest wissen, welche Daten hin und her gehen, bevor Sie sie beenden. (wireshark ist dafür gut geeignet) (und der Name der ausführbaren Datei des Prozesses, so dass Sie ihn löschen und verhindern können, dass er beim Neustart wieder angezeigt wird) oder, falls Sie etwas installiert haben (wie HTTPD oder FTPD oder etwas anderes), sollten Sie bereits Zugriff darauf haben der Prozess selbst.
Normalerweise wird es ein Steuerungsprogramm haben (HTTPD stop | start oder so). Oder, wenn es sich um ein System handelt, sollten Sie sich wahrscheinlich nicht damit anlegen. Wie auch immer, ich dachte, da alle anderen dir den "How-to" -Winkel geben, sollte ich dir die Vorbehalte geben.
quelle
Ich habe zuerst nach den Prozessen mongo und node gesucht und dann Folgendes ausgeführt:
Sobald Sie identifiziert sind, beenden Sie die Prozesse einfach mit dem Befehl kill.
Zuletzt tippen
meteor
und es sollte wieder funktionieren.quelle
Sie könnten ein Skript schreiben, das die iptables modifiziert und neu startet. Ein Skript zum Hinzufügen einer Regel zum Löschen aller Pakete auf dem Port, ein anderes Skript zum Entfernen der Regel.
Die anderen Antworten haben Ihnen gezeigt, wie Sie den an den Port gebundenen Prozess beenden können - dies ist möglicherweise nicht das, was Sie möchten. Wenn Sie möchten, dass der Server weiterhin ausgeführt wird, aber keine Verbindungen von Clients hergestellt werden, möchten Sie den Port blockieren und den Prozess nicht anhalten.
quelle
Ein weiteres Problem: Manchmal besitzt der Kernel selbst Ports. Ich weiß, dass NAT-Routing einige Ports für die Verwendung durch NAT offen hält. Sie können einen Prozess dafür nicht beenden, dies ist ein Kernel, und eine Neukonfiguration und ein Neustart sind erforderlich.
quelle
Wenn Sie möchten, dass Ihr Port früher freigegeben wird, müssen Sie den folgenden Wert festlegen:
Zum Einstellen von 60 Sekunden (Standard) auf 1 Sekunde
quelle
Sie können den Befehl killcx verwenden, um eine Verbindung zu schließen, ohne dass ein Prozess beendet werden muss.
quelle
Mir ist bewusst, dass diese Antwort nicht die eigentliche Frage beantwortet, aber in sie hineinzulesen, könnte eine relevante Information sein:
Das Standardverhalten beim Binden eines Sockets an einen Port (und eine Adresse) besteht darin, dass der Socket eine Weile in TIME_WAIT verbleibt, wenn der Socket durch abrupte Beendigung des Prozesses geschlossen wird. Dies bedeutet, dass Sie sich nicht sofort wieder an diese Adresse / diesen Port binden können. Wenn Sie das System selbst über die Standard-BSD-Socket-Schnittstelle entwickeln, können Sie dieses Verhalten (zumindest teilweise) mit der Socket-Option SO_REUSEADDR steuern. Auf diese Weise können Sie sich grundsätzlich wieder an dieselbe Adresse / denselben Port binden, wenn sich der Socket im Status TIME_WAIT befindet. Trotzdem noch eine Steckdose pro Port!
Diese Informationen sollten jedoch nur als Entwicklungshilfe verwendet werden, da es einen Grund dafür gibt, dass TIME_WAIT an erster Stelle steht, der bereits in den anderen Antworten erläutert wurde.
quelle
Wenn Sie keinen Datenverkehr über den Socket möchten, aber den Prozess am Leben erhalten möchten: tcpkill .
Startet einen Sniffing-Daemon, der den gesamten Datenverkehr auf diesem Port abfängt und zerstört. Sehr praktisch zum Testen Ihrer Anwendungen auf Netzwerksplits.
quelle
Sie können eine Hörbuchse mit ss schließen :
Wobei 1234 Ihre Portnummer ist.
ss ist Teil des iproute2-Pakets, daher gibt es eine starke Änderung, die es bereits auf einem modernen Linux installiert hat.
Dies erfuhr ich aus einer Antwort auf eine verwandte Frage .
quelle