Evitando o acesso SSL a um servidor Nginx

1

Eu tenho um servidor que executa vários hosts virtuais. Alguns desses sites possuem componentes SSL e outros não. Hoje percebi que, se eu tentar acessar um dos sites não-SSL via https , o Nginx só encontra um host virtual que usa o SSL e tenta renderizá-lo - dando ao familiar "não confiável "aviso antes de fazer isso.

Eu tentei várias soluções, mas nenhuma delas funcionou e esgotou meu conhecimento sobre o Nginx e / ou compreensão de leitura. Idealmente, gostaria de ver um erro 404 se um site for acessado por meio de um protocolo que não é compatível.

Eu tentei várias edições no bloco de servidor default , mas nenhuma funcionou. Também tentei capturar e redirecionar o acesso à porta 443 para esse site específico, mas isso (previsivelmente) também falhou.

Alguém pode me apontar na direção certa?

    
por Rob Wilkerson 06.05.2014 / 17:09

5 respostas

2

Não pode fazer. Sem Server Name Indication (SNI), o nome do host faz parte da carga criptografada. Mesmo com o SNI, um navegador não aceita um redirecionamento de uma URL HTTPS sem antes passar pelo processo de handshake + validação HTTPS.

Se desejar, você pode usar dois endereços IP, um para seu site seguro e outro para os sites não seguros, e apenas ouvir 443 no IP seguro.

    
por 06.05.2014 / 17:12
1

Você pode fazer o que está procurando adicionando uma entrada de servidor com um certificado ssl falso (eu uso auto-assinado para localhost) que retorna o erro desejado. Este deve ser o primeiro bloco do servidor ou, pelo menos, antes de qualquer outro bloco ssl. Note que eu normalmente uso negar todos, mas neste caso adicionei o 404.

server {
        listen       443 ssl default_server;
        server_name    localhost;
        ssl_certificate_key  /etc/ssl/private/localhost.key;
        ssl_certificate /etc/ssl/certs/localhost.crt;
#       deny  all;
        return 404;
}

Para gerar o certificado auto-assinado, você pode usar os seguintes comandos

openssl genrsa 4096 > localhost.key
openssl req -new -sha256 -key localhost.key -subj "/CN=localhost" > localhost.csr
openssl x509 -req -days 3650 -in localhost.csr -signkey localhost.key -out localhost.crt
chmod 600 localhost.key
mv localhost.key /etc/ssl/private/
mv localhost.crt /etc/ssl/certs/
    
por 03.07.2016 / 20:09
1

Eu não acho que nenhuma das outras respostas cobre toda a história:

O que você quer fazer é possível para um servidor, por causa do SNI. No entanto, o nginx, apesar de suportar o SNI, não suporta fazer o que você deseja fazer. O nginx reagirá a um nome SNI incomparável tratando a solicitação como se fosse seu site SSL padrão (e se você não marcou nenhum site SSL como seu padrão, o primeiro site SSL em sua configuração). Isso geralmente resultará no usuário vendo um aviso de aviso de certificado, porque o nome no certificado enviado pelo nginx não corresponde ao nome que o cliente solicitou.

O RFC para SNI especifica que o servidor PODE considerar um nome SNI não reconhecido como fatal:

If the server understood the client hello extension but does not recognize the server name, it SHOULD send an "unrecognized_name" alert (which MAY be fatal).

Até onde eu posso dizer, no entanto, tanto o Apache quanto o nginx continuam com a conexão e a tratam da mesma maneira que tratariam um cabeçalho "Host:" não correspondido ou ausente, que é selecionar o host virtual marcado como padrão para esse endereço: port.

A menos que você tenha adquirido um certificado SSL correspondente a todos os nomes de domínio possíveis que o cliente possa usar ao contatar seu servidor, não será possível impedir que o usuário veja um aviso sobre um certificado inválido antes de continuar. Mesmo que você faça um redirecionamento assim que eles chegam ao site, isso só será processado depois que o certificado inválido for aceito.

Atualização de 2017: como é fácil obter certificados SSL gratuitos para todos os seus domínios agora, você pode obter certificados SSL para todos os seus domínios, mesmo que não pretenda veicular conteúdo real com HTTPS, apenas para garantir que quaisquer redirecionamentos ou mensagens de erro funcionarão sem nenhum aviso sobre certificados incompatíveis.

    
por 13.07.2015 / 14:24
0

Não é possível com o NGinx (ou, por padrão, com qualquer outra coisa).

Se você não se importa com clientes mais antigos (como os que usam o Chrome ou o IE no Windows XP) e você está bem suportando apenas clientes que usam a extensão SNI do protocolo TLS, use haproxy na frente nginx para fazer isso.

Outra solução seria colocar todos os sites não-SSL em um endereço IP completamente separado que não escute na porta https.

    
por 06.05.2014 / 19:29
0

Não sei exatamente o que você tentou, mas se você tem suporte a SNI, um método é formar um resumo:

server {
    listen [::]:443 default_server ssl;
    listen 443 default_server ssl;
    server_name _;
    return 444;
}

    server {
    listen  [::]:443 ssl;
        listen  443 ssl;
    server_name  ssl.site.net;
    ssl_certificate      your.crt;
    ssl_certificate_key  your.key;
....etc...

que descarregará servidores não correspondentes (a partir de uma configuração que eu usava para usar, atualmente não aplico grão-de-sal) Como outros apontaram, não acredito você pode fazer um redirecionamento dessa maneira, apenas uma queda.

Para suporte não-SNI (leia-se: legado) você sempre pode obter um certificado barato para captura de curingas, então você poderá manipular todas as conexões e redirecionar como desejar sem problemas.

Edit: pensando duas vezes, se bem me lembro, porque nginx suporta SNI, mesmo que um cliente que não suporte SNI conecte, ele ainda causará nginx em return 444 ao tentar combinar um certificado para enviar ... pensamentos?

    
por 06.05.2014 / 19:56

Tags