2013-08-19 9 views
16

Ho bisogno di utilizzare Nginx come proxy SSL, che inoltra il traffico a back-end diversi a seconda del sottodominio.proxy nginx basato su host quando si utilizza https

Mi sembra che dovrei definire più sezioni "server {" ma che non funziona correttamente per SSL. In questo modo avrei sempre elaborato il protocollo SSL nel primo host virtuale in quanto il nome del server è sconosciuto fino a quando non elabori il traffico https.

Scenario:

  • Un indirizzo IP
  • One SSL jolly jolly
  • più backend che deve essere letta come la seguente:

    https://one.mysite.com/ -> http://localhost:8080 
    https://two.mysite.com/ -> http://localhost:8090 
    

Nginx dice " se "è il male: http://wiki.nginx.org/IfIsEvil, ma che altro posso fare?

Ho provato questo, ma non funziona, ottengo un errore 500 ma nulla nei log degli errori.

server { 
    listen 443; 
    server_name *.mysite.com; 

    ssl on; 
    ssl_certificate ssl/mysite.com.crt; 
    ssl_certificate_key ssl/mysite.com.key; 

    location/{ 
     if ($server_name ~ "one.mysite.com") { 
      proxy_pass http://localhost:8080; 
     } 
     if ($server_name ~ "two.mysite.com") { 
      proxy_pass http://localhost:8090; 
     } 
    } 

Qualcuno è riuscito a realizzare questo con Nginx? Qualsiasi aiuto/alternative, link, sarebbe molto apprezzato.

risposta

27

ho trovato la soluzione, che è sostanzialmente quella di definire le opzioni SSL e il certificato SSL di fuori del blocco "server":

ssl_certificate ssl/mysite.com.crt; 
ssl_certificate_key ssl/mysite.com.key; 
ssl_session_timeout 5m; 
ssl_protocols  SSLv3 TLSv1; 
ssl_ciphers   ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+EXP; 
ssl_prefer_server_ciphers on; 

server { 
    listen 80; 
    server_name *.mysite.com; 
    rewrite^https://$host$request_uri? permanent; 
} 
server { 
    listen 443 ssl; 
    server_name one.mysite.com; 

    ssl on; 

    location/{ 
     proxy_pass http://localhost:8080; 
    } 
} 
server { 
    listen 443 ssl; 
    server_name two.mysite.com; 

    ssl on; 

    location/{ 
     proxy_pass http://localhost:8090; 
    } 
} 

cose fondamentali:

  • "SSL su;" è l'unica cosa che deve essere all'interno dei blocchi "server" che ascoltano in https, puoi metterlo anche fuori, ma cosa renderà i blocchi "server" che ascoltano nella porta 80 per usare il protocollo https e non l'http previsto.
  • Poiché "ssl_certificate", "ssl_ciphers: e altri" ssl_ * "si trovano all'esterno del blocco" server ", Nginx esegue lo scaricamento SSL senza un nome_server. Che è ciò che dovrebbe fare, poiché la decrittografia SSL non può avvenire in base a .. alcun nome host, come in questa fase l'URL è crittografato
  • JAVA e arricciare non riescono a lavorare adesso non c'è nome_server - partita di perdere ospite
+7

Grazie, questa informazione mi è stata di grande aiuto. FYI: Ho scoperto che quando usi 'listen 443 ssl;' anche tu non devi fare 'ssl on;' perché nginx accenderà la modalità SSL per te. Fonte: http://nginx.org/en/docs/http/ngx_http_core_module.html#listen – Tom

1

in base allo http://www.informit.com/articles/article.aspx?p=1994795, si dovrebbero infatti avere due sezioni "server", con due diversi nomi di server. In ognuno di essi, dovresti includere le tue direttive ssl_ *.

+0

C'è un problema con quello, lascia che ti spieghi con un esempio: se hai hai due "server" sezioni con SSL in ascolto nella porta 443 Nginx eseguirà la decript SSL usando il primo virtualhost, perché ancora non sa quale dominio si possiede. Una volta che il dominio può essere abbinato eseguirà le direttive dell'host virtuale giusto ma la decript SSL avverrà nell'host virtuale sbagliato. JAVA e arricciatura (probabilmente più client SSL) non riusciranno perché non vi è corrispondenza tra il nome host e il dominio effettivamente utilizzato. –

+1

Questo è ciò che corregge SNI. La maggior parte dei browser moderni lo supportano ora, il che rende la vita molto più semplice. – rubyruy

4

la risposta breve è quella di utilizzare Server Name Indication.. Questo dovrebbe funzionare di default nei browser comuni e cURL.