nginx - Come impedire l'elaborazione delle richieste con nomi di server non definiti con HTTPS

15

Come evitare che nginx elabori una richiesta con un nome server indefinito utilizzando il protocollo https.

La seguente configurazione rende questo lavoro per normali richieste http. Reimposta la connessione per le richieste con host headers vuoto che equivale a server_name nella configurazione di nginx:

server {
    listen      80;
    server_name "";
    return      444;
}

Aggiornato per chiarezza:

Il server, tuttavia, fornisce html del blocco server di supporto ssl predefinito quando viene inviata una richiesta su https con host header vuota. Come può essere evitato?

Vorrei ottenere il comportamento esatto delle richieste http con host header vuoto - non html servito, reset della connessione (restituisce 444).

Quale sarebbe il modo corretto per bloccare tali richieste https e ottenere il comportamento menzionato anche per le connessioni https? (Vorrei evitare di usare il certificato SSL corretto per questo, poiché questo potrebbe solo suggerire agli spammer il vero dominio del server.)

Aggiornamento 13.03.2015

Mettere un haproxy davanti a nginx con l'impostazione

strict-sni

risolto completamente il problema.

    
posta binaryanomaly 14.04.2014 - 23:15
fonte

4 risposte

11

L'ho risolto generando un certificato falso che non rivela il nome di dominio e aggiungendolo come predefinito all'inizio della configurazione:

server {
    listen 443 default;
    server_name     _;

    ssl     on;
    ssl_certificate         /path/to/fake.crt;
    ssl_certificate_key     /path/to/fake.key;

    return 403;
}

E sì, richiede un nginx con supporto SNI (controlla nginx -V ).

Seguire su: Come creare un certificato SSL autofirmato per scopi di test     
risposta data 12.12.2015 - 08:13
fonte
9

A causa della natura di come funziona SSL, l'handshake SSL / TLS viene eseguito prima che il nome host previsto sia dato al server web. Ciò significa che il certificato (primo) predefinito viene utilizzato quando si tenta di accedere al sito, indipendentemente dal nome di dominio utilizzato.

Questo vale sia per Apache che per Nginx.

Dal Wiki di Apache :

As a rule, it is impossible to host more than one SSL virtual host on the same IP address and port. This is because Apache needs to know the name of the host in order to choose the correct certificate to setup the encryption layer. But the name of the host being requested is contained only in the HTTP request headers, which are part of the encrypted content. It is therefore not available until after the encryption is already negotiated. This means that the correct certificate cannot be selected, and clients will receive certificate mismatch warnings and be vulnerable to man-in-the-middle attacks.

Dalla documentazione di nginx :

With this configuration a browser receives the default server’s certificate, i.e. www.example.com regardless of the requested server name. This is caused by SSL protocol behaviour. The SSL connection is established before the browser sends an HTTP request and nginx does not know the name of the requested server. Therefore, it may only offer the default server’s certificate.

Come puoi risolvere questo problema?

La soluzione più semplice è utilizzare indirizzi IP separati per ogni sito che desideri proteggere.

Se ciò non è possibile, potrebbe essere possibile risolvere il problema utilizzando Indicazione del nome del server (SNI, RFC 6066 ). Ciò consente a un browser di passare il nome di dominio al server durante l'handshake.

Sia Nginx che Apache supportano SNI. Puoi scoprire di più su nginx SNI nella documentazione .

Vale la pena notare che SNI può essere utilizzato solo per i nomi di dominio e non per gli indirizzi IP. Quando si configura il server Web è necessario adottare ulteriori precauzioni per risolvere il problema, pertanto qualsiasi richiesta relativa all'IP viene gestita correttamente.

Only domain names can be passed in SNI, however some browsers may erroneously pass an IP address of the server as its name if a request includes literal IP address. One should not rely on this.

Il Wiki di Apache ha ulteriori informazioni sull'implementazione di SNI . Ma anche la loro documentazione consiglia che questa soluzione non è perfetta.

Using name-based virtual hosts with SSL adds another layer of complication. Without the SNI extension, it's not generally possible (though a subset of virtual host might work). With SNI, it's necessary to consider the configuration carefully to ensure security is maintained.

Detto questo, puoi vedere come questa configurazione non è semplice come i normali host virtuali. Per trovare una soluzione al tuo problema, dovremmo conoscere maggiori dettagli sulla tua configurazione e il comportamento previsto quando viene inviata una richiesta solo IP.

Generalmente, per "bloccare" un dominio non configurato o una richiesta IP, devi configurarlo come sito predefinito e quindi visualizzare un errore, reindirizzare, uscire, ecc.

    
risposta data 26.04.2014 - 12:21
fonte
4

Se capisco che vuoi negare le richieste HTTP, che non contengono un'intestazione Host, anche se queste richieste si trovano all'interno di una connessione SSL (ad esempio https-Requests). Si tratta di richieste HTTP / 1.0 di vecchio stile, HTTP / 1.1 richiede un'intestazione Host ma anche la maggior parte dei client HTTP / 1.0 ne invia uno. Il blocco di questi client può essere fatto con:

    if ( $http_host = '' ) {
            return 444;
    }

Ma questo non aiuta se il client usa un'intestazione Host con junk o l'indirizzo IP al suo interno. Quindi sarebbe meglio verificare che l'intestazione host contenga i valori attesi (come bonus aiuta anche contro gli attacchi di rebinding DNS), ad es.

    if ( $http_host !~* ^(example\.com|www\.example\.com)$ ) {
            return 444;
    }
    
risposta data 26.04.2014 - 16:51
fonte
0

Ho usato il metodo simile a @int_ua menzionato, ma un po 'complicato.

Ho configurato il mio nginx per utilizzare RSA e ECDSA come metodo di autenticazione TLS, ma ho emesso un certificato DSA per il server predefinito.
Poiché non esiste una suite di crittografia disponibile, l'handshake TLS fallirebbe prima di servire qualsiasi pagina.
Penso che avrebbe lo stesso risultato di quello che hai configurato (HAproxy strict-sni) e credo che il mio metodo avrebbe prestazioni migliori.

Puoi visualizzare il risultato della mia configurazione:

Invalid SNI: https://207.246.127.148/
   (You can configure your hosts to this IP address and view the result as well)
Valid SNI: https://cloud.jemmylovejenny.tk/
   The Valid SNI link points to the same IP address as above

Vorrei dare la mia configurazione qui:

Configurazione SSL
(Ho usato un codice openssl uguale cipher in modo che le cifre siano un po 'strane ... Puoi anche rimanere la tua configurazione , ma ricorda che non contengono alcuna crittografia DSS!)

    #Protocols
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
    #
    #Key Exchange
    ssl_ecdh_curve X25519:P-256:P-384:P-224:P-521;
    ssl_dhparam /var/SSL/DH-param.pem;
    #
    #Cipher Suites
    ssl_ciphers "[TLS_AES_128_GCM_SHA256|TLS_CHACHA20_POLY1305_SHA256]:[TLS_AES_256_GCM_SHA384|TLS_AES_128_CCM_8_SHA256|TLS_AES_128_CCM_SHA256]:[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|DHE-RSA-CHACHA20-POLY1305]:[ECDHE-ECDSA-AES256-GCM-SHA384|ECDHE-RSA-AES256-GCM-SHA384]:[ECDHE-ECDSA-AES128-SHA|ECDHE-RSA-AES128-SHA]:[ECDHE-ECDSA-AES256-SHA|ECDHE-RSA-AES256-SHA]:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA";
    ssl_prefer_server_ciphers on;


Configurazione server predefinita

##
# General
##
# Listen
listen 8080 default_server;
listen 8443 ssl spdy http2 default_server;
#
# Server Name
server_name _;

##
# SSL Settings
##
#
# Certificate
#  DSA
ssl_certificate /var/SSL/certificates/DEFAULT.dsa.crt;
ssl_certificate_key /var/SSL/keys/DEFAULT.dsa.key;

root /var/www/html/nginx/;


La chiave DSA viene generata da OpenSSL e il certificato viene emesso dalla mia PKI personale. Puoi usare questo certificato se vuoi.
(Questo certificato non verrebbe mai inviato dal server nginx, quindi tutto questo certificato, inclusi keylength e periodo valido non ha senso)

Certificato:

-----BEGIN CERTIFICATE-----
MIIFrjCCBJagAwIBAgIUHVfGi/SP2d/B4vbxZSKSVEpSoGEwDQYJKoZIhvcNAQEL
BQAwgYExCzAJBgNVBAYTAkNOMSMwIQYDVQQKDBpKZW1teUxvdmVKZW5ueSBQS0kg
U2VydmljZTEeMBwGA1UECwwVcGtpLmplbW15bG92ZWplbm55LnRrMS0wKwYDVQQD
DCRKZW1teUxvdmVKZW5ueSBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwMTAx
MDAwMDAwWhcNMTkxMjMxMjM1OTU5WjAiMSAwHgYDVQQDDBdERUZBVUxUIFNTTCBD
RVJUSUZJQ0FURTCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCVcFt4xWkIBtiN/Xay
O7Ls5EjBCFckvyBQpRJ5wmjrxepQbUK9xmiXmpkXOsEYHy14UQXswzKPBWiHsNDs
8apFoGAvjBxSg9Y07wd5VBnhBGvqd0VmD92eKAFW1sZZVoSrLwizfIde0sj9bZCD
KICt/0jdz0QGBZzXTtd4MOcjUQIVAPD9cVtRAdD6al8v/SV2YVQHZmafAoGBAI+A
tCrjcvK0PFILpwpGD/3gJI8o2oxKoPjjE3SM9b4mrN/2ixEGgGiXHOrEyZ7IgSjf
1Z6X2nuN+IgsNdJAZjNbnuacxbu4z5FmnO6i9IRXEqtKNzONeHJSG+7w7zUPfsPT
8sTxHU0Z5ynjiLz4GcnO5LVcMNbf2uEsl41fObB4A4GEAAKBgHOFoU8xns0qMFLz
h3ZiYScs2Rznw7xeo2HbM8hGI9zKWRoV49f9V2vHFjdPSLkPbzgoSqOxmGD7UZep
W0TcsSPVKIuKBw07vvJkpUG8U71mcedNN5+fNbIcgjKdTlIIbrEFYRFG6zrIcZ3/
WArPchw3RC+SRrBXW8+27T4+0PMao4IB5TCCAeEwHwYDVR0jBBgwFoAU4BPpj9H7
K19wMi69RQ9t6BLyNOcwHQYDVR0OBBYEFFrpB6sLpQwodD7KWPssHj0fkqjCMAkG
A1UdEQQCMAAwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
BgEFBQcDAjBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3Jscy5wa2kuamVtbXls
b3ZlamVubnkudGsvU0hBMlNlY3VyZVNlcnZlckNBLmNybDCBggYDVR0gBHsweTBt
BglghkgBpKInAQIwYDAtBggrBgEFBQcCARYhaHR0cHM6Ly9wa2kuamVtbXlsb3Zl
amVubnkudGsvY3BzMC8GCCsGAQUFBwICMCMaIWh0dHBzOi8vcGtpLmplbW15bG92
ZWplbm55LnRrL3JwYTAIBgZngQwBAgEwgYYGCCsGAQUFBwEBBHoweDAtBggrBgEF
BQcwAYYhaHR0cDovL29jc3AucGtpLmplbW15bG92ZWplbm55LnRrMEcGCCsGAQUF
BzAChjtodHRwOi8vY2FjZXJ0cy5wa2kuamVtbXlsb3ZlamVubnkudGsvU0hBMlNl
Y3VyZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IB
AQCtgVPw2KLT/ntVYZE8AL71C0R1gsn9MKoqD6asaM16qK60G7YK8qC2I/5wWXAr
+zVeegvU/73qWq66DnIF333uZz3aeaXoIEfDRcfePVzWTG62cO2fPyTWyIczaPFf
NqQqoukM3UeBM0yIRSbiyRAFoyz0TWhdgSDXGrG+X5EvUnH6J+umnt/PNGaNnz1f
eXJBh79UnmCpMI6rW+7UG4F60xxQ/RQeRZZt//Ze5YzIDRjUQpXQ1a+9cHuPT8EY
Ft4xe4q5FgMVTBsu1zAfA/ViSDlHWAO8oioKkYDYHqYmLT6ERSoXNVK6WbNh4mem
AaF8T8DKQTHD5GKFBJSSkvF7
-----END CERTIFICATE-----


Chiave:

-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQCVcFt4xWkIBtiN/XayO7Ls5EjBCFckvyBQpRJ5wmjrxepQbUK9
xmiXmpkXOsEYHy14UQXswzKPBWiHsNDs8apFoGAvjBxSg9Y07wd5VBnhBGvqd0Vm
D92eKAFW1sZZVoSrLwizfIde0sj9bZCDKICt/0jdz0QGBZzXTtd4MOcjUQIVAPD9
cVtRAdD6al8v/SV2YVQHZmafAoGBAI+AtCrjcvK0PFILpwpGD/3gJI8o2oxKoPjj
E3SM9b4mrN/2ixEGgGiXHOrEyZ7IgSjf1Z6X2nuN+IgsNdJAZjNbnuacxbu4z5Fm
nO6i9IRXEqtKNzONeHJSG+7w7zUPfsPT8sTxHU0Z5ynjiLz4GcnO5LVcMNbf2uEs
l41fObB4AoGAc4WhTzGezSowUvOHdmJhJyzZHOfDvF6jYdszyEYj3MpZGhXj1/1X
a8cWN09IuQ9vOChKo7GYYPtRl6lbRNyxI9Uoi4oHDTu+8mSlQbxTvWZx5003n581
shyCMp1OUghusQVhEUbrOshxnf9YCs9yHDdEL5JGsFdbz7btPj7Q8xoCFFfXTHSl
C7tdLJO9vQFcyKMhU8TU
-----END DSA PRIVATE KEY-----
    
risposta data 02.08.2018 - 10:41
fonte

Leggi altre domande sui tag