Como posso alcançar uma porta aberta e de escuta no Linux?

Como posso alcançar uma porta aberta e de escuta no Linux?

Depois de encaminhar a porta que desejo abrir, não consigo conectar ou obter dados para esta porta. O software PHP CLI que escrevi está escutando ativamente a porta emUbuntu 14.04. Parte do código é mostrada abaixo. A porta é aberta como AF_INET, o script não gera erros para cada linha e /etc/protocols tem 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. */ }

As portas são encaminhadas e meuiptables estão vazios, embora eu tenha tentado adicionar especificamente uma regra de permissão para a porta. Tentei executar o script como superusuário. Quando o servidor está escutando, netstat -tuln lista esta linha (com minha porta 8399), e noto que o apache também está listado, que funciona bem e mostra como uma porta aberta em sites de verificação de portas externas (na porta 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

Usando o nmap, a porta também mostra estar aberta. Eu tentei portas diferentes também. Meu script de conexão do lado do cliente é um script JavaScript websocket que funciona para conectar ao executar o PHP CLI no Windows. O script é muito longo para ser incluído aqui e não se conecta à rede externa. Se eu definir scripts JS e PHP para endereços locais 127.0.0.1 ou 192.168.0.### então ele funcionará, mas não de um dispositivo fora da minha 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');

Estou faltando algum firewall no Linux além do iptables que não estou ignorando? O Apache está abrindo as portas corretamente e outros softwares no PC, mas parece que meu script está faltando uma etapa necessária para abrir totalmente a porta para uso externo.

tl, dr; Conectando-se usando endereço IP externo usando cliente JavaScript ao servidor PHP funcionando no Windows, mas não no Ubuntu.Porta encaminhada, escutando, não bloqueada pelo iptables, o que sobrou?

Responder1

Está faltando algo conceitualmente e no código. Você tem o código PHP escutando conexões, mas precisa aceitar uma conexão antes de usá-la.

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

A chamada para socket_accept()blocos. Ele não retornará até que algum programa cliente se conecte ao programa que agora aguarda conexão.

Uma chamada para socket_accept()retorna o soquete real que você usa para se comunicar com o programa remoto. Eu não acho isset()que seja realmente o que você quer, você deveria investigar socket_select()ou algo assim. Quando terminar de se comunicar com o controle remoto, você liga socket_close($ns)e retorna à chamada socket_accept($this->wsRead[0])para aguardar que outro programa remoto se conecte ao seu programa.

Quando seu programa PHP terminar de lidar com as conexões, ele deverá chamar socket_close($this->wsRead[0])para fechar o soquete, o que basicamente diz ao kernel do sistema operacional para parar de ouvir os pacotes TCP SYN recebidos para a porta que você especificar.

Responder2

Acontece que o problema era de várias coisas, principalmente decorrente do meu modem/roteador. Eu uso umMotorola SB6580, que recentemente teve uma atualização de firmware e não foi reinicializado por 10 dias, tornando-o bastante lento, impedindo-me de querer fazer muitas alterações nele.

Oatualização de firmware alterou a página de encaminhamento de portaincluir uma seção de endereço de host remoto externo (o padrão é 0.0.0.0) não é problema aqui, mas outra coisa que eles fizeram quebrou as regras de encaminhamento de porta existentes que eu havia definido.

Eu estava usando um intervalo de portas a serem encaminhadas que não estava funcionando e, ao alterar esse intervalo para 8399 - 8399, ele começou a funcionar novamente. A reinicialização não afetou além de aumentar a velocidade do modem, nem a mudança do protocolo de Ambos para 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

Além disso, ao usar o comando gethostbyname(gethostname()) do PHP no Linux, o endereço retornado é um endereço local de 127.0.1.1, a segunda entrada no arquivo /etc/hosts, que não funcionará para vincular um soquete. $_SERVER['REMOTE_ADDR'] também retorna um aviso: não é possível procurar o host. Poralterando manualmente para o endereço inicial (sub-rede?) (o meu é 192.168.0.101) ou o curinga IPv4 0.0.0.0, o ouvinte de soquete será vinculado corretamente e aceitará conexões externas.

Minha experiência com o roteador e inexperiência com Linux me fez seguir o caminho errado para solucionar problemas do Linux. Depois de perceber que as coisas também não estavam funcionando no Windows 7, fiz as 2 alterações acima e agora tudo funciona como deveria.

informação relacionada