webserver-llc / angie

Angie - drop-in replacement for Nginx
https://angie.software/en/
BSD 2-Clause "Simplified" License
1.15k stars 64 forks source link

[feature request] SSL early data config option support for streams #60

Open pmkol opened 8 months ago

pmkol commented 8 months ago

Integrating 0-RTT for streams can enhance its capabilities. I suggest incorporating it into the source code.

diff -r 8cadaf7e7231 -r 5b16afc16eb9 src/stream/ngx_stream_ssl_module.c
--- a/src/stream/ngx_stream_ssl_module.c        Tue May 26 19:17:11 2020 +0300
+++ b/src/stream/ngx_stream_ssl_module.c        Mon Jun 01 11:57:12 2020 -0500
@@ -196,6 +196,13 @@
     offsetof(ngx_stream_ssl_conf_t, crl),
     NULL },

+    { ngx_string("ssl_early_data"),
+      NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_STREAM_SRV_CONF_OFFSET,
+      offsetof(ngx_stream_ssl_conf_t, early_data),
+      NULL },
+
     ngx_null_command
};

@@ -286,6 +293,9 @@
   { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
     (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },

+    { ngx_string("ssl_early_data"), NULL, ngx_stream_ssl_variable,
+      (uintptr_t) ngx_ssl_get_early_data, NGX_STREAM_VAR_CHANGEABLE, 0 },
+
     ngx_stream_null_variable
};

@@ -602,6 +612,7 @@
   scf->session_timeout = NGX_CONF_UNSET;
   scf->session_tickets = NGX_CONF_UNSET;
   scf->session_ticket_keys = NGX_CONF_UNSET_PTR;
+    scf->early_data = NGX_CONF_UNSET;

   return scf;
}
@@ -624,6 +635,8 @@
   ngx_conf_merge_value(conf->prefer_server_ciphers,
                        prev->prefer_server_ciphers, 0);

+    ngx_conf_merge_value(conf->early_data, prev->early_data, 0);
+
   ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
                        (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
                         |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
@@ -811,6 +824,10 @@
       return NGX_CONF_ERROR;
   }

+    if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
   return NGX_CONF_OK;
}

diff -r 8cadaf7e7231 -r 5b16afc16eb9 src/stream/ngx_stream_ssl_module.h
--- a/src/stream/ngx_stream_ssl_module.h        Tue May 26 19:17:11 2020 +0300
+++ b/src/stream/ngx_stream_ssl_module.h        Mon Jun 01 11:57:12 2020 -0500
@@ -54,6 +54,8 @@

   u_char          *file;
   ngx_uint_t       line;
+
+    ngx_flag_t      early_data;
} ngx_stream_ssl_conf_t;
vlhomutov commented 8 months ago

Hello.

I see that this patch is very similar to this one: https://mailman.nginx.org/pipermail/nginx-devel/2020-June/013211.html Is it the same patch or maybe you are an author?

AFAIK, the main reason it is not merged is the lack of ability to signal early data to application. In HTTP you can pass custom header with a value taken from corresponding variable, so the application can decide if it is willing to accept early data in this context or not (considering replay attacks). In stream, this is not possible: there is no means to pass anything extra to proxied application, what raises security questions.

Can you please elaborate on your specific use case? What protocol are you using and what benefit are you expecting?

pmkol commented 8 months ago

Hello.

I see that this patch is very similar to this one: https://mailman.nginx.org/pipermail/nginx-devel/2020-June/013211.html Is it the same patch or maybe you are an author?

AFAIK, the main reason it is not merged is the lack of ability to signal early data to application. In HTTP you can pass custom header with a value taken from corresponding variable, so the application can decide if it is willing to accept early data in this context or not (considering replay attacks). In stream, this is not possible: there is no means to pass anything extra to proxied application, what raises security questions.

Can you please elaborate on your specific use case? What protocol are you using and what benefit are you expecting?

I am not the patch author. I simply found improvement methods referenced in this patch. In the context of streaming, the 0-RTT feature is needed. For example, in the case of DNS over TLS (DoT), it involves encrypting TCP-based DNS traffic directly with SSL. Enabling 0-RTT enhances performance.

For simple requests like DNS, since it's possible to transmit the requester's IP to the backend DNS program using proxy_protocol, the backend only needs to impose limits on the number of requests per IP, which does not pose a security issue.