nginx: Como evitar que um bloco de servidores SSL com o nome exato aja como o catchall de todos os SSL

16

Eu tenho um servidor web com muitos servidores virtuais. Apenas 1 deles é SSL. O problema é que, como não há nenhum bloco de servidor catchall escutando SSL, qualquer solicitação https para os outros sites é atendida pelo bloco 1 SSL.

Minha configuração, essencialmente, é assim:

# the catch all
server {
  listen 80 default;

  # I could add this, but since I have no default cert, I cannot enable SSL,
  # and this listen ends up doing nothing (apparently).
  # listen 443; 

  server_name _;
  # ...
}

# some server
server {
  listen 80;
  server_name server1.com;
  # ...
}

# some other server ...
server {
  listen 80;
  server_name server2.com;
  # ...
}

# ... and it's https equivalent
server {
  listen 443;
  ssl on;
  server_name server2.com;
  # ...
}

Agora, como não há ouvinte padrão para 443, uma solicitação como https://server1.com acabará sendo veiculada pelo bloco server2.com https. Isso segue a lógica de server_name em os documentos

If there is no match, a server { ... } block in the configuration file will be used based on the following order:

  1. the server block with a matching listen directive marked as [default|default_server]
  2. the first server block with a matching listen directive (or implicit listen 80;)

Qual é a solução preferida para esse problema? Preciso configurar um certificado fictício para o meu bloco de captura de todos os servidores apenas para que eu possa ouvir em 443 e lidar com as solicitações ruins? Existe algum parâmetro que eu não saiba que força um nome de host exato a coincidir com server ?

    
por numbers1311407 27.10.2011 / 22:24

6 respostas

9

Ideally either I'd like nginx to not serve https at all unless the hostname matches, or for it to redirect to http at the same host.

Nenhum dos dois é possível. A conexão de um cliente que vai para o link não pode ser aceita por nada além de um certificado SSL com "foo.example.com" como um dos seus nomes. Não há oportunidade de redirecionar até que a conexão SSL seja aceita.

Se você configurar cada site para SSL, um usuário que clicar no erro de certificado receberá o site solicitado. Se você configurar um site "catch all" para SSL que forneça apenas uma página de erro e configure a hospedagem virtual baseada em nome para o site que supostamente suporta o SSL, você poderá exibir uma página de erro para os clientes.

A hospedagem virtual SSL e HTTP simplesmente não funciona bem juntos.

    
por 28.10.2011 / 00:43
3

A única maneira de fazer isso é criar um certificado SSL auto-assinado e usá-lo para obter controle sobre solicitações de entrada de https. Você pode criar seu certificado SSL autoassinado em algumas etapas simples descritas neste post .

Digamos que você crie um certificado autoassinado com um nome de arquivo de server.crt. Você então acrescentaria o seguinte na sua configuração nginx:

server {
    listen  443;

    ssl    on;
    ssl_certificate         /etc/nginx/ssl/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/server.key;

    server_name server1.com;

    keepalive_timeout 60;
    rewrite ^       http://$server_name$request_uri? permanent;
}

Você ainda receberá a mensagem de aviso SSL do navegador, mas pelo menos terá controle sobre o que acontece a seguir.

    
por 31.03.2013 / 17:14
2

Adicione um bloco de servidor pega-tudo e retorne o código de status 444. Ele diz ao nginx para fechar a conexão antes de enviar qualquer dado.

server {
    listen 443 default_server ssl;
    server_name _;
    return 444;
}
    
por 17.04.2018 / 19:58
1

Nos dias de hoje, você pode usar a extensão Indicação de nome de servidor TLS (SNI, RFC 6066). O ouvinte HTTPS poderá reconhecer o nome do domínio antes de veicular o certificado apropriado.

Isso significa que você precisará ter certificados para TODOS os seus domínios e, quando o SNI for usado para reconhecer um dos outros domínios, é possível usar o redirecionamento HTTP 301 para a versão HTTP não criptografada, a menos que o nome do servidor corresponda ao único. um que precisa de criptografia.

Mais informações sobre o SNI estão disponíveis na documentação do nginx link

    
por 25.02.2018 / 13:14
0

Mapeie o hostname solicitado para nomes de host válidos no http {} block:

map $ssl_server_name $correct_hostname_example {
  default 0;
  example.com 1;
  www.example.com 1;
}

E, em seguida, no bloco server {} , eliminar as conexões com o nome de host errado:

if ($correct_hostname_example = 0) {
  return 444;
}

Use vários mapas conforme necessário para vários blocos de servidores. A conexão ainda será estabelecida usando um dos seus certificados, mas se este último bloco estiver presente em cada bloco de servidor que serve SSL, então efetivamente você "bloqueará" conexões com nomes de host inválidos. Pode ser necessário apenas no primeiro bloco do servidor, mas adicioná-lo a cada bloco de servidor garantirá que a ordem não seja importante.

A variável $ssl_server_name está presente em nginx 1.7 ou superior.

    
por 02.05.2018 / 20:42
-2

Redirecionar para http:

server {
    listen       443;
    server_name  *.com;
    rewrite        ^ http://$host$request_uri? permanent;
}    

Retorno 404:

server {
    listen       443;
    server_name  *.com;
    return 404;
}    
    
por 02.02.2012 / 13:36

Tags