[PATCH] SSL: add "{proxy,uwsgi}_ssl_server_name" directives

Piotr Sikora piotr at cloudflare.com
Wed Feb 5 06:54:34 UTC 2014


# HG changeset patch
# User Piotr Sikora <piotr at cloudflare.com>
# Date 1391582201 28800
#      Tue Feb 04 22:36:41 2014 -0800
# Node ID f0129ac05ced1ee418fa97dbbae35f3c0b831992
# Parent  3abb7076b3ecc27d970183c4d0238cefaa7a7c78
SSL: add "{proxy,uwsgi}_ssl_server_name" directives.

Send TLS Server Name Indication (SNI) when connecting to
an SSL upstream and provided value isn't an empty string.

Signed-off-by: Piotr Sikora <piotr at cloudflare.com>

diff -r 3abb7076b3ec -r f0129ac05ced src/event/ngx_event_connect.h
--- a/src/event/ngx_event_connect.h	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/event/ngx_event_connect.h	Tue Feb 04 22:36:41 2014 -0800
@@ -50,6 +50,8 @@ struct ngx_peer_connection_s {
 #if (NGX_SSL)
     ngx_event_set_peer_session_pt    set_session;
     ngx_event_save_peer_session_pt   save_session;
+
+    ngx_str_t                        server_name;
 #endif
 
 #if (NGX_THREADS)
diff -r 3abb7076b3ec -r f0129ac05ced src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/http/modules/ngx_http_proxy_module.c	Tue Feb 04 22:36:41 2014 -0800
@@ -553,6 +553,13 @@ static ngx_command_t  ngx_http_proxy_com
       offsetof(ngx_http_proxy_loc_conf_t, ssl_ciphers),
       NULL },
 
+    { ngx_string("proxy_ssl_server_name"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_http_set_complex_value_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_server_name),
+      NULL },
+
 #endif
 
       ngx_null_command
@@ -2390,6 +2397,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
      *     conf->upstream.location = NULL;
      *     conf->upstream.store_lengths = NULL;
      *     conf->upstream.store_values = NULL;
+     *     conf->upstream.ssl_server_name = NULL;
      *
      *     conf->method = { 0, NULL };
      *     conf->headers_source = NULL;
@@ -2725,6 +2733,10 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
                              "DEFAULT");
 
+    if (conf->upstream.ssl_server_name == NULL) {
+        conf->upstream.ssl_server_name = prev->upstream.ssl_server_name;
+    }
+
     if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
         return NGX_CONF_ERROR;
     }
diff -r 3abb7076b3ec -r f0129ac05ced src/http/modules/ngx_http_upstream_keepalive_module.c
--- a/src/http/modules/ngx_http_upstream_keepalive_module.c	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c	Tue Feb 04 22:36:41 2014 -0800
@@ -49,6 +49,10 @@ typedef struct {
     socklen_t                          socklen;
     u_char                             sockaddr[NGX_SOCKADDRLEN];
 
+#if (NGX_HTTP_SSL)
+    ngx_str_t                          server_name;
+#endif
+
 } ngx_http_upstream_keepalive_cache_t;
 
 
@@ -237,9 +241,17 @@ ngx_http_upstream_get_keepalive_peer(ngx
         item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
         c = item->connection;
 
-        if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
-                         item->socklen, pc->socklen)
-            == 0)
+        if ((ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
+                          item->socklen, pc->socklen)
+             == 0)
+#if (NGX_HTTP_SSL)
+            && (pc->server_name.len == item->server_name.len)
+            && (pc->server_name.len == 0
+                || ngx_strncmp(pc->server_name.data, item->server_name.data,
+                               pc->server_name.len)
+                   == 0)
+#endif
+            )
         {
             ngx_queue_remove(q);
             ngx_queue_insert_head(&kp->conf->free, q);
@@ -346,6 +358,22 @@ ngx_http_upstream_free_keepalive_peer(ng
     item->socklen = pc->socklen;
     ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
 
+#if (NGX_HTTP_SSL)
+
+    item->server_name.len = pc->server_name.len;
+
+    if (item->server_name.len) {
+        item->server_name.data = ngx_pnalloc(c->pool, pc->server_name.len);
+        if (item->server_name.data == NULL) {
+            goto invalid;
+        }
+
+        ngx_memcpy(item->server_name.data, pc->server_name.data,
+                   pc->server_name.len);
+    }
+
+#endif
+
     if (c->read->ready) {
         ngx_http_upstream_keepalive_close_handler(c->read);
     }
diff -r 3abb7076b3ec -r f0129ac05ced src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/http/modules/ngx_http_uwsgi_module.c	Tue Feb 04 22:36:41 2014 -0800
@@ -409,6 +409,13 @@ static ngx_command_t ngx_http_uwsgi_comm
       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers),
       NULL },
 
+    { ngx_string("uwsgi_ssl_server_name"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_http_set_complex_value_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_server_name),
+      NULL },
+
 #endif
 
       ngx_null_command
@@ -1505,6 +1512,10 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t
     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
                              "DEFAULT");
 
+    if (conf->upstream.ssl_server_name == NULL) {
+        conf->upstream.ssl_server_name = prev->upstream.ssl_server_name;
+    }
+
     if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
         return NGX_CONF_ERROR;
     }
diff -r 3abb7076b3ec -r f0129ac05ced src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/http/ngx_http_upstream.c	Tue Feb 04 22:36:41 2014 -0800
@@ -478,6 +478,9 @@ static void
 ngx_http_upstream_init_request(ngx_http_request_t *r)
 {
     ngx_str_t                      *host;
+#if (NGX_HTTP_SSL)
+    ngx_str_t                       name;
+#endif
     ngx_uint_t                      i;
     ngx_resolver_ctx_t             *ctx, temp;
     ngx_http_cleanup_t             *cln;
@@ -536,6 +539,33 @@ ngx_http_upstream_init_request(ngx_http_
 
     u->peer.local = ngx_http_upstream_get_local(r, u->conf->local);
 
+#if (NGX_HTTP_SSL)
+
+    if (u->ssl && u->conf->ssl_server_name) {
+
+        if (ngx_http_complex_value(r, u->conf->ssl_server_name, &name)
+            != NGX_OK)
+        {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
+        u->peer.server_name.len = name.len;
+
+        if (u->peer.server_name.len) {
+            u->peer.server_name.data = ngx_pnalloc(r->pool, name.len + 1);
+            if (u->peer.server_name.data == NULL) {
+                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
+
+            ngx_memcpy(u->peer.server_name.data, name.data, name.len);
+            u->peer.server_name.data[name.len] = '\0';
+        }
+    }
+
+#endif
+
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
     u->output.alignment = clcf->directio_alignment;
@@ -1363,6 +1393,18 @@ ngx_http_upstream_ssl_init_connection(ng
         }
     }
 
+    if (u->peer.server_name.len) {
+
+        if (SSL_set_tlsext_host_name(c->ssl->connection,
+                                     u->peer.server_name.data)
+            == 0)
+        {
+            ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+    }
+
     r->connection->log->action = "SSL handshaking to upstream";
 
     rc = ngx_ssl_handshake(c);
diff -r 3abb7076b3ec -r f0129ac05ced src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h	Tue Feb 04 16:26:46 2014 +0400
+++ b/src/http/ngx_http_upstream.h	Tue Feb 04 22:36:41 2014 -0800
@@ -195,6 +195,7 @@ typedef struct {
 #if (NGX_HTTP_SSL)
     ngx_ssl_t                       *ssl;
     ngx_flag_t                       ssl_session_reuse;
+    ngx_http_complex_value_t        *ssl_server_name;
 #endif
 
     ngx_str_t                        module;



More information about the nginx-devel mailing list