nginx force ssl http

2019-09-03 09:17发布

问题:

I am struggling on how to force SSL on my website (nginx). I would like to force a redirect from both "http://www.example.com" and "http://example.com" to "https://example.com" (without any www).

The code I wrote currently can catch "http://www.example.com" but does not catch "http://example.com", it seems to infinite loop a redirection. I'm pretty sure it has something to do with the "server_name". I tried swapping it up a down inside the "server { ... }" brackets and stuff but it still does not behave the way I would like it.

Here is my nginx conf

server {
    server_name     www.example.com;
    return 301      https://example.com$request_uri;
}

server {

    server_name     example.com;

    root            /var/www/example.com;
    index index.html index.php index.htm;

    location / {
        include         /etc/nginx/conf/fastcgi_params;
        fastcgi_pass    unix:/var/run/php5-fpm.sock;
        fastcgi_index   index.php;
        fastcgi_param   SCRIPT_FILENAME $document_root/$fastcgi_script_name;

    }

    location ~ /\.ht {
        deny            all;
    }

}


server {

    #listen 443 spdy default deferred;
    ssl                         on;
    ssl_certificate_key         /etc/myssl/www.example.com.key;
    ssl_certificate             /etc/myssl/www.example.com.chained.crt;
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                 'ECDHE-RSA-AES128-[...]';
    ssl_prefer_server_ciphers   on;
    ssl_dhparam                 /usr/share/myssl/dhparams/dh2048-group14.pem;
    ssl_session_timeout         5m;
    ssl_session_cache           shared:SSL:5m;
    add_header                  Strict-Transport-Security max-age=15768000;

}

回答1:

You'll want to configure each of your server blocks to specifically listen to a certain port, such as the following:

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

server {
    listen          443 ssl spdy; 
    server_name     www.example.com;
    ssl_certificate_key         /etc/myssl/www.example.com.key;
    ssl_certificate             /etc/myssl/www.example.com.chained.crt;
    [other ssl_* directives, as required]
    return 301      https://example.com$request_uri;
}

server {
    listen          443 ssl spdy; 
    server_name     example.com;
    ssl_certificate_key         /etc/myssl/www.example.com.key;
    ssl_certificate             /etc/myssl/www.example.com.chained.crt;
    [other ssl_* directives, as required]
    [remaining example.com configuration here]
}

This says listen on HTTP (port 80) for requests to http://www.example.com and http://example.com and redirect them to https://example.com. The second block listens for https://www.example.com and redirects to https://example.com. Then, the final block listens for SSL/SPDY requests to https://example.com.

Add your remaining HTTPS-only configuration to the second block, which looks to be essentially merging the second and third blocks.

The following is now demonstrated in the example: You will need to add another server block if you want your server to respond or redirect users accessing https://www.example.com & thus you may require a second valid SSL certificate (one for www.example.com and one for example.com). Alternatively, a wildcard certificate or a certificate with alternate DNS names would work for both circumstances.

Also ensure that no other conflicting configuration files are present in your configuration directory (eg /etc/nginx/conf.d or /etc/nginx/sites-enabled; depending on your platform).

Edited: expanded based on other information given.



标签: ssl nginx