1

I would like to avoid having to repeat all the virtualhost server {} blocks in nginx just to have custom ssl settings that vary slightly from plain http requests.

Most ssl directives can be placed right in the main block, except one hurdle I cannot find a workaround for: different keep-alive for https vs http

Is there any way I can use $scheme to dynamically change the keepalive_timeout ?

I've even considered that I can use more_set_input_headers -r 'Keep-Alive: timeout=60'; to conditionally replace the keep-alive timeout only if it already exists, but the problem is $scheme cannot be used in location ie. this is invalid location ^https {}

2 Answers 2

2

I'm pretty sure you can use a map :

map $scheme $myCustomTTL {
   default     90;
   http        90;
   https       60;
}

add_header Keep-Alive timeout=$myCustomTTL;
4
  • Ohh! Didn't know about that one, it's a very basic switch/case, thank you.
    – ck_
    Nov 27, 2012 at 9:29
  • 1
    This will not work. You just set a header for browser, but it will not affect nginx behavior. Clients may ignore this header.
    – VBart
    Nov 28, 2012 at 3:43
  • 1
    You're right. I've just followed what @ck_ was suggesting with headers, without asking myself if it was a good practice. keepalive_timeout is the directive used by nginx to control the KeepAlive behavior. So what should be written is : keepalive_timeout ${myCustomTTL}s ${myCustomTTL}s Nov 28, 2012 at 7:53
  • Actually: keepalive_timeout" directive invalid value in /etc/nginx/nginx.conf what I think is happening is how nginx cannot use variables during load time, only runtime.
    – ck_
    Nov 29, 2012 at 9:08
0

As it seems that keepalive_timeout cannot be used with parameters but only with fixed values, another solution would be to use nginx as a SSL endpoint.

Your SSL requests will be handled by a specific server{} block, that would only manage the SSL handshake and the specific Keep-Alive value, then forward the plain-HTTP request to the main server {} block.

Your nginx configuration would include something like the following:

upstream plain_http {
   server  127.0.0.1:80;
} 

server {
   listen   443;
   server_name  *.yourdomain.com;
   ssl                       on;
   ssl_certificate           /etc/nginx/ssl/mycert.pem;
   ssl_certificate_key       /etc/nginx/ssl/mykey.key;
   ssl_protocols             SSLv3 TLSv1;
   ssl_ciphers               ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;
   ssl_prefer_server_ciphers on;

   keepalive_timeout 90;

   location / {
     proxy_pass              http://plain_http;
     proxy_redirect http:// https://;  
   }
}

The proxy_redirect directive tells nginx to rewrite URI found in Location and Refresh headers in the plain-HTTP response.

2
  • Can nginx proxy_pass to another proxy_pass? ie. daisy chain the ssl to an apache reverse proxy?
    – ck_
    Nov 29, 2012 at 14:38
  • There's no reason you couldn't do that, since the plain-HTTP nginx server is quite independant from its SSL sibling. Nov 29, 2012 at 14:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .