Using http/https in a single server block ("ssl" parameter for "listen")


#1

Hi,

I’d like to enable both http and https within a single server block,
without having to copy the whole block and only change “listen 80” to
“listen 443” and add “ssl on”.

This appears to work somehow using the “ssl” parameter with “listen”,
but “nginx -t” complains that it can be used together with “default”
only ("“ssl” parameter can be specified for the default “listen”
directive only").
However, obviously I can use “default” only once.

Would it be possible to allow usage of the “ssl” parameter without
having to use “default”?

The example for “ssl” at
http://wiki.nginx.org/NginxHttpCoreModule#listen uses “default”, but
it’s not mentioned in the documentation that this is a requirement.

Example:
server {
server_name example.com;
listen 80;
listen 443 ssl;

location / {
    proxy_pass http://server;
}

}

I’m using nginx/0.7.47.

Thanks,
Daniel


#2

On Wed, Apr 01, 2009 at 08:23:18PM +0200, Daniel H. wrote:

However, obviously I can use “default” only once.
server_name example.com;
listen 80;
listen 443 ssl;

location / {
    proxy_pass http://server;
}

}

I’m using nginx/0.7.47.

I can not say right now if is it possible to allow “ssl” parameter
on non-default listen, but how do you plan to use two name-based
SSL servers on one IP-address:

server {
server_name example.com;
listen 80;
listen 443 ssl;
}

server {
server_name beispiel.de;
listen 80;
listen 443 ssl;
}

?


#3

Daniel,

That appears to be like a nice simplification, but I fear it will add
quite
a lot of complexity on the side you don’t see. Also, how does it know
where
to get the SSL information such as the key or cipher suite? Didn’t see
anything in your specification.

Working with what is currently here, I typically put the shared
locations
into a site.locations file and include it in each server block. The
benefits of the separation are that it is easy to change locations for
both
servers at once, but if need be I can modify each server separately (say
to
add a new location in SSL only, for example). Also, I think it may have
to
do with performance… Generally it is much better for NginX if you
separate server blocks as much as possible, but I think it is even more
so
in the case of SSL as SSL adds some overhead. We should probably wait
until
someone more versed with the insides to make a final judgement :).

  • Merlin

#4

Hi Igor,

2009/4/1 Igor S.:

listen 80;

on non-default listen, but how do you plan to use two name-based
listen 80;
listen 443 ssl;
}

?

Yes.

I’m using a single ssl_certificate/ssl_certificate_key config in the
http block, so it gets used for all servers.
I have a single certificate, which works for multiple hostnames (see
http://daniel.hahler.de/many_common_names_cn_in_one_ssl_certific - I’m
not sure if it’s currently this exact same setup/config, but it comes
close).

However, you could still allow to use ssl config options in server
blocks to work when only “listen X ssl” is used, but not “ssl on”?!
(But of course, you should know much better if this is
feasible/possible)

Cheers,
Daniel


#5

Hi Igor,

Actually, currently it’s enough to set “ssl” on default listen only and
you will get SSL in all server{}s listening on the port:

Thanks! That works, but has been very unclear from the documentation.

I’ve now adjusted some server blocks already to a single one and use
$schema, e.g. for
proxy_set_header X-Forwarded-Proto $scheme;

    server_name beispiel.de;
}

SSL is property of listen socket, although it’s not kernel related feature
such as rcvbuf/backlog/etc.: if SSL-handshake has been started you simply
can not return to plain text.

Thanks for the explanation. This sounds like it’s non-trivial to
support it with a non-default “listen” directive (and would not make
sense (or rather work) then anyway).

Thanks for your help,
Daniel


#6

On Fri, Apr 03, 2009 at 12:47:51PM +0200, Daniel H. wrote:

However, obviously I can use “default” only once.
š š server_name example.com;
I can not say right now if is it possible to allow “ssl” parameter
š š server_name beispiel.de;
I have a single certificate, which works for multiple hostnames (see
http://daniel.hahler.de/many_common_names_cn_in_one_ssl_certific - I’m
not sure if it’s currently this exact same setup/config, but it comes
close).

However, you could still allow to use ssl config options in server
blocks to work when only “listen X ssl” is used, but not “ssl on”?!
(But of course, you should know much better if this is
feasible/possible)

Actually, currently it’s enough to set “ssl” on default listen only and
you will get SSL in all server{}s listening on the port:

 server {
     listen 80;
     listen 443 default ssl;
     server_name example.com;
 }

 server {
     listen 80;
     listen 443;  # it is SSL-enabled too
     server_name beispiel.de;
 }

SSL is property of listen socket, although it’s not kernel related
feature
such as rcvbuf/backlog/etc.: if SSL-handshake has been started you
simply
can not return to plain text.