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.