![¿Cómo puedo alcanzar un puerto abierto y de escucha en Linux?](https://rvso.com/image/76414/%C2%BFC%C3%B3mo%20puedo%20alcanzar%20un%20puerto%20abierto%20y%20de%20escucha%20en%20Linux%3F.png)
Después de reenviar el puerto que deseo abrir, parece que no puedo conectarme ni recibir datos en este puerto. El software PHP CLI que he escrito está escuchando activamente el puerto enubuntu 14.04. Parte del código se muestra a continuación. El puerto se abre como AF_INET, el script no arroja errores para cada línea y /etc/protocols tiene tcp definido como 'tcp 6 TCP'.
// 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. */ }
Los puertos se reenvían y milas iptables están vacías, aunque he intentado agregar específicamente una regla de permiso para el puerto. Intenté ejecutar el script como superusuario. Cuando el servidor está escuchando, netstat -tuln enumera esta línea (con mi puerto 8399), y noto que Apache también aparece, que funciona bien y se muestra como un puerto abierto desde sitios web de verificación de puertos externos (en el puerto 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
Al usar nmap, el puerto también se muestra abierto. También probé diferentes puertos. Mi secuencia de comandos de conexión del lado del cliente es una secuencia de comandos websocket JavaScript que funciona para conectarse cuando se ejecuta PHP CLI en Windows. El script es demasiado largo para incluirlo aquí y no se conecta desde una red externa. Si configuro los scripts JS y PHP en las direcciones locales 127.0.0.1 o 192.168.0.###, entonces funciona, pero no desde un dispositivo fuera de mi 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');
¿Me falta algún firewall en Linux además de iptables que no paso por alto? Apache está abriendo correctamente los puertos y otro software en la PC, pero parece que a mi script le falta un paso necesario para abrir completamente el puerto para uso externo.
tl, dr; Conexión mediante una dirección IP externa mediante un cliente JavaScript al servidor PHP que funciona en Windows pero no en Ubuntu.Puerto reenviado, escuchando, no bloqueado por iptables, ¿lo que queda?
Respuesta1
Te falta algo conceptualmente y en el código. Tienes el código PHP escuchando conexiones, pero debes aceptar una conexión antes de usarla.
$ns = socket_accept($this->wsRead[0]);
$some_string = socket_read($ns, 128);
La llamada a socket_accept()
los bloques. No volverá hasta que algún programa cliente se conecte al programa que ahora espera conexión.
Una llamada a socket_accept()
devuelve el socket real que utiliza para comunicarse con el programa remoto. No creo isset()
que sea realmente lo que quieres, deberías investigar socket_select()
o algo así. Cuando haya terminado de comunicarse con el control remoto, llame socket_close($ns)
y luego vuelva a llamar socket_accept($this->wsRead[0])
para esperar a que otro programa remoto se conecte a su programa.
Cuando su programa PHP haya terminado de manejar las conexiones, debería llamar socket_close($this->wsRead[0])
para cerrar el socket, lo que básicamente le dice al kernel del sistema operativo que deje de escuchar los paquetes TCP SYN entrantes para el puerto que especifique.
Respuesta2
Resulta que el problema era de varias cosas, la mayoría provenientes de mi módem/enrutador. Uso unMotorola SB6580, que recientemente tuvo una actualización de firmware y no se reinició durante 10 días, lo que provocó que se volviera bastante lento, lo que me disuadió de querer hacer demasiados cambios en él.
ElLa actualización del firmware cambió la página de reenvío de puertos.para incluir una sección de dirección de host remoto externo (el valor predeterminado es 0.0.0.0) no hay problema aquí, pero algo más que hicieron rompió las reglas de reenvío de puertos existentes que había establecido.
Estaba usando una variedad de puertos para reenviar que no funcionaban y, al cambiar este rango a 8399 - 8399, comenzó a funcionar nuevamente. El reinicio no lo afectó además de aumentar la velocidad del módem, ni tampoco el cambio de protocolo de Ambos a TCP.
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
Además, cuando se utiliza el comando de PHP gethostbyname(gethostname()) en Linux, la dirección devuelta es una dirección local de 127.0.1.1, la segunda entrada en el archivo /etc/hosts, que no funcionará para vincular un socket. $_SERVER['REMOTE_ADDR'] también devuelve una advertencia: no se puede buscar el host. Porcambiando esto manualmente a la dirección de inicio (¿subred?) (la mía es 192.168.0.101) o el comodín IPv4 0.0.0.0, el detector de socket está vinculado correctamente y acepta conexiones externas.
Mi experiencia con el enrutador y mi inexperiencia con Linux me hicieron inclinarme por el camino equivocado para solucionar problemas de Linux. Después de notar que las cosas tampoco funcionaban en Windows 7, hice los 2 cambios anteriores y ahora todo funciona como debería.