Wie kann ich unter Linux einen offenen und lauschenden Port erreichen?

Wie kann ich unter Linux einen offenen und lauschenden Port erreichen?

Nach der Weiterleitung des Ports, den ich öffnen möchte, kann ich keine Verbindung herstellen oder Daten über diesen Port abrufen. Die von mir geschriebene PHP-CLI-Software hört den Port aktiv ab.Ubuntu 14.04. Ein Teil des Codes wird unten angezeigt. Der Port ist als AF_INET geöffnet, das Skript gibt für jede Zeile keine Fehler aus und in /etc/protocols ist TCP als „TCP 6 TCP“ definiert.

// I have tried $host=gethostbyname(gethostname());$port=8399 (host is 127.0.1.1)
// as well as $host = '0.0.0.0'; $port = 8399; and other addresses

$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1)
socket_bind($this->wsRead[0], $host, $port) 
socket_listen($this->wsRead[0], 10)
while (isset($this->wsRead[0])) { /* Handshake/Process data, etc. */ }

Die Ports werden weitergeleitet und meiniptables sind leer, obwohl ich versucht habe, speziell eine Zulassungsregel für den Port hinzuzufügen. Ich habe versucht, das Skript als Superuser auszuführen. Wenn der Server lauscht, listet netstat -tuln diese Zeile auf (mit meinem Port 8399), und ich stelle fest, dass auch Apache aufgeführt ist, was einwandfrei funktioniert und als offener Port von externen Port-Checking-Websites angezeigt wird (auf Port 8301):

Proto Recv-Q Send-Q Local Address      Foreign Address    State
tcp        0      0 0.0.0.0:8399       0.0.0.0:*          LISTEN
tcp6       0      0 :::8301            :::*               LISTEN
tcp6       0      0 :::80              :::*               LISTEN

Bei Verwendung von nmap wird der Port ebenfalls als offen angezeigt. Ich habe auch verschiedene Ports ausprobiert. Mein clientseitiges Verbindungsskript ist ein JavaScript-WebSocket-Skript, das eine Verbindung herstellt, wenn die PHP-CLI unter Windows ausgeführt wird. Das Skript ist zu lang, um es hier einzufügen, und es stellt keine Verbindung vom externen Netzwerk her. Wenn ich sowohl JS- als auch PHP-Skripte auf die lokalen Adressen 127.0.0.1 oder 192.168.0.### einstelle, funktioniert es zwar, aber nicht von einem Gerät außerhalb meines LAN.

// The JS is basically this, plus some connection events to alert success/fail.
// This external connection request will always time out
Server = new WebSocket('ws://68.215.154.129:8399');

Fehlt mir in Linux außer iptables noch eine Firewall, die ich nicht umgehe? Apache und andere Software auf dem PC öffnen die Ports korrekt, aber anscheinend fehlt in meinem Skript ein notwendiger Schritt, um den Port für die externe Verwendung vollständig zu öffnen.

tl,dr; Die Verbindung über eine externe IP-Adresse mithilfe eines JavaScript-Clients zum PHP-Server funktioniert unter Windows, aber nicht unter Ubuntu.Port weitergeleitet, lauscht, nicht durch iptables blockiert, was ist übrig?

Antwort1

Ihnen fehlt konzeptionell und im Code etwas. Sie haben den PHP-Code, der auf Verbindungen wartet, aber Sie müssen eine Verbindung akzeptieren, bevor Sie sie verwenden können.

$ns = socket_accept($this->wsRead[0]);
$some_string = socket_read($ns, 128);

Der Aufruf von socket_accept()blockiert. Er wird erst dann zurückgegeben, wenn ein Client-Programm eine Verbindung mit dem jetzt auf die Verbindung wartenden Programm herstellt.

Ein Aufruf von socket_accept()gibt den tatsächlichen Socket zurück, den Sie zur Kommunikation mit dem Remote-Programm verwenden. Ich glaube nicht, isset()dass das wirklich das ist, was Sie wollen. Sie sollten sich das ansehen socket_select()oder so etwas. Wenn Sie mit der Kommunikation mit dem Remote-Programm fertig sind, rufen Sie auf socket_close($ns)und kehren dann zu call zurück, socket_accept($this->wsRead[0])um zu warten, bis ein anderes Remote-Programm eine Verbindung zu Ihrem Programm herstellt.

Wenn Ihr PHP-Programm mit der Verbindungsverarbeitung fertig ist, sollte es socket_close($this->wsRead[0])den Socket schließen. Dadurch wird dem Betriebssystemkernel grundsätzlich mitgeteilt, dass er nicht mehr auf eingehende TCP-SYN-Pakete für den von Ihnen angegebenen Port lauschen soll.

Antwort2

Es stellte sich heraus, dass das Problem mehrere Ursachen hatte, hauptsächlich mein Modem/Router. Ich benutze einMotorola SB6580, das vor Kurzem ein Firmware-Update hatte und 10 Tage lang nicht neu gestartet wurde, wodurch es ziemlich langsam wurde und mich davon abhielt, zu viele Änderungen daran vornehmen zu wollen.

DerFirmware-Update hat die Port-Weiterleitungsseite geändertum einen Abschnitt mit einer externen Remote-Host-Adresse einzuschließen (Standard: 0.0.0.0), hier kein Problem, aber etwas anderes, das sie getan haben, hat gegen die vorhandenen Portweiterleitungsregeln verstoßen, die ich festgelegt hatte.

Ich habe einen Portbereich für die Weiterleitung verwendet, der nicht funktionierte. Durch Ändern dieses Bereichs auf 8399 - 8399 funktionierte es wieder. Der Neustart hatte keine Auswirkungen, abgesehen von der Erhöhung der Modemgeschwindigkeit, und auch die Änderung des Protokolls von Both auf TCP hatte keine Auswirkungen.

IP Addr|Start Port|End Port|Remote Host Addr|Start Port|End Port|Protocol|Enabled
192.168.0.101|8340|    8399|         0.0.0.0|      8340|    8399|    Both|Checked
192.168.0.101|8399|    8399|         0.0.0.0|      8399|    8399|     TCP|Checked

Wenn Sie unter Linux den PHP-Befehl gethostbyname(gethostname()) verwenden, wird als Adresse die lokale Adresse 127.0.1.1 zurückgegeben, der zweite Eintrag in der Datei /etc/hosts, der für die Bindung eines Sockets nicht funktioniert. $_SERVER['REMOTE_ADDR'] gibt außerdem eine Warnung zurück: Host kann nicht gesucht werden.manuelles Ändern in die Home-Adresse (Subnetz?) (meine ist 192.168.0.101) oder den IPv4-Platzhalter 0.0.0.0, der Socket-Listener ist korrekt gebunden und akzeptiert externe Verbindungen.

Aufgrund meiner Erfahrung mit dem Router und meiner Unerfahrenheit mit Linux bin ich bei der Fehlerbehebung unter Linux auf die falsche Spur geraten. Nachdem ich bemerkt hatte, dass die Dinge auch unter Windows 7 nicht funktionierten, habe ich die beiden oben genannten Änderungen vorgenommen und jetzt funktioniert alles wie es sollte.

verwandte Informationen