Vraag Hoe te dwingen of door te sturen naar SSL in nginx?


Ik heb een aanmeldingspagina op een subdomein zoals: https://signup.example.com

Het zou alleen via HTTPS toegankelijk moeten zijn, maar ik ben bang dat mensen er op de een of andere manier via HTTP op zullen stuiten en een 404 krijgen.

Mijn html / server-blok in nginx ziet er als volgt uit:

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

Wat kan ik toevoegen zodat mensen die naar toe gaan http://signup.example.com word omgeleid naar https://signup.example.com ? (Ter info: ik weet dat er Rails-plug-ins zijn die kunnen forceren SSL maar hoopte dat te vermijden)


210
2018-03-22 18:45


oorsprong


Mogelijk duplicaat van Hoe kan ik in Nginx alle http-verzoeken naar https herschrijven met behoud van het subdomein? - Nasreddine


antwoorden:


Volgens nginx valkuilen, het is iets beter om de onnodige opname, gebruik weg te laten $request_uri in plaats daarvan. Voeg in dat geval een vraagteken toe om te voorkomen dat nginx query-argumenten verdubbelt.

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

137
2018-03-22 19:22



Of, volgens de site die u heeft gelinkt, "BETER": return 301 http://domain.com$request_uri; - nh2
Een commentaar. de $ server_name $ pakt de eerste servernaam variabele. Dus onthoud dit als u niet-FQN-namen in uw configuratie hebt - engineerDave
@ nh2 Dit is een ander geval van onjuiste documentatie sinds het gebruik return 301... veroorzaakt een "te veel omleidingen" -fout terwijl de herschrijfmethode daadwerkelijk werkt. - Mike Bethany
Dat is nu gedocumenteerd als "ook SLECHT". @MikeBethany return 301 werkt, tenzij (ik veronderstel) u het triggert ook voor correcte URL's, door te luisteren op beide poorten (bijvoorbeeld van config. die het probleem veroorzaakt: take serverfault.com/a/474345/29689's eerste antwoord en weglaten van de if). - Blaisorblade
Ik vraag me af wat er in de loop der jaren is veranderd en of dit andere antwoord beter is: serverfault.com/a/337893/119666 - Ryan


De beste manier zoals beschreven in de officiële how-to is door de return richtlijn:

server {
    listen      80;
    server_name signup.mysite.com;
    return 301 https://$server_name$request_uri;
}

237
2017-09-03 23:50



kortste antwoord en werkte perfect in mijn geval - mateusz.fiolka
Dit wordt over het algemeen aanbevolen omdat het een resultaat oplevert 301 Moved Permanently (uw links zijn permanent verplaatst) en herschreven - sgb
Dit werkt niet omdat het een "te veel omleidingen" -fout veroorzaakt, zelfs als je hebt ingesteld proxy_set_header X-Forwarded-Proto https; - Mike Bethany
@MikeBethany definieer je listen 443; in hetzelfde blok? - Joe B
Dit zou het geaccepteerde antwoord moeten zijn. - sjas


Dit is de juiste en meest efficiënte manier als u alles in één serverblok wilt bewaren:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

Al het andere hierboven, met gebruik van "herschrijven" of "als ssl_protocol" enz. Is langzamer en erger.

Hier is hetzelfde, maar nog efficiënter, door alleen het herschrijven van het http-protocol uit te voeren, vermijdt het om bij elk verzoek de $ scheme-variabele te moeten controleren. Maar serieus, het is zoiets kleins dat je ze niet hoeft te scheiden.

server {
    listen   80;
    listen   [::]:80;

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}

108
2018-01-31 20:43



Geweldig, een of andere lafaard stemde dit antwoord af zonder te zeggen waarom, ook al is dit antwoord correct. Misschien nog een van die "als is het kwade" sekteleden. Als je de moeite neemt om de Nginx-documentatie over If te lezen, zul je weten dat IfIsNOTEvil slechts BEPAALD gebruik ervan is binnen een context van locatie {}, die we hier allemaal niet doen. Mijn antwoord is absoluut de juiste manier om dingen te doen! - DELETEDACC
Ik heb dit niet gestemd, maar ik wil erop wijzen dat de standaardversie in de meest recente versies is gewijzigd in 'default_server'. - spuder
De eerste oplossing kan niet het meest efficiënt zijn, als de tweede nog efficiënter is. En je hebt zelfs beschreven, waarom je daar geen if zou moeten gebruiken: "het voorkomt dat je de $ scheme-variabele op elk verzoek moet controleren". Het punt van het niet gebruiken van ifs gaat niet alleen over prestaties, maar ook over declaratief zijn, en niet noodzakelijk. - pepkin88
+1 voor if ($ scheme = http) - Fernando Kosh
Zou $ host hier moeten gebruiken, zoals vermeld in de andere antwoorden. - Artem Russakovskii


Als u de nieuwe dubbele HTTP- en HTTPS-serverdefinitie gebruikt, kunt u het volgende gebruiken:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($ssl_protocol = "") {
       rewrite ^   https://$server_name$request_uri? permanent;
    }
}

Dit lijkt voor mij te werken en veroorzaakt geen omleidingslussen.

Bewerk:

vervangen:

rewrite ^/(.*) https://$server_name/$1 permanent;

met de herschrijflijn van Pratik.


56
2017-08-08 11:12



@DavidPashley je oplossing werkte als een charme voor mij. Bedankt - Jayesh Gopalan
If you are using the new dual HTTP and HTTPS server definition dan moet je het scheiden. - VBart
elegant en werkt perfect! - jipipayo
Dit was de enige oplossing die voor mij werkte met mijn Laravel / Homestead Nginx-configuratie. - Jared Eitnier
Ook zou de herschrijflijn moeten zijn return 301 https://$server_name$request_uri; omdat dit de geprefereerde methode is. - Jared Eitnier


Nog een andere variant, die de host behoudt: request header en volgt het voorbeeld "GOED" op nginx valkuilen:

server {
    listen   10.0.0.134:80 default_server;

    server_name  site1;
    server_name  site2;
    server_name  10.0.0.134;

    return 301 https://$host$request_uri;
}

Dit zijn de resultaten. Merk op dat gebruik $server_name in plaats van $host zou altijd doorverwijzen naar https://site1.

# curl -Is http://site1/ | grep Location
Location: https://site1/

# curl -Is http://site2/ | grep Location
Location: https://site2/


# curl -Is http://site1/foo/bar | grep Location
Location: https://site1/foo/bar

# curl -Is http://site1/foo/bar?baz=qux | grep Location
Location: https://site1/foo/bar?baz=qux

27
2018-04-11 12:20



Note that using $server_name instead of $host would always redirect to https://site1 is dat niet wat? $request_uri is voor? - Jürgen Paul
$request_uri bevat geen host- of domeinnaam. Met andere woorden, het begint altijd met een "/" -teken. - Peter
Beste antwoord veruit. - Ashesh
Ik weet niet zeker waarom dit antwoord zo laag is in stemmen. Het is de enige die het waard is om te gebruiken. - zopieux
Kan niet geloven dat zoveel mensen $ server_name gebruiken, dit is de juiste manier om het te doen - Greg Ennis


Zorg ervoor dat u 'beveiligd' inschakelt voor cookies, anders worden ze op het HTTP-verzoek verzonden en kunnen ze worden gepakt door een tool als Firesheep.


3
2018-03-23 00:40





server {
    listen x.x.x.x:80;

    server_name domain.tld;
    server_name www.domian.tld;
    server_name ipv4.domain.tld;

    rewrite     ^   https://$server_name$request_uri? permanent;
}

Dit werkt beter denk ik. x.x.x.x verwijst naar het IP-adres van uw server. Als u met Plesk 12 werkt, kunt u dat doen door het bestand "nginx.conf" in de directory "/var/www/vhosts/system/domain.tld/conf" voor het gewenste domein te wijzigen. Vergeet niet de nginx-service opnieuw op te starten nadat u de configuratie hebt opgeslagen.


1
2017-08-23 19:40



rewrite ^ https://$host$request_uri? permanent;  zou een betere oplossing zijn, omdat je verschillende servernamen op een vhost zou kunnen hebben