Nginx: forza SSL su un percorso, non SSL su altri


27

Come posso configurare il file conf di Nginx per forzare SSL su uno solo dei percorsi nel mio sito e non SSL su tutto il resto?

Ad esempio, desidero che tutti gli URL in / utente siano https ma tutti gli altri URL siano http.

Per la prima parte ho:

rewrite ^/user(.*) https://$http_host$request_uri?;

Non voglio usare "if". Presumo che trarrebbe vantaggio dall'ordine di funzionamento ma non voglio finire in un ciclo.

Risposte:


38

Nella tua configurazione nginx, dovresti avere due aree "server". Uno per la porta 80 e uno per la porta 443 (non SSL e SSL). Aggiungi semplicemente una posizione nel tuo sito web non SSL per reindirizzare alla tua pagina SSL.

server {
    root /var/www/
    location / {
    }
    location /user {
        rewrite ^ https://$host$request_uri? permanent;
    }
}

inoltrerà tutto il traffico che finisce in / utente al tuo server https: //.

Quindi, nel tuo server 443, fai il contrario.

server {
    listen 443;
    root /var/www/
    location / {
        rewrite ^ http://$host$request_uri? permanent;
    }
    location /user {
    }
}

2
Questo approccio è buono, ma rientra in un paio di insidie comuni , in particolare "Root inside location block" e "Taxing rewrites"
kolbyjack

1
Ho modificato. Sembra a posto? Ho anche eliminato Listen 80 e aggiunto http_host.
pbreitenbach,

Con questa configurazione, la connessione passa da / a ssl / non-ssl quando un utente naviga nelle pagine del sito, ssl for urles è iniziato con /usere non ssl per tutti gli altri url. Di conseguenza, anche l'utente digita esplicitamente https://www.example.com/la barra degli indirizzi del browser, la pagina risultante è http://www.example.com/. C'è un modo per implementare la riscrittura automatica dell'URL tra ssl / non-ssl come ottenuto dalle impostazioni descritte in questa risposta, ma rispettare comunque la richiesta esplicita di ssl se è esplicitamente digitata dall'utente nella barra degli indirizzi? Grazie!
arrivederci,

@goodbyeera yeah. Se l'idea è di forzare gli utenti a utilizzare SSL in determinate aree, possiamo sovrascrivere i loro protocolli lì ma onorarli ovunque altro semplicemente rimuovendo i comandi di riscrittura dalla configurazione del server 443. Naturalmente, ora quando accedono a una parte protetta, continueranno a navigare con SSL quando vanno da qualche altra parte, ma consente alle persone di scegliere di utilizzare SSL fin dall'inizio.
Chuck Dries,

13

Nginx consente di elaborare sia HTTP che HTTPS all'interno dello stesso serverblocco. Pertanto non è necessario duplicare le direttive per entrambi e si può reindirizzare il percorso che si desidera proteggere

server {
  listen 80 default_server;
  listen 443 ssl;
  ... ssl certificate and other configs ...

  location /user {
    if ($scheme = 'http') {
      rewrite ^ https://$http_host$request_uri? permanent;
    }
  }

  ... your basic configuration ...
}

Assicurati di non mettere la ssl onlinea lì perché interromperà il semplice HTTP.

Facoltativamente, puoi reindirizzare tutte le altre richieste da HTTPS a HTTP allo stesso modo:

if ($scheme = 'https') {
  rewrite ^ http://$http_host$request_uri? permanent;
}

AGGIORNAMENTO : come sottolinea gentilmente Alexey Ten nella sezione commenti, controllare schemeogni richiesta non è un'idea brillante. Dovresti seguire il modo dichiarativo di configurare il tuo nginx. In questo caso, dichiarare due blocchi server con reindirizzamenti location, spostare la logica comune in un file separato e includein entrambi. Quindi la risposta di GruffTech è migliore.


2
È inefficace fare lo schema di controllo nginx per ogni richiesta.
Alexey Ten,

1
So che alla domanda è stata data risposta 3 anni fa, ma l'ho trovata faticando a fare quello che ho fatto gradualmente e volevo solo condividere i miei risultati con persone che seguiranno i miei passi.
Hnatt,

1
Bene, dovresti leggere wiki.nginx.org/IfIsEvil
Alexey Ten il

1
@AlexeyTen non è il caso "quando non puoi evitare di usare un if"? Esiste un altro modo per avere la stessa configurazione per HTTP e HTTPS senza duplicare le direttive?
Hnatt,

2
Utilizzare la includedirettiva per le direttive comuni. Qualche duplicazione è OK.
Alexey Ten,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.