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.