Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Most people type in the browser bar: mysite.com and not https://mysite.com.

Alot of developers including myself have something like this in their Nginx config file which means that this mysite.com request causes a redirect to the https:// site:

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

}

Google pagespeed team recently said [ref] these redirects are terrible for performance particularly on mobile because the redirect causes the request to go back through the mobile carrier network.

My question is is there any other way to write the nginx.conf such that people typing in the server_name don't experience this http:// to https:// redirect penalty?

share|improve this question
    
Deny requests to http? There's no way around this if you require https for your service. –  Nathan C Jul 22 '13 at 15:51
    
@NathanC thanks, may I ask what the deny code would look like? –  tim peterson Jul 22 '13 at 15:54
    
Listen on 443 only and don't even have the server listening on http. –  Nathan C Jul 22 '13 at 15:54
    
so if you listen on 443 only and type in only the server_name you get a blank screen? –  tim peterson Jul 22 '13 at 15:57
    
It'll actually be a "connection refused" message. If you don't want that, see my answer (give me a minute to type it :)) –  Nathan C Jul 22 '13 at 15:59

2 Answers 2

No, this would require that you change the behavior of the browser. It's all request response based. The user types example.com in his browser bar and the browser automatically adds http:// in front of that. So your server will always get the first request on http://example.com and you can only answer with a redirect to your SSL enabled address if there is nothing without SSL.

Denying the request, as proposed by Nathan is absolutely no option. Because the browser will display an error page that this website is not reachable and might not even exist.

But there is something else you can do: HTTP Strict Transport Security (HSTS)

HSTS tells the browser that your site is only reachable via SSL and that subsequent requests should always be auto-completed with https:// instead of http://. You can achieve this in nginx with the following lines in your SSL server block:

add_header Strict-Transport-Security "max-age=262974383";

http {
  # One server listening on port 80 and sending the redirect to HTTPS
  server {
    server_name example.com;
    return 301 https://$server_name$request_uri;
  }

  # Our actual server handling incoming requests.
  server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate      /etc/ssl/my_site.pem;
    ssl_certificate_key  /etc/ssl/my_site.key;
    # Tell the browser that he should always visit us with SSL.
    add_header Strict-Transport-Security "max-age=262974383";
  }
}
share|improve this answer
    
thanks, this is more what I was looking for, trying it out now to see if it does what i need –  tim peterson Jul 22 '13 at 19:08
    
hmm i don't have a ssl.conf file, can I put this in my nginx.conf file? If so, in what block? If not, how would I make my server recognize this newly created ssl.conf file? –  tim peterson Jul 22 '13 at 19:23
    
Put it inside your SSL server block where you have the listen, server_name and ssl_certificate* lines. My configuration is very advanced, I just included for people who'd like to see it. –  Fleshgrinder Jul 22 '13 at 19:32
    
ok i'll try that thanks –  tim peterson Jul 22 '13 at 19:53
    
hmm, if I don't have a listen 80 server block then the first page load of mysite.com fails and with the second load then it accepts it. I only have a listen 443 server block containing your Strict-Transport-Security directive. –  tim peterson Jul 22 '13 at 20:18

Either don't listen on port 80 (which will toss an error), or deny the request:

server {
    listen 80;
    server_name mysite.com;
   location / {
  deny    all;
}
}

Then just have your normal 443 block.

share|improve this answer
    
I assume deny all still gives you a blank screen even if there is no error? I guess my question is is there any way to still show the site without a redirect? –  tim peterson Jul 22 '13 at 16:03
    
If you don't absolutely require https for everything, then use http for your main page and https everywhere else. It highly depends on your application though. –  Nathan C Jul 22 '13 at 16:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.