O comando openssl s_client sempre diz 400 Solicitação incorreta

5

Estou tentando testar um servidor que está funcionando normalmente no navegador da Web, com a opção openssl s_client, conectando-o diretamente usando o openssl retorna o 400 Bad Request:

openssl s_client -servername example.com -connect example.com:443 -tls1
(some information about the certificate)

GET / HTTP/1.1 
(and the error occurs **immediately** - no time to include more headers like Host:)

Importante: Eu já tentei colocar o cabeçalho Host:, a coisa é que quando eu corro GET, o erro ocorre imediatamente, deixando-me sem chance de incluir mais cabeçalhos. Substitua example.com pelo meu host ...

    
por Luciano Andress Martini 13.06.2017 / 20:21

4 respostas

12

De acordo com o link , meu comando era:

openssl s_client -crlf -connect www.pgxperts.com:443

onde -crlf significa, de acordo com a ajuda do comando openssl,

-crlf - converte LF do terminal em CRLF

Então eu poderia inserir comandos de múltiplas linhas e nenhuma "solicitação incorreta" como resposta após a primeira linha de comando mais.

    
por 05.07.2017 / 11:06
3

Pelo que eu posso ver, o 400 Bad Request provavelmente está relacionado ao uso do HTTP / 1.1 em sua linha GET.

Você adicionou um cabeçalho "Host:" após a solicitação GET? O RFC afirma que, para HTTP / 1.1, é necessário um cabeçalho de host:

link

19.6.1.1 Changes to Simplify Multi-homed Web Servers and Conserve IP Addresses

The requirements that clients and servers support the Host request- header, report an error if the Host request-header (section 14.23) is missing from an HTTP/1.1 request, and accept absolute URIs (section 5.1.2) are among the most important changes defined by this specification.

    
por 14.06.2017 / 02:28
1

OK teve a mesma coisa e demorou um pouco para descobrir.

Não consigo encontrar uma maneira de enviar várias linhas na solicitação ao usar s_client interativamente. Ele sempre envia a solicitação imediatamente assim que você entra na primeira linha. Se alguém souber como contornar isso, por favor me avise!

Editar : vejo Wei Ele postou a maneira de fazer isso - use o -crlf flag mas deixando esta resposta aqui como um método alternativo.

Nesse meio tempo, como sugerido por jww, você precisa usar echo para isso:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client ...

A próxima questão é que, por padrão, o openssl fecha a conexão quando o arquivo de entrada é fechado. O que acontece imediatamente ao usar echo como este. Então você não tem tempo para ver a resposta e, em vez disso, apenas vê a saída DONE! : - (

Você pode adicionar um sleep ao comando echo para contornar isso (note que os colchetes são importantes):

(echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"; sleep 10) | openssl s_client ...

Ou, melhor que isso, você pode usar a opção -ign_eof para deixar a conexão aberta:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -ign_eof ...

Ou melhor ainda, se você estiver preocupado apenas com as respostas HTTP, use a opção -quite , que oculta a maior parte do ruído TLS e também define essa opção -ign_eof para você:

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | openssl s_client -quiet ...
    
por 03.07.2017 / 02:45
1

Você pode enviar uma solicitação GET com o OpenSSL:

openssl s_client -quiet -connect cdn.sstatic.net:443 <<eof
GET /stackexchange/js/universal-login.js HTTP/1.1
Connection: close
Host: cdn.sstatic.net

eof

Note que você também pode usar "HTTP / 2", mas tenha cuidado porque alguns servidores (por exemplo, github.com) não são compatíveis.

    
por 24.01.2018 / 00:55