Force www. and https in nginx.conf (SSL)
Asked Answered
C

4

16

After purchasing a SSL certificate I have been trying to force all pages to secured https and to www.

https://www.exampl.com is working and secure but only if type it in exactly. www.example.com or example.com are still pointing to http.

We use nginx as a proxy and need to input the rewrite there. I have SSH / root access via Putty. I have accessed nginx.conf by inputting into putty.

Now what? Do I input the nginx commands on this page? Starting where the cursor is? Any command lines first?

HTTPS:

.htacess – Original code I was given before I found out I had to input into nginx

RewriteEngine On 
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

Nginx code converter – This is how it shows on the converter. Is everything on the correct lines?

# nginx configuration location / {
if ($http_host ~* "^example.com"){
rewrite ^(.*)$ http://example.com/$1 redirect; } }

and then

WWW

.htacess – Original code I was given before I found out I had to input into nginx

#Force www:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example.com [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]

Nginx code converter – This is how it shows on the converter. Is everything on the correct line?

# nginx configuration location / { 
if ($http_host ~* "^example.com"){ 
rewrite ^(.*)$ http://www.example.com/$1 redirect; } 

}

Do I then save? Restart?

Any help would be greatly appreciated. I have been battling this for weeks. My Hosting company helped as far as they could, now I am learning on the fly…. Or should I just stop and hire a developer? $$$

Thanks

Clomp answered 9/9, 2015 at 18:26 Comment(1)
rewrite ^ is an anti pattern now, use HTTP 301 redirect insteadHurl
T
38

The best way to implement WWW and HTTPS redirection is to create a new server section in Nginx config:

server {
    listen      80;   #listen for all the HTTP requests
    server_name example.com www.example.com;
    return      301         https://www.example.com$request_uri;
}

You will also have to perform https://example.com to https://www.example.com redirection. This may be done with code similar to the following:

server {
    listen              443 ssl;
    server_name         example.com;

    ssl_certificate     ssl.crt; #you have to put here...
    ssl_certificate_key ssl.key; #   ...paths to your certificate files
    return      301     https://www.example.com$request_uri;
}

And of course, you must reload Nginx config after each change. Here are some useful commands:

check for errors in the configuration:

sudo service nginx configtest

reload configuration (this would be enough to make changes "work"):

sudo service nginx reload

restart the whole webserver:

sudo service nginx restart

Important note:

All your server sections must be inside http section (or in a file included in http section):

http {
    # some directives ...
    server {
        # ...
    }
    server {
        # ...
    }
    # ...
}
Telpherage answered 9/9, 2015 at 20:17 Comment(32)
Curious, That is the most straightforward answer I have received during my quest to solve this. Thank you! Before implementing your suggestions above I wanted to make sure I had the right SSL information.Clomp
server { listen 443 ssl; server_name example.com; ssl_certificate ssl.crt; /var/cpanel/ssl/installed/certs/example_com_dfb5e_bdd8f_1472083199_f90ea94fc5187‌​75dfb39c8495459faef.crt ssl_certificate_key ssl.key; /var/cpanel/ssl/installed/keys/dfb5e_bdd8f_97d6e27f792fd220e7cd5d1bdcb11788.key return 301 example.com$request_uri; }Clomp
@Clomp Just put the paths instead of ssl.crt and ssl.key. I used these filenames as examples. There is a good manual of how to set up SSL in NginxTelpherage
@ Curious This is what I used. server { listen 443 ssl; server_name example.com; ssl_certificate /var/cpanel/ssl/installed/certs/example_com_dfb5e_bdd8f_1472083199_f90ea94fc518775dfb39c8495459faef.crt ssl_certificate_key /var/cpanel/ssl/installed/keys/dfb5e_bdd8f_97d6e27f792fd220e7cd5d1bdcb11788.key return 301 example.com$request_uri; }Clomp
@ curious Then I used sudo service nginx reload Then ctrl O to save. I don't think anything happenedClomp
@Clomp if you type this command: sudo service nginx configtest what do you see in the terminal?Telpherage
@Clomp there also must be semicolon after ...5459faef.crt and ...dcb11788.key. So each Nginx directive must end with ;Telpherage
I tried each of these separately to see if one works and the other one doesn’t. Both send back sever directive not allowed here. I feel like I am getting close but after trying this last time the site would not work so I deleted the code. Thanks for the continuous help.Clomp
server { listen 80; #listen for all the HTTP requests server_name example.com www.example.com; return 301 example.com.com$request_uri; } root@vps14544 [~]# sudo service nginx configtest nginx: [emerg] "server" directive is not allowed here in /etc/nginx/nginx.conf:1 nginx: configuration file /etc/nginx/nginx.conf test failedClomp
server { listen 443 ssl; server_name example.com; ssl_certificate /var/cpanel/ssl/installed/certs/example_com_dfb5e_bdd8f_1472083199_f90ea94fc518775dfb39c8495459faef.crt; ssl_certificate_key /var/cpanel/ssl/installed/keys/dfb5e_bdd8f_97d6e27f792fd220e7cd5d1bdcb11788.key; return 301 example.com.com$request_uri; } root@vps14544 [~]# nginx: [emerg] "server" directive is not allowed here in /etc/nginx/nginx.conf:2 -bash: nginx:: command not foundClomp
I then erased the code and ran sudo service nginx configtest – nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successfulClomp
@Clomp are all of your server sections inside http section?Telpherage
I am not sure...Where can I locate that info?Clomp
@Clomp http section is declared in nginx.conf file. Do youknow where it is located? it can be located in several places. in my case the path is /etc/nginx/nginx.conf. The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named nginx.conf and placed in the directory /usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx.Telpherage
@ Curious this is my nano/etc/nginx/nginx.conf. is this the http section? user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream;Clomp
@Clomp ok, so you can put the suggested server sections inside http section. Take a look at my edited answer (under "Important note" header). feel free to ask if something doesn't work :)Telpherage
@Courious So I would use the same code just use http { first? http { server { listen ...............Clomp
@Clomp in your /etc/nginx/nginx.conf there is a line: http {. You can paste server sections just after this line, so it would be something like an example in my answer. And don't forget to reload Nginx after thatTelpherage
@ Curious I added the code to the http {section –saved –exited and reloaded “sudo service nginx reload” Then, root@vps14544 [~]# sudo service nginx configtest nginx: [warn] conflicting server name "www.example.com" on 0.0.0.0:80, ignored nginx: [warn] conflicting server name "example.com" on 0.0.0.0:80, ignored nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful andClomp
root@vps14544 [~]# sudo service nginx configtest nginx: [warn] conflicting server name "example.com" on 0.0.0.0:443, ignored nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful Still not working….hmmm…Sorry this has been so drawn out.Clomp
@Clomp it looks like you have duplication of server_name example.com directive. Can you please show the whole ngnx.conf? You may edit your question and put the contents of nginx.conf there. It would be much easier to help you if I saw your config.Telpherage
I added etc/nginx/nginx.conf to the original questions. ThanksClomp
@ Curious It now seems to be redirecting to www. and https even with the conflicting server name warning. Every version of the domain name "http":///www.example.com or "http"://example.com or example.com or www.example.com does seem to be forcing to "https"://www.example.comClomp
@Clomp I think you get this warnings because there are config files in the /etc/nginx/conf.d/ directory. if it i important to you to get rid of these warnings, you could show the contents of these files as well. glad that this problem is getting solved:)Telpherage
I don't see anything listed in /etc/nginx/conf.d/. I do want to eliminate the warnings if possible.Clomp
there should be files in /etc/nginx/conf.d/ dir. otherwise i'm surprised that is does work :) try this command: ls -a /etc/nginx/conf.d/ what do you see in the output?Telpherage
root@vps14544 [~]# ls -a /etc/nginx/conf.d/ ./ ../ default.conf default.conf-original-install example_ssl.confClomp
can you show the contents of /etc/nginx/conf.d/default.conf file ?Telpherage
Added it the to question under header /etc/nginx/conf.d/default.confClomp
@Clomp everything is clear now. to get rid of these warnings you have to edit default.conf: 1) comment this line listen 80; in the first server block (put # in the beginning of the line) 2) two lines below: replace this line server_name www.drinkfind.com drinkfind.com; with this server_name www.drinkfind.com; 3) Remove or comment the last two server blocks. And then reload Nginx, everything should work (I believe).Telpherage
All variations are redirecting to www. and there are now no warnings after sudo service nginx configtest. I have been on multiple sites looking for help with minimal solutions. I cannot thank you enough for all the time you have spent walking me through this process. In the future if there are any other issues I need help with is there a way I can get in touch with you. Thanks again! Cheers!!Clomp
you're welcome @Clomp you can contact me via email: [email protected]Telpherage
P
13

The following solution seems to be clear and simple, everything defined in one server block. So with this setup I force everything to https://www.domain.tld, so both handlers are here non-HTTPS and non-WWW on HTTPS. There are two IF's but if you don't want to duplicate entire SSL block two times to handle it... this is the way to do it.

server {
    listen 80;
    listen 443 ssl;

    server_name domain.tld www.domain.tld;

    # global HTTP handler
    if ($scheme = http) {
        return 301 https://www.domain.tld$request_uri;
    }

    # global non-WWW HTTPS handler
    if ($http_host = domain.tld){
        return 303 https://www.domain.tld$request_uri;
    }
}

And even better solution to avoid IF's:

# Redirect all traffic from HTTP to HTTPS
server {
    listen 80;

    server_name example.com www.example.com;

    # Destination redirect base URI
    set $RURI https://www.example.com;

    location / {return 301 $RURI$request_uri;}
}

# Redirect non-WWW HTTPS traffic to WWW HTTPS
server {
    listen 443 ssl;
    # NOTE: SSL configuration is defined elsewhere
    server_name example.com;
    return 301 $scheme://www.$host$request_uri;
}

# MAIN SERVER BLOCK
server {
    listen 443 ssl;
    # NOTE: SSL configuration is defined elsewhere
    server_name www.example.com;
}
Phosphoroscope answered 21/4, 2016 at 18:20 Comment(0)
V
0

If you have a sites-enabled directory, do not use the "http" top directive. Just create another file (with any name) in the site-enabled directory that has:

server {
    listen      80;   #listen for all the HTTP requests
    server_name example.com www.example.com;
    return      301         https://www.example.com$request_uri;
}

and comment out the line

listen 80; 

where the server_name is the same in the other file that serves www.example.com

Viniculture answered 29/4, 2016 at 7:16 Comment(0)
P
0

I searched a lot , finally this is my right answer. also remember to add a www A record in your domain registar's dns control panel.

 # Force all users to https://www.example.com
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /etc/nginx/ssl/www.example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/www.example.com.key;
    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl;
    server_name www.example.com;
    root /var/www/html

    error_page  403 /error/404.html;
    error_page  404 /error/404.html;
    error_page  500 502 503 504 /error/50x.html;
    ssl_certificate /etc/nginx/ssl/www.example.com.pem;
    ssl_certificate_key /etc/nginx/ssl/www.example.com.key;
}
Possessed answered 1/6, 2020 at 15:50 Comment(1)
Would you edit your answer to explain how this differs from the accepted answer? That will make it more useful for people scanning answers to understand why yours might be preferable.Brozak

© 2022 - 2024 — McMap. All rights reserved.