Listener de netcat do Linux (nc -l) suspenso

0

No meu Raspberry Pi 3 Terminal (Linux) digitei o seguinte e tecle Enter :

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/' | nc -l 2345

O Raspberry Pi 3 faz parte da minha rede doméstica com um endereço fixo de 192.168.0.8. Então, no meu mac eu digitei o seguinte no meu navegador (Chrome) e tecle Enter :

192.168.0.8:2345

Eu posso ver a solicitação GET do navegador no meu Terminal Linux (Raspberry Pi), mas o ouvinte nc fica preso e não envia a resposta (a mensagem de redirecionamento HTTP 302) para o navegador.

Somente quando eu parar o programa nc pressionando Ctrl + C , o navegador recebe a mensagem de resposta e exibe o site https://www.eff.org .

Alguém tem uma idéia do porque o ouvinte nc fica preso em vez de enviar a resposta e fechar a conexão?

    
por Thomas Grusz 04.12.2017 / 06:17

1 resposta

0

Eu repliquei seu problema. Quando me conecto com outro nc em vez de um navegador, vejo a resposta sendo enviada imediatamente. Acho que o seu navegador também recebe a resposta, mas como nc não encerra a conexão, o navegador não sabe tudo e não há problema em continuar com o redirecionamento.

(Nota: durante meus testes, eu precisei do \r\n final na resposta de nc para redirecionar com sucesso o meu navegador, portanto, todos os meus exemplos usam essa correção.)

Editar: correção simples

Aqui eu encontrei o seguinte:

HTTP requests and HTTP responses use a generic message format of RFC 822 for transferring the required data. This generic message format consists of the following four items.

  • [...]
  • [...]
  • An empty line (i.e., a line with nothing preceding the CRLF) indicating the end of the header fields
  • [...]

Portanto, a sua resposta deve ser:

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n\r\n' | ...

Depois de receber isso, seu navegador deve continuar com o redirecionamento, encerrando a conexão com nc em seu próprio nome. No início de dezembro de 2017, funciona com o Opera e o Vivaldi; não funciona com o Firefox, Chrome ou Safari, para o qual você pode precisar de outra correção (veja abaixo).

Resposta original, agora inferior (ainda pode ser útil para comunicação não HTTP com nc )

De acordo com esta resposta no Server Fault , você precisa usar -c , -q ou opção semelhante, dependendo da nc implementation.

No meu Debian eu tenho a versão -q capaz instalada. Então

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -q 0 -l -p 2345

funciona bem (note que também preciso de -p para especificar porta). A explicação é:

-q seconds
after EOF on stdin, wait the specified number of seconds and then quit. If seconds is negative, wait forever (default).

Se o seu nc não tiver uma opção adequada, a solução alternativa será detectar a comunicação de um cliente e eliminar toda a linha de comando. Um exemplo que funciona no meu Debian, bash :

printf 'HTTP/1.1 302 Moved\r\nLocation: https://www.eff.org/\r\n' | nc -l -p 2345 | { read foo; sleep 1; kill 0; }

Ao executar um canal, bash coloca cada processo em um único grupo de processos; kill 0 envia sinais para todo o seu grupo de processos. Dessa forma, nc é eliminado em cerca de 1 segundo depois que qualquer solicitação for recebida, acionando read .

    
por 04.12.2017 / 10:00