ssl_preread_server_name not extracted

Sergey Kandaurov pluknet at nginx.com
Tue Sep 12 09:40:34 UTC 2017


> On 12 Sep 2017, at 07:29, Brian <crazibri at gmail.com> wrote:
> 
> I have the following file named test.stream which is being included via nginx.conf  stream { include /etc/nginx/conf.d/*.stream; }
> 
> the ssl_preread_server_name variable is not being extracted and I’m running Nginx/1.13.5 (via centos 7 nginx repo).  Any idea whats going on here?  tcpdump shows the SNI field. 
> 
> nginx -V
> nginx version: nginx/1.13.5
> built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) 
> built with OpenSSL 1.0.1e-fips 11 Feb 2013
> TLS SNI support enabled
> 
> 
>    map $ssl_preread_server_name $name {
>        cm.example.com cm;
>        ut.example.com ut;
>    }
>    upstream ut {
>        server 10.0.0.76:9000;
>    }
>    upstream cm {
>        server 10.0.0.61:9000;
>    }
> 
>    log_format stream_routing '$remote_addr [$time_local] '
>                          'with SNI name "$ssl_preread_server_name" '
>                          'proxying to "$name" '
>                          '$protocol $status $bytes_sent $bytes_received '
>                          '$session_time';
> 
>    server {
>         listen 443 ssl;
> 
>         #Certificate & Key .PEM Format
>         ssl_certificate /etc/ssl/certs/internal_back.crt;
>         ssl_certificate_key /etc/ssl/certs/internal_back.key;
>         #CIPHERS
>         include /etc/nginx/conf.d/tcp.common;
> 
>         proxy_pass $name;
>         ssl_preread on;
>         access_log /var/log/nginx/stream.log stream_routing;
>         error_log /var/log/nginx/stream-error.log debug;
>    }
> 
> 

This is not going to work.
ssl_preread isn't designed to work with SSL-terminated connection,
as shown in your snippet, i.e. it won't work with “listen .. ssl”,
since it would parse SSL/TLS Application Data, but not Client Hello.

See for details:
https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

OTOH, once SSL is terminated, you may use $ssl_server_name variable:
http://nginx.org/en/docs/http/ngx_http_ssl_module.html#var_ssl_server_name

You could also exclude map{} by using $ssl_server_name in proxy_pass.

:    upstream cm.example.com {
:        server 10.0.0.61:9000;
:    }
:    upstream ut.example.com {
:        server 10.0.0.76:9000;
:    }

:    server {
:        listen 443 ssl;
:
:        proxy_pass $ssl_server_name;
:    }

The above simplification works with $ssl_preread_server_name as well:

:    upstream cm.example.com {
:        server 10.0.0.61:9000;
:    }
:    upstream ut.example.com {
:        server 10.0.0.76:9000;
:    }

:    server {
:        listen 443;
:
:        proxy_pass $ssl_preread_server_name;
:    }

OTOH, you may still want map{} to provide a default value,
if client didn’t sent SNI, or something, e.g.:

:    map $ssl_preread_server_name $name {
:        “”       default.fallback.value;
:        default  $ssl_preread_server_name;
:    }


-- 
Sergey Kandaurov



More information about the nginx mailing list