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

Ender17
  • 163
  • 1
  • 1
  • 7

4 Answers4

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 {
        # ...
    }
    # ...
}
Oleg
  • 22,300
  • 9
  • 68
  • 84
  • 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. – Ender17 Sep 10 '15 at 16:20
  • 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 https://www.example.com$request_uri; } – Ender17 Sep 10 '15 at 16:40
  • @Ender17 Just put the paths instead of `ssl.crt` and `ssl.key`. I used these filenames as examples. There is [a good manual](http://nginx.org/en/docs/http/configuring_https_servers.html) of how to set up SSL in Nginx – Oleg Sep 10 '15 at 17:33
  • @ 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 https://www.example.com$request_uri; } – Ender17 Sep 10 '15 at 21:27
  • @ curious Then I used sudo service nginx reload Then ctrl O to save. I don't think anything happened – Ender17 Sep 10 '15 at 21:30
  • @Ender17 if you type this command: `sudo service nginx configtest` what do you see in the terminal? – Oleg Sep 11 '15 at 07:29
  • @Ender17 there also must be semicolon after `...5459faef.crt` and `...dcb11788.key`. So each Nginx directive must end with `;` – Oleg Sep 11 '15 at 07:31
  • 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. – Ender17 Sep 11 '15 at 13:47
  • server { listen 80; #listen for all the HTTP requests server_name example.com www.example.com; return 301 https://www.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 failed – Ender17 Sep 11 '15 at 13:47
  • 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 https://www.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 found – Ender17 Sep 11 '15 at 13:48
  • 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 successful – Ender17 Sep 11 '15 at 13:49
  • @Ender17 are all of your `server` sections inside `http` section? – Oleg Sep 11 '15 at 13:52
  • I am not sure...Where can I locate that info? – Ender17 Sep 11 '15 at 14:44
  • @Ender17 `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.](http://nginx.org/en/docs/beginners_guide.html) – Oleg Sep 11 '15 at 14:48
  • @ 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; – Ender17 Sep 11 '15 at 14:57
  • @Ender17 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 :) – Oleg Sep 11 '15 at 15:00
  • @Courious So I would use the same code just use http { first? http { server { listen ............... – Ender17 Sep 11 '15 at 16:56
  • 1
    @Ender17 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 that – Oleg Sep 11 '15 at 19:58
  • @ 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 and – Ender17 Sep 13 '15 at 23:06
  • 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. – Ender17 Sep 13 '15 at 23:09
  • @Ender17 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. – Oleg Sep 14 '15 at 05:49
  • I added etc/nginx/nginx.conf to the original questions. Thanks – Ender17 Sep 14 '15 at 15:38
  • @ 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.com – Ender17 Sep 14 '15 at 16:05
  • @Ender17 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:) – Oleg Sep 14 '15 at 16:12
  • I don't see anything listed in /etc/nginx/conf.d/. I do want to eliminate the warnings if possible. – Ender17 Sep 15 '15 at 01:15
  • 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? – Oleg Sep 15 '15 at 07:37
  • root@vps14544 [~]# ls -a /etc/nginx/conf.d/ ./ ../ default.conf default.conf-original-install example_ssl.conf – Ender17 Sep 15 '15 at 13:50
  • can you show the contents of `/etc/nginx/conf.d/default.conf` file ? – Oleg Sep 15 '15 at 15:26
  • Added it the to question under header /etc/nginx/conf.d/default.conf – Ender17 Sep 15 '15 at 16:16
  • @Ender17 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). – Oleg Sep 15 '15 at 18:06
  • All variations are redirecting to https://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!! – Ender17 Sep 15 '15 at 22:15
  • you're welcome @Ender17 you can contact me via email: `olegv0907@gmail.com` – Oleg Sep 16 '15 at 06:41
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;
}
JimmyBanks
  • 4,178
  • 8
  • 45
  • 72
stamster
  • 953
  • 11
  • 18
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

David Noriega
  • 196
  • 1
  • 1
  • 7
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;
}
download
  • 1
  • 1
  • 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. – Jeremy Caney Jun 01 '20 at 16:03