[nginx] SSL support in the uwsgi module.
Maxim Dounin
mdounin at mdounin.ru
Wed Dec 4 19:02:24 UTC 2013
details: http://hg.nginx.org/nginx/rev/c82b2e020b9f
branches:
changeset: 5457:c82b2e020b9f
user: Maxim Dounin <mdounin at mdounin.ru>
date: Wed Dec 04 23:01:27 2013 +0400
description:
SSL support in the uwsgi module.
Based on patch by Roberto De Ioris.
diffstat:
src/http/modules/ngx_http_uwsgi_module.c | 204 +++++++++++++++++++++++++++++-
1 files changed, 197 insertions(+), 7 deletions(-)
diffs (truncated from 305 to 300 lines):
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -34,6 +34,12 @@ typedef struct {
ngx_uint_t modifier1;
ngx_uint_t modifier2;
+
+#if (NGX_HTTP_SSL)
+ ngx_uint_t ssl;
+ ngx_uint_t ssl_protocols;
+ ngx_str_t ssl_ciphers;
+#endif
} ngx_http_uwsgi_loc_conf_t;
@@ -66,6 +72,11 @@ static char *ngx_http_uwsgi_cache_key(ng
void *conf);
#endif
+#if (NGX_HTTP_SSL)
+static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
+ ngx_http_uwsgi_loc_conf_t *uwcf);
+#endif
+
static ngx_conf_num_bounds_t ngx_http_uwsgi_modifier_bounds = {
ngx_conf_check_num_bounds, 0, 255
@@ -86,6 +97,20 @@ static ngx_conf_bitmask_t ngx_http_uwsgi
};
+#if (NGX_HTTP_SSL)
+
+static ngx_conf_bitmask_t ngx_http_uwsgi_ssl_protocols[] = {
+ { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
+ { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
+ { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
+ { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
+ { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
+ { ngx_null_string, 0 }
+};
+
+#endif
+
+
ngx_module_t ngx_http_uwsgi_module;
@@ -361,6 +386,31 @@ static ngx_command_t ngx_http_uwsgi_comm
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
&ngx_http_upstream_ignore_headers_masks },
+#if (NGX_HTTP_SSL)
+
+ { ngx_string("uwsgi_ssl_session_reuse"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_session_reuse),
+ NULL },
+
+ { ngx_string("uwsgi_ssl_protocols"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_conf_set_bitmask_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_protocols),
+ &ngx_http_uwsgi_ssl_protocols },
+
+ { ngx_string("uwsgi_ssl_ciphers"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers),
+ NULL },
+
+#endif
+
ngx_null_command
};
@@ -448,15 +498,29 @@ ngx_http_uwsgi_handler(ngx_http_request_
uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
- if (uwcf->uwsgi_lengths) {
+ u = r->upstream;
+
+ if (uwcf->uwsgi_lengths == NULL) {
+
+#if (NGX_HTTP_SSL)
+ u->ssl = (uwcf->upstream.ssl != NULL);
+
+ if (u->ssl) {
+ ngx_str_set(&u->schema, "suwsgi://");
+
+ } else {
+ ngx_str_set(&u->schema, "uwsgi://");
+ }
+#else
+ ngx_str_set(&u->schema, "uwsgi://");
+#endif
+
+ } else {
if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
- u = r->upstream;
-
- ngx_str_set(&u->schema, "uwsgi://");
u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
u->conf = &uwcf->upstream;
@@ -494,6 +558,7 @@ ngx_http_uwsgi_handler(ngx_http_request_
static ngx_int_t
ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
{
+ size_t add;
ngx_url_t url;
ngx_http_upstream_t *u;
@@ -506,6 +571,41 @@ ngx_http_uwsgi_eval(ngx_http_request_t *
return NGX_ERROR;
}
+ if (url.url.len > 8
+ && ngx_strncasecmp(url.url.data, (u_char *) "uwsgi://", 8) == 0)
+ {
+ add = 8;
+
+ } else if (url.url.len > 9
+ && ngx_strncasecmp(url.url.data, (u_char *) "suwsgi://", 9) == 0)
+ {
+
+#if (NGX_HTTP_SSL)
+ add = 9;
+ r->upstream->ssl = 1;
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "suwsgi protocol requires SSL support");
+ return NGX_CONF_ERROR;
+#endif
+
+ } else {
+ add = 0;
+ }
+
+ u = r->upstream;
+
+ if (add) {
+ u->schema.len = add;
+ u->schema.data = url.url.data;
+
+ url.url.data += add;
+ url.url.len -= add;
+
+ } else {
+ ngx_str_set(&u->schema, (u_char *) "uwsgi://");
+ }
+
url.no_resolve = 1;
if (ngx_parse_url(r->pool, &url) != NGX_OK) {
@@ -517,8 +617,6 @@ ngx_http_uwsgi_eval(ngx_http_request_t *
return NGX_ERROR;
}
- u = r->upstream;
-
u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
if (u->resolved == NULL) {
return NGX_ERROR;
@@ -1145,6 +1243,9 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
conf->upstream.intercept_errors = NGX_CONF_UNSET;
+#if (NGX_HTTP_SSL)
+ conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
+#endif
/* "uwsgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
@@ -1392,6 +1493,27 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t
ngx_conf_merge_value(conf->upstream.intercept_errors,
prev->upstream.intercept_errors, 0);
+#if (NGX_HTTP_SSL)
+ ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
+ prev->upstream.ssl_session_reuse, 1);
+
+ ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
+ (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
+ |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
+ |NGX_SSL_TLSv1_2));
+
+ ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
+ "DEFAULT");
+
+ if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (conf->upstream.ssl == NULL) {
+ conf->upstream.ssl = prev->upstream.ssl;
+ }
+#endif
+
ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");
hash.max_size = 512;
@@ -1670,6 +1792,7 @@ ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_
{
ngx_http_uwsgi_loc_conf_t *uwcf = conf;
+ size_t add;
ngx_url_t u;
ngx_str_t *value, *url;
ngx_uint_t n;
@@ -1705,12 +1828,35 @@ ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_
return NGX_CONF_ERROR;
}
+#if (NGX_HTTP_SSL)
+ uwcf->ssl = 1;
+#endif
+
return NGX_CONF_OK;
}
+ if (ngx_strncasecmp(url->data, (u_char *) "uwsgi://", 8) == 0) {
+ add = 8;
+
+ } else if (ngx_strncasecmp(url->data, (u_char *) "suwsgi://", 9) == 0) {
+
+#if (NGX_HTTP_SSL)
+ add = 9;
+ uwcf->ssl = 1;
+#else
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "suwsgi protocol requires SSL support");
+ return NGX_CONF_ERROR;
+#endif
+
+ } else {
+ add = 0;
+ }
+
ngx_memzero(&u, sizeof(ngx_url_t));
- u.url = value[1];
+ u.url.len = url->len - add;
+ u.url.data = url->data + add;
u.no_resolve = 1;
uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
@@ -1844,3 +1990,47 @@ ngx_http_uwsgi_cache_key(ngx_conf_t *cf,
}
#endif
+
+
+#if (NGX_HTTP_SSL)
+
+static ngx_int_t
+ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
+{
+ ngx_pool_cleanup_t *cln;
+
+ uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
+ if (uwcf->upstream.ssl == NULL) {
+ return NGX_ERROR;
+ }
+
+ uwcf->upstream.ssl->log = cf->log;
+
+ if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx,
+ (const char *) uwcf->ssl_ciphers.data)
+ == 0)
+ {
+ ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
+ "SSL_CTX_set_cipher_list(\"%V\") failed",
+ &uwcf->ssl_ciphers);
+ return NGX_ERROR;
+ }
+
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NGX_ERROR;
+ }
+
+ cln->handler = ngx_ssl_cleanup_ctx;
+ cln->data = uwcf->upstream.ssl;
More information about the nginx-devel
mailing list