Nginx SSL Preread esporadicamente obtém solicitações onde nenhum nome de servidor é extraído

Nginx SSL Preread esporadicamente obtém solicitações onde nenhum nome de servidor é extraído

estou usando omódulo de fluxo nginxpara aproveitar o nginx como um proxy reverso tcp na frente do s3. Recentemente, precisei adicionar lógica para acomodar um upstream adicional. Para fazer isso, optei por fazer uso da lógica condicional por meio da variável de mapa $ssl_preread_server_name.ssl_prereadpermite que o nginx extraia o nome do servidor da mensagem ClientHello sem encerrar o SSL. Você pode ver a lógica abaixo:

map $ssl_preread_server_name $https_cname {
    s3.amazonaws.com https_s3_backend;
    aws-service-2.amazonaws.com aws-service-2-backend;
}
upstream https_s3_backend {
    server s3.amazonaws.com:443;
}
upstream aws_service_2_backend {
    server aws-service-2.amazonaws.com:443;
}

server {
    listen       443;
    proxy_pass $https_cname;
    ssl_preread on;
}

Quando chega uma solicitação com o nome de servidor s3.amazonaws.com, a solicitação é enviada para s3. Quando chega uma solicitação com o nome de servidor aws-service-2.amazonaws.com, a solicitação é enviada para aws-service-2.

Isso funciona na maioria das vezes. Mas, às vezes, há erros no log de erros que indicam que, de alguma forma, as solicitações estão atingindo os servidores nginx na porta 443 sem nenhum nome de servidor.

[error] ... no host in upstream "", client: x.x.x.x, server: 0.0.0.0:443

Quando adiciono uma instrução padrão na lógica do mapa, esses erros desaparecem. Quais são as possíveis explicações para algumas solicitações s3 recebidas sem nenhum nome de servidor extraído? A única maneira de as solicitações atingirem essas caixas nginx atualmente é se alguém fizer uma operação s3.

Responder1

Não estou familiarizado com o Amazon S3 como tal, mas acho que o problema é que as solicitações são geradas sem definir o nome do servidor (consulteIndicação do nome do servidor).

Eu experimentei o mesmo problema em uma configuração semelhante e consegui reproduzir isso, por exemplo, no OpenSSL v1.0.2p conectando-me sem definir explicitamente o parâmetro servername:

openssl s_client -connect <mydomain>:<some_port> -showcerts

Essa solicitação apenas me forneceria o certificado do servidor padrão e não respeitaria o nome de domínio que forneci na URL. Por outro lado, ao especificar o parâmetro servername:

openssl s_client -connect <mydomain>:<some_port> -showcerts -servername <mydomain>

.. a solicitação é enviada para o domínio correto e o certificado correto é retornado.

Ao acessar o mesmo servidor da web com curl ou por meio de navegadores da web, não observo esse problema, suspeito que a implementação no navegador da web e no curl esteja definindo o nome do servidor extraindo-o da URL em segundo plano, enquanto alguns aplicativos do lado do cliente, como como openssl trata-o como um parâmetro opcional.

Então, no seu caso, acho que você precisa:

  • descubra onde as solicitações são geradas
  • veja se existe uma opção para definir o nome do servidor

informação relacionada