Opened 4 months ago

Closed 4 months ago

#1959 closed task (invalid)

Unexpected invalidation of embedded variables in ngx_http_ssl_module

Reported by: stevekerrison@… Owned by:
Priority: minor Milestone:
Component: documentation Version:
Keywords: ssl documentation variables scope Cc: stevekerrison@…
uname -a: Linux <obfuscated> #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.16.1
built by gcc 8.3.0 (Alpine 8.3.0)
built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/ --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fomit-frame-pointer' --with-ld-opt=-Wl,--as-needed


If certain ssl options are set in an http block, and related embedded variables referenced, but then if within a server block an option is overridden, previously referenced embedded variables may become null.

Skeleton example config:

http {
    ssl_verify_client on;

    proxy_set_header X-Client-Verify $ssl_client_verify;

    server {
        ssl_verify_client optional;
        proxy_pass ...;

Above, if $ssl_client_verify is logged by a log_format, it'll have a value, but in upstream servers I'm seeing X-Client-Verify as null, which presumably means it was never set.

However, if I do:

http {
    ssl_verify_client on;
    proxy_set_header X-Client-Verify $ssl_client_verify;

    server {
        ssl_verify_client optional;
        proxy_set_header X-Client-Verify $ssl_client_verify;
        proxy_pass ...;

Then the header is set as expected.

I believe this might be resolvable with a documentation update, as it's behaviour that seems to make sense if you know how nginx works. Indeed, I'd say there have been similar occurrences in other modules.

I think it needs to be made explicit how variables are affected by option scope. Perhaps it is somewhere else and I've missed it? In any case, I'm happy to propose some doc updates if some sort of consensus can be reached on the best way to do it.

Best regards,

Change History (3)

comment:1 by Sergey Kandaurov, 4 months ago

Please make sure you didn't inherit directives as documented, and report back.

These directives are inherited from the previous level if and only if
there are no proxy_set_header directives defined on the current level.

comment:2 by stevekerrison@…, 4 months ago

Hi Sergey,

Does that mean to say that all proxy_set_header from the upper level are ignored if any are set in the current level?

That would explain the issue.

If so, is there a way to make that a bit clearer in the documentation?

For example:

If any proxy_set_header directives are specified in the current level, then all proxy_set_header directives from the previous level are ignored.

That still leaves my understanding of the two default fields a bit fuzzy, however.

Please let me know if my understanding is correct.

Many thanks,

comment:3 by Sergey Kandaurov, 4 months ago

Resolution: invalid
Status: newclosed

So, it appeared that's the case. Thanks for feedback.

The existing documentation perfectly covers the proposed improvement
by using a biconditional logical connective ("if and only if").
I'm not sure it needs further clarification.

Note: See TracTickets for help on using tickets.