nginx strict sni - Add option strict_sni and strict_sni_header
parent
cb59b7e7c6
commit
cbc1c1b2dc
|
@ -124,10 +124,14 @@ Run it from the nginx directory.
|
||||||
|
|
||||||
This is a condition for using strict sni. [View issue.](https://github.com/hakasenyang/openssl-patch/issues/7#issuecomment-427664716)
|
This is a condition for using strict sni. [View issue.](https://github.com/hakasenyang/openssl-patch/issues/7#issuecomment-427664716)
|
||||||
|
|
||||||
|
- How to use nginx strict-sni?
|
||||||
|
- **ONLY USE IN http { }**
|
||||||
|
- strict_sni : nginx strict-sni ON/OFF toggle option.
|
||||||
|
- strict_sni_header : if you do not want to respond to invalid headers. (**only with strict_sni**)
|
||||||
- Strict SNI requires at least two ssl server (fake) settings (server { listen 443 ssl }).
|
- Strict SNI requires at least two ssl server (fake) settings (server { listen 443 ssl }).
|
||||||
- It does not matter what kind of certificate or duplicate.
|
- It does not matter what kind of certificate or duplicate.
|
||||||
|
|
||||||
Thanks [@JemmyLoveJenny](https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427040319)!
|
Thanks [@JemmyLoveJenny](https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427040319), [@NewBugger](https://github.com/hakasenyang/openssl-patch/issues/7#issuecomment-427831677)!
|
||||||
|
|
||||||
### nginx OpenSSL-1.1.x Renegotiation Bugfix
|
### nginx OpenSSL-1.1.x Renegotiation Bugfix
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,8 @@
|
||||||
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
|
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
|
||||||
index 75129134..a41edeab 100644
|
index 75129134..e9ea5231 100644
|
||||||
--- a/src/event/ngx_event_openssl.c
|
--- a/src/event/ngx_event_openssl.c
|
||||||
+++ b/src/event/ngx_event_openssl.c
|
+++ b/src/event/ngx_event_openssl.c
|
||||||
@@ -1455,6 +1455,14 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
@@ -2547,6 +2547,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
||||||
|
|
||||||
c->read->error = 1;
|
|
||||||
|
|
||||||
+#if (!defined SSL_R_CALLBACK_FAILED || !defined SSL_F_FINAL_SERVER_NAME)
|
|
||||||
+ if (sslerr == SSL_ERROR_SSL) {
|
|
||||||
+ ERR_peek_error();
|
|
||||||
+ ERR_clear_error();
|
|
||||||
+ return NGX_ERROR;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
|
|
||||||
|
|
||||||
return NGX_ERROR;
|
|
||||||
@@ -1568,6 +1576,14 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
|
|
||||||
|
|
||||||
c->read->error = 1;
|
|
||||||
|
|
||||||
+#if (!defined SSL_R_CALLBACK_FAILED || !defined SSL_F_FINAL_SERVER_NAME)
|
|
||||||
+ if (sslerr == SSL_ERROR_SSL) {
|
|
||||||
+ ERR_peek_error();
|
|
||||||
+ ERR_clear_error();
|
|
||||||
+ return NGX_ERROR;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_read_early_data() failed");
|
|
||||||
|
|
||||||
return NGX_ERROR;
|
|
||||||
@@ -2547,6 +2563,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
|
||||||
char *text)
|
char *text)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
@ -42,18 +12,22 @@ index 75129134..a41edeab 100644
|
||||||
ngx_uint_t level;
|
ngx_uint_t level;
|
||||||
|
|
||||||
level = NGX_LOG_CRIT;
|
level = NGX_LOG_CRIT;
|
||||||
@@ -2583,6 +2602,20 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
@@ -2583,6 +2586,24 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
|
||||||
|
|
||||||
n = ERR_GET_REASON(ERR_peek_error());
|
n = ERR_GET_REASON(ERR_peek_error());
|
||||||
|
|
||||||
+ /* Strict SNI Error Patch
|
+ /* Strict SNI Error Patch
|
||||||
+ * https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427040319
|
+ * https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427040319
|
||||||
|
+ * https://github.com/hakasenyang/openssl-patch/issues/7#issuecomment-427872934
|
||||||
+ */
|
+ */
|
||||||
+#if (defined SSL_R_CALLBACK_FAILED && defined SSL_F_FINAL_SERVER_NAME)
|
+#if (defined SSL_R_CALLBACK_FAILED && defined SSL_F_FINAL_SERVER_NAME)
|
||||||
+ if (n == SSL_R_CALLBACK_FAILED) {
|
+ if (n == SSL_R_CALLBACK_FAILED) {
|
||||||
+ f = ERR_GET_FUNC(ERR_peek_error());
|
+ f = ERR_GET_FUNC(ERR_peek_error());
|
||||||
+ if (f == SSL_F_FINAL_SERVER_NAME) {
|
+ if (f == SSL_F_FINAL_SERVER_NAME) {
|
||||||
+ ERR_peek_error();
|
+ while (ERR_peek_error()) {
|
||||||
|
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
|
+ "ignoring ssl error at STRICT SNI block");
|
||||||
|
+ }
|
||||||
+ ERR_clear_error();
|
+ ERR_clear_error();
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
|
@ -63,34 +37,174 @@ index 75129134..a41edeab 100644
|
||||||
/* handshake failures */
|
/* handshake failures */
|
||||||
if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
|
if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
|
||||||
#ifdef SSL_R_NO_SUITABLE_KEY_SHARE
|
#ifdef SSL_R_NO_SUITABLE_KEY_SHARE
|
||||||
|
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
|
||||||
|
index c57ec00c..a14d68a9 100644
|
||||||
|
--- a/src/http/ngx_http_core_module.c
|
||||||
|
+++ b/src/http/ngx_http_core_module.c
|
||||||
|
@@ -441,6 +441,20 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||||
|
offsetof(ngx_http_core_loc_conf_t, directio_alignment),
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
+ { ngx_string("strict_sni"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_flag_slot,
|
||||||
|
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_core_loc_conf_t, strict_sni),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
+ { ngx_string("strict_sni_header"),
|
||||||
|
+ NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
|
||||||
|
+ ngx_conf_set_flag_slot,
|
||||||
|
+ NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
|
+ offsetof(ngx_http_core_loc_conf_t, strict_sni_header),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
{ ngx_string("tcp_nopush"),
|
||||||
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||||
|
ngx_conf_set_flag_slot,
|
||||||
|
@@ -3387,6 +3401,8 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
||||||
|
clcf->read_ahead = NGX_CONF_UNSET_SIZE;
|
||||||
|
clcf->directio = NGX_CONF_UNSET;
|
||||||
|
clcf->directio_alignment = NGX_CONF_UNSET;
|
||||||
|
+ clcf->strict_sni = NGX_CONF_UNSET;
|
||||||
|
+ clcf->strict_sni_header = NGX_CONF_UNSET;
|
||||||
|
clcf->tcp_nopush = NGX_CONF_UNSET;
|
||||||
|
clcf->tcp_nodelay = NGX_CONF_UNSET;
|
||||||
|
clcf->send_timeout = NGX_CONF_UNSET_MSEC;
|
||||||
|
@@ -3615,6 +3631,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
NGX_OPEN_FILE_DIRECTIO_OFF);
|
||||||
|
ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
|
||||||
|
512);
|
||||||
|
+ ngx_conf_merge_value(conf->strict_sni, prev->strict_sni, 0);
|
||||||
|
+ ngx_conf_merge_value(conf->strict_sni_header, prev->strict_sni_header, 0);
|
||||||
|
ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
|
||||||
|
ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
|
||||||
|
|
||||||
|
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
|
||||||
|
index 4c6da7c0..04e14d09 100644
|
||||||
|
--- a/src/http/ngx_http_core_module.h
|
||||||
|
+++ b/src/http/ngx_http_core_module.h
|
||||||
|
@@ -382,6 +382,8 @@ struct ngx_http_core_loc_conf_s {
|
||||||
|
ngx_flag_t sendfile; /* sendfile */
|
||||||
|
ngx_flag_t aio; /* aio */
|
||||||
|
ngx_flag_t aio_write; /* aio_write */
|
||||||
|
+ ngx_flag_t strict_sni; /* strict_sni */
|
||||||
|
+ ngx_flag_t strict_sni_header; /* strict_sni_header */
|
||||||
|
ngx_flag_t tcp_nopush; /* tcp_nopush */
|
||||||
|
ngx_flag_t tcp_nodelay; /* tcp_nodelay */
|
||||||
|
ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
|
||||||
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
|
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
|
||||||
index 7dd28b8c..5e5bbed1 100644
|
index 7dd28b8c..1901129d 100644
|
||||||
--- a/src/http/ngx_http_request.c
|
--- a/src/http/ngx_http_request.c
|
||||||
+++ b/src/http/ngx_http_request.c
|
+++ b/src/http/ngx_http_request.c
|
||||||
@@ -849,7 +849,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
@@ -846,14 +846,18 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
|
+ c = ngx_ssl_get_connection(ssl_conn);
|
||||||
|
+
|
||||||
|
+ hc = c->data;
|
||||||
|
+
|
||||||
|
+ clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
|
||||||
|
+
|
||||||
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
|
||||||
|
|
||||||
if (servername == NULL) {
|
if (servername == NULL) {
|
||||||
- return SSL_TLSEXT_ERR_NOACK;
|
- return SSL_TLSEXT_ERR_NOACK;
|
||||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
+ return (clcf->strict_sni) ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = ngx_ssl_get_connection(ssl_conn);
|
- c = ngx_ssl_get_connection(ssl_conn);
|
||||||
@@ -864,7 +864,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
-
|
||||||
|
if (c->ssl->handshaked) {
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
}
|
||||||
|
@@ -864,7 +868,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
host.len = ngx_strlen(servername);
|
host.len = ngx_strlen(servername);
|
||||||
|
|
||||||
if (host.len == 0) {
|
if (host.len == 0) {
|
||||||
- return SSL_TLSEXT_ERR_NOACK;
|
- return SSL_TLSEXT_ERR_NOACK;
|
||||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
+ return (clcf->strict_sni) ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
host.data = (u_char *) servername;
|
host.data = (u_char *) servername;
|
||||||
@@ -879,7 +879,7 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
@@ -873,13 +877,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
- hc = c->data;
|
||||||
|
-
|
||||||
|
if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
|
||||||
NULL, &cscf)
|
NULL, &cscf)
|
||||||
!= NGX_OK)
|
!= NGX_OK)
|
||||||
{
|
{
|
||||||
- return SSL_TLSEXT_ERR_NOACK;
|
- return SSL_TLSEXT_ERR_NOACK;
|
||||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
+ return (clcf->strict_sni) ? SSL_TLSEXT_ERR_ALERT_FATAL : SSL_TLSEXT_ERR_NOACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
|
||||||
|
@@ -891,8 +893,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
|
||||||
|
hc->conf_ctx = cscf->ctx;
|
||||||
|
|
||||||
|
- clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
|
||||||
|
-
|
||||||
|
ngx_set_connection_log(c, clcf->error_log);
|
||||||
|
|
||||||
|
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
|
||||||
|
@@ -936,15 +936,18 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||||
|
static void
|
||||||
|
ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
|
{
|
||||||
|
- ssize_t n;
|
||||||
|
- ngx_int_t rc, rv;
|
||||||
|
- ngx_str_t host;
|
||||||
|
- ngx_connection_t *c;
|
||||||
|
- ngx_http_request_t *r;
|
||||||
|
+ ssize_t n;
|
||||||
|
+ ngx_int_t rc, rv;
|
||||||
|
+ ngx_str_t host;
|
||||||
|
+ ngx_connection_t *c;
|
||||||
|
+ ngx_http_core_loc_conf_t *clcf;
|
||||||
|
+ ngx_http_request_t *r;
|
||||||
|
|
||||||
|
c = rev->data;
|
||||||
|
r = c->data;
|
||||||
|
|
||||||
|
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
+
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
|
||||||
|
"http process request line");
|
||||||
|
|
||||||
|
@@ -1060,10 +1063,10 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||||
|
ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
|
||||||
|
|
||||||
|
if (rc == NGX_HTTP_PARSE_INVALID_VERSION) {
|
||||||
|
- ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED);
|
||||||
|
+ (r->http_connection->ssl && clcf->strict_sni && clcf->strict_sni_header) ? ngx_http_terminate_request(r, 0) : ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
|
+ (r->http_connection->ssl && clcf->strict_sni && clcf->strict_sni_header) ? ngx_http_terminate_request(r, 0) : ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
@@ -1808,6 +1811,9 @@ ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||||
|
ngx_int_t
|
||||||
|
ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
|
{
|
||||||
|
+ ngx_http_core_loc_conf_t *clcf;
|
||||||
|
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
+
|
||||||
|
if (r->headers_in.server.len == 0
|
||||||
|
&& ngx_http_set_virtual_server(r, &r->headers_in.server)
|
||||||
|
== NGX_ERROR)
|
||||||
|
@@ -1818,7 +1824,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
|
if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||||
|
"client sent HTTP/1.1 request without \"Host\" header");
|
||||||
|
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
|
+ (r->http_connection->ssl && clcf->strict_sni && clcf->strict_sni_header) ? ngx_http_terminate_request(r, 0) : ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue