Why can't I use the "ssl" modified on more than one listen statement?

Hi,

The following is an example of how we would like to run our
configuration.

ssl_certificate      common.crt;
ssl_certificate_key  common.key;

server {
  listen           80;
  server_name      www.nginx.org;
  ...
}

server {
  listen           443 default ssl;
  server_name      secure.nginx.org;
  ...
}

server {
  listen           80;
  listen           443 ssl;
  server_name      images.nginx.org;
  include images.location;
}

We encounter the following error trying to install the configuration:

[emerg]: a duplicate listen options for 0.0.0.0:443 in
/usr/local/etc/nginx/projects/proj.conf:19

All of the server names are CNAMEs of one IP address.

If I do the following, it works:

ssl_certificate      common.crt;
ssl_certificate_key  common.key;

server {
  listen           80;
  server_name      www.nginx.org;
  ...
}

server {
  listen           443 default ssl;
  server_name      secure.nginx.org;
  ...
}

server {
  listen           80;
  server_name      images.nginx.org;
  include images.location;
}

server {
  listen           443;
  ssl on;
  server_name      images.nginx.org;
  include images.location;
}

Why can I not specify like the first example above?

Thanks,
-peter

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,132621,132621#msg-132621

Hello!

On Tue, Sep 21, 2010 at 11:39:46AM -0400, portante wrote:

listen 80;
server {
/usr/local/etc/nginx/projects/proj.conf:19
server {

include images.location;
}
[/code]

Why can I not specify like the first example above?

Socket can’t be in ssl mode for some servers and in non-ssl for
others, so there is no need to specify “ssl” argument for
non-default servers. I.e. this will work with ssl in both
servers:

server {
listen 443 default ssl;

}

server {
listen 443;

}

In your first configuration nginx was able to detect that you used
meaningless “ssl” argument in second server and complained. In
second configuration it wasn’t able to detect meaningless “ssl
on;” statement. This is the only difference.

Maxim D.

Okay that makes sense, except, why do we expose that to the user in the
configuration files? Why make the user ensure that only one server
configuration specifies the “ssl” listen option, when the “ssl on/off”
can be specified without errors?

I would like to have my server blocks be independent of each other, so
that I can have a complete specification of what I want to happen for
that virtual server without relying on another server block to get that
to happen.

It would be nice to be able to use listen 443 ssl; in all
of my server blocks (we keep them in separate files since they represent
independent projects and code bases) as a way to describe that
0.0.0.0:443 should be in SSL mode, if it is not already.

It should still be an error if I have one server block with the ssl
option and one without, but when they all have the same option, what
problem are we trying to alert the user to?

Thanks for engaging in this discussion. I appreciate it.

Sincerely, -peter

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,132621,132672#msg-132672

Hello,

Here is a patch against 0.8.50 to only complain when the listen options
are actually different.

Would folks be interested in this?

$ svn diff -r 32178:32179 src/http/ngx_http.c
Index: src/http/ngx_http.c
===================================================================
--- src/http/ngx_http.c (revision 32178)
+++ src/http/ngx_http.c (revision 32179)
@@ -1273,9 +1273,35 @@
         if (lsopt->set) {

             if (addr[i].opt.set) {
-                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
-                        "a duplicate listen options for %s",
addr[i].opt.addr);
-                return NGX_ERROR;
+               /*
+                * If this set is not the same as the old set, complain
+                */
+               if ((lsopt->default_server !=
addr[i].opt.default_server)
+                       || (lsopt->bind != addr[i].opt.bind)
+                       || (lsopt->wildcard != addr[i].opt.wildcard)
+#if (NGX_HTTP_SSL)
+                       || (lsopt->ssl != addr[i].opt.ssl)
+#endif
+#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
+                       || (lsopt->ipv6only != addr[i].opt.ipv6only)
+#endif
+                       || (lsopt->backlog != addr[i].opt.backlog)
+                       || (lsopt->rcvbuf != addr[i].opt.rcvbuf)
+                       || (lsopt->sndbuf != addr[i].opt.sndbuf)
+#if (NGX_HAVE_SETFIB)
+                       || (lsopt->setfib != addr[i].opt.setfib)
+#endif
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
+                       || (ngx_strcmp(lsopt->accept_filter,
addr[i].opt.accept_filter) != 0)
+#endif
+#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
+                       || (lsopt->deferred_accept !=
addr[i].opt.deferred_accept)
+#endif
+                       || (ngx_strcmp(lsopt->addr, addr[i].opt.addr) !=
0)) {
+                   ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                       "conflicting listen options for %s",
addr[i].opt.addr);
+                   return NGX_ERROR;
+               }
             }

             addr[i].opt = *lsopt;

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,132621,133967#msg-133967

Sorry, I meant to include my updated configuration example:

ssl_certificate      common.crt;
ssl_certificate_key  common.key;

server {
  listen           80;
  server_name      www.nginx.org;
  ...
}

server {
  listen           443 ssl;
  server_name      secure.nginx.org;
  ...
}

server {
  listen           80;
  server_name      images.nginx.org;
  include images.location;
}

server {
  listen           443 ssl;
  server_name      images.nginx.org;
  include images.location;
}

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,132621,132674#msg-132674

On Sat, Sep 25, 2010 at 11:00:18AM -0400, portante wrote:

===================================================================

  •           /*
    
  •                   || (lsopt->ipv6only != addr[i].opt.ipv6only)
    

+#endif

  •           }
           }
    
           addr[i].opt = *lsopt;
    

[/code]

This patch breaks “listen default_server” and force to set various
listen socket options in all listen directive. The attached patch allows
to set only “ssl” option in several listen directives.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs