Nginx com ssl_verify_client = on não falha no handshake TLS

1

Eu tenho o Nginx 1.10 com ssl_verify_client = on . Tudo funciona bem, exceto que o servidor conclui o handshake TLS e passa a analisar os cabeçalhos, mesmo que o certificado não tenha sido enviado pelo cliente.

Pode ser verificado enviando solicitação http sem certificado de cliente e cabeçalho http extremamente grande, nginx retorna " 400 Cabeçalho de solicitação ou cookie muito grande ".

De acordo com nosso auditor de segurança, o servidor deve falhar no handshake TLS, porque analisar os cabeçalhos "aumenta a possível superfície de ataque.

Minha configuração do nginx:

server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    server_name myserver.com;

    ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem;

    ssl_verify_client on;
    ssl_client_certificate /etc/nginx/ssl/ca.pem;

    location / {
            proxy_pass       http://127.0.0.1:8001;
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
    } }
    
por jhexp 25.04.2017 / 18:51

1 resposta

0

Eu acho que você precisa exigir o uso de SNI para evitar a inspeção de cabeçalho. O Nginx deve determinar se um bloco do servidor corresponde à solicitação e, para isso, precisa de um nome de host. Ele pode obter um nome de host do SNI durante o handshake de TLS, mas se o SNI não for usado, ele precisará ler as informações do host nos cabeçalhos http.

Você pode exigir o uso de SNI configurando um manipulador de bloco de servidor padrão para solicitações de cliente não-SNI que recusam essas conexões. Para fazer isso, remova a diretiva default_server do bloco principal do servidor ssl e adicione um servidor padrão explícito acima dela que 1) escuta em 443, 2) corresponde a solicitações sem nome de host e 3) sempre retorna 444. Exemplo:

server {
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;
  server_name   "";

  ssl_ciphers aNULL;
  ssl_certificate /path/to/dummy.crt;
  ssl_certificate_key /path/to/dummy.key;

  return 444;
}

server {
  listen 443 ssl;
  listen [::]:443 ssl;

  server_name myserver.com;

  ssl_certificate /etc/letsencrypt/live/myserver.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/myserver.com/privkey.pem;

  ssl_verify_client on;
  ssl_client_certificate /etc/nginx/ssl/ca.pem;

  location / {
        proxy_pass       http://127.0.0.1:8001;
        proxy_set_header Host      $host;
        proxy_set_header X-Real-IP $remote_addr;
} }

O servidor padrão, então, manipula todas as solicitações SSL que não usam o SNI. O retorno 444 é um código não padrão do nginx que fecha a conexão. Essa estrutura também fecha uma possível falha de segurança na qual o certificado de um servidor padrão pode expor recursos de maneiras inesperadas. Agora, o nginx só processará solicitações que usem SNI e que tenham um nome de host correspondente a um de seus outros blocos de servidor.

    
por 26.04.2017 / 21:02