238 votes

Comment forcer ou rediriger vers SSL dans nginx ?

J'ai une page d'inscription sur un sous-domaine : https://signup.example.com

Il ne devrait être accessible que via HTTPS, mais j'ai peur que les gens tombent dessus via HTTP et obtiennent un message 404.

Mon bloc html/serveur dans nginx ressemble à ceci :

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;
    }
  }
}

Qu'est-ce que je peux ajouter pour que les gens qui vont à http://signup.example.com sont redirigés vers https://signup.example.com ? (Pour info, je sais qu'il existe des plugins Rails qui peuvent forcer les SSL mais j'espérais éviter cela)

278voto

VBart Points 8009

Le meilleur moyen, tel qu'il est décrit dans le mode d'emploi officiel c'est en utilisant le return directive :

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

149voto

Dangph Points 5561

Selon Les pièges de nginx il est légèrement préférable d'omettre la capture inutile, en utilisant $request_uri à la place. Dans ce cas, ajoutez un point d'interrogation pour empêcher nginx de doubler les arguments de la requête.

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

134voto

DELETEDACC Points 1507

C'est la méthode la plus correcte et la plus efficace si vous voulez tout garder dans un seul bloc de serveurs :

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;
    }
}

Tout ce qui précède, l'utilisation de "rewrite" ou de "if ssl_protocol" etc. est plus lent et pire.

Voici la même chose, mais encore plus efficace, en exécutant la réécriture uniquement sur le protocole http, cela évite d'avoir à vérifier la variable $scheme à chaque requête. Mais sérieusement, c'est une chose tellement mineure que vous n'avez pas besoin de les séparer.

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;
}

56voto

David Pashley Points 22851

Si vous utilisez la nouvelle définition de double serveur HTTP et HTTPS, vous pouvez utiliser ce qui suit :

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;
    }
}

Cela semble fonctionner pour moi et ne provoque pas de boucles de redirection.

Edit :

Remplacé :

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

avec la ligne de réécriture de Pratik.

31voto

Peter Points 556

Une autre variante encore, qui préserve l'en-tête de requête Host : et suit l'exemple de "BON" sur Les pièges de nginx :

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;
}

Voici les résultats. Notez que l'utilisation de $server_name au lieu de $host serait toujours redirigé vers 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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X