Crie um servidor HTTPS com socat

1

Atualmente estou tentando configurar um servidor https de brinquedo com o socat Estou fazendo o seguinte:

Como descrito aqui link

cert()  {
   openssl genrsa -out $1.key 2048
   openssl req -new -key $1.key -x509 -days 3653 -out $1.crt
   cat $1.key $1.crt > $1.pem
}
$ cert server &&  cert client

$ openssl dhparam -out dhparams.pem 2048 # see [1]
$ cat dhparams.pem >> server.pem

[1] link

Em seguida, no terminal # 1 eu corro:

$ socat ssl-l:1443,reuseaddr,fork,cert=server.pem,cafile=client.crt,verify=1 exec:'uptime'

no terminal # 2 eu corro:

$ socat - ssl:localhost:1443,cert=client.pem,cafile=server.crt

E tudo funciona como esperado, eu obtenho o tempo de atividade, mas se eu fizer

$ curl --cert client.pem --cacert server.crt https://localhost:1443
curl: (51) SSL: unable to obtain common name from peer certificate

Ele falha.

Eu admito que meu entendimento sobre HTTPS é um pouco instável, por isso tenho várias perguntas:

  1. Por que falha?
  2. Por que precisamos transferir o certificado do cliente para o servidor? Isso não acontece enquanto eu navego na net, ou não?
por user3165667 09.06.2018 / 20:05

1 resposta

0

Why it fails ?

As instruções que você aparentemente seguiu estão parcialmente incorretas.

$ openssl req -new -key server.key -x509 -days 3653 -out server.crt
//     enter fields... (may all be empty when cert is only used privately)

Os campos que req -new -x509 solicita (pelo menos com o arquivo de configuração upstream 'padrão') são usados como o nome da entidade no certificado criado (ou o CSR sem -x509 ). (Para um certificado auto-assinado, o nome do emissor é o mesmo que o nome do assunto, para que os mesmos dados também apareçam lá.)

Para o servidor HTTPS, para estabelecer que uma conexão atingiu o servidor válido e não um impostor, o certificado do servidor deve ser válido por rfc5280 (assinado por uma CA confiável etc.) E o certificado deve ser emitido para o servidor indicado na URL: o campo Nome Comum no nome da entidade no certificado deve corresponder ao servidor desejado ou à extensão de Nome Alternativo da Entidade (comumente abreviado como SAN e também denominado UCC pela Microsoft ou pessoas influenciadas pela Microsoft) devem estar presentes e conter uma entrada que o faça. Consulte rfc2818 . É por isso que o OpenSSL solicita este campo como:

Common Name (e.g. server FQDN or YOUR name) []:

porque a maioria das pessoas usa URLs que identificam o servidor pelo FQDN, embora haja exceções. Então você precisa responder a essa solicitação com localhost . Oficialmente, o SAN é preferido e implementado por todas as CAs 'reais' (Digicert, GoDaddy, etc) desde cerca de 2000, mas fazer SAN com OpenSSL é um pouco mais trabalhos. Existem muitos Qs já no Stack sobre SAN no OpenSSL; se você precisar e não puder encontrá-los, vou procurar algumas das minhas anotações. Uma exceção é se você quiser usar o Chrome / Chromium: a partir de alguns meses atrás, requer que o certificado tenha SAN (com o nome do servidor correto) e não aceite mais subject.CN. Há também Qs sobre isso; idem.

Observação Os protocolos baseados em SSL / TLS que não sejam HTTPS podem diferir, e um nome de assunto vazio pode, de fato, estar bem, por exemplo, LDPs SNMP DE FTPS.

Why do we need to transfer the client certificate to the server ? This does not happen while I browse the net, or does it ?

Você realmente se refere à internet ou à web? Embora o protocolo SSL / TLS suporte autenticação de cliente via certificado de cliente, poucos servidores da Web na parte segura (HTTPS) da Web usam isso. A maioria dos servidores da Web que precisam autenticar seus clientes usa métodos de nível HTTP - como, por exemplo, as opções oferecidas pelo Stack . Isso permite que eles controlem a interface do usuário e a tornem consistente em todos os navegadores e forneçam instruções, ajuda e suporte, enquanto a interface do usuário para certificados de clientes é implementada por cada navegador ou plataforma de forma diferente e geralmente requer alguma habilidade técnica ou pelo menos inteligência e paciência para usar corretamente, o que a maioria dos websites considera que a maioria dos usuários não pode ou pelo menos não fará.

Os poucos servidores da Web que O uso do certificado de cliente geralmente exige certificados emitidos por uma autoridade de certificação pública e / ou uma terceira parte confiável (como um governo ou banco) ou, às vezes, uma execução da autoridade de certificação ou controlada pelo próprio servidor. O uso de certs de clientes auto-assinados exigiria que os usuários fornecessem seus certs antecipadamente - e esse processo de provisão teria que ser muito seguro, porque qualquer um que conseguisse um certificado falso aceito uma vez seria capaz de fazer conexões fraudulentas por anos.

OTOH quando você 'possui' ambas as extremidades, o administrador do servidor tem um trabalho fácil identificando e confiando no administrador do cliente, e vice-versa. A troca de chaves AIUI OpenVPN usa isso (SSL / TLS com selfsigned ou talvez adhoc-CA certs).

Resposta de bônus: a alteração acima deve fazer a camada TLS da conexão funcionar, mas sua configuração ainda não funcionará como um servidor HTTPS, porque a saída de uptime não é uma resposta HTTP válida. Você precisa de algo que gere cabeçalhos HTTP e conteúdo, praticamente da mesma forma que as 'páginas' CGI sob um servidor web real (para HTTP ou HTTPS).

    
por 16.06.2018 / 10:27