Wie kann man "nc" an einem Port anhören, ohne "SO_REUSEPORT" einzustellen?

983
MondKin

Ich möchte, dass ein ncBefehl einen TCP-Port überwacht, also habe ich Folgendes getan:

nc -lv 8888 

In einer anderen Konsole habe ich dann geprüft, ob ein anderes Programm, das versucht, den gleichen Port zu überwachen, eine Address already in useArt Fehler erhalten würde. Ich gab den gleichen Befehl erneut aus:

nc -lv 8888 

Zu meiner Überraschung war auch der zweite Befehl erfolgreich. Zu untersuchen, wie 2 - Programme können auf dem gleichen TCP - Port horchen, fand ich, das ist möglich, wenn der Abhörsocket mit der Option geöffnet wird SO_REUSEPORT, so dass ich vorstellen nc, wird es zu benutzen.

Wie kann ich verhindern, ncdass andere Programme denselben Port verwenden? Ich möchte, dass Port 8888 angehört wird und sichergestellt wird, dass dies das einzige Programm ist, das an diesem Port zu hören ist.

Bisher habe ich in der Lage gewesen zu tun, was ich will durch die Einführung socatzusammen ncwie folgt aus :

socat TCP-LISTEN:8888,fork TCP:localhost:4444 nc -lv 4444 

Weil verhindert socat, dass ein anderes Programm am selben Port hört.

Aber kann man das nur mit erreichen nc?

1
Technisch kann es "SO_REUSEPORT" sein. Für Benutzer, die mit dem Konzept nicht vertraut sind: [link] (https://stackoverflow.com/q/14388706). In Linux ist es nicht schlecht, weil "alle Sockets, die dieselbe Adress- und Portkombination verwenden möchten, zu Prozessen gehören müssen, die dieselbe effektive Benutzer-ID verwenden". Theoretisch müssen Sie also darauf achten, was Sie ausführen. Trotzdem ist Ihre Frage berechtigt. Kamil Maciorowski vor 5 Jahren 0
Danke für diesen Link, ich habe viel gelernt! Die Frage wurde ebenfalls aktualisiert, um `SO_REUSEPORT` zu lesen. MondKin vor 5 Jahren 0

1 Antwort auf die Frage

2
mpromonet

Suchen Sie nach einem der netcat-Quellcodes netcat.c in der Methode local_listen:

 ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ret == -1) err(1, NULL);  # if defined(SO_REUSEPORT) ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); if (ret == -1) err(1, NULL); # endif 

Um das Verhalten zu ändern, müssen Sie dann den Code ändern.

Ich habe jedoch einen Test mit netcat-openbsd 1.105-7 gemacht, der Teil von Ubuntu Xenial ist und offensichtlich ohne Definition von SO_REUSEPORT erstellt wurde. Da SO_REUSEADDR festgelegt ist, aber nicht SO_REUSEPORT (unter einem Kernel> 3.9), funktioniert es so, als würden Sie erwarten, dass Sie nicht die zweite Intance am selben Port ausführen.

Ich verwende Ubuntu 18.04, vielleicht wird es hier mit 'SO_REUSEPORT' kompiliert. Schade, es gibt keine Konfigurationsoption, um diese Option auszuschalten :(. Vielen Dank für Ihre Zeit! MondKin vor 5 Jahren 0