Opened 13 months ago

Last modified 3 months ago

#2562 new enhancement

SSL: use server names from upstream configuration for proxied server's name validation

Reported by: lyokha@… Owned by:
Priority: minor Milestone:
Component: nginx-core Version:
Keywords: Cc:
uname -a: Linux fedora 6.5.10-300.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Nov 2 20:01:06 UTC 2023 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.25.4
built by gcc 13.2.1 20231011 (Red Hat 13.2.1-4) (GCC)
built with OpenSSL 3.1.1 30 May 2023
TLS SNI support enabled
configure arguments: --with-http_ssl_module --with-stream --with-stream_ssl_module --with-http_stub_status_module --add-module=/home/lyokha/Загрузки/echo-nginx-module-0.63 --add-module=/home/lyokha/devel/nginx-combined-upstreams-module --add-module=/home/lyokha/devel/nginx-custom-counters-module --add-module=/home/lyokha/devel/nginx-easy-context --add-module=/home/lyokha/devel/nginx-haskell-module --add-module=/home/lyokha/devel/nginx-haskell-module/aliases --add-module=/home/lyokha/devel/nginx-haskell-module/examples/dynamicUpstreams/nginx-upconf-module --add-dynamic-module=/home/lyokha/devel/nginx-healthcheck-plugin --add-dynamic-module=/home/lyokha/devel/nginx-log-plugin --add-dynamic-module=/home/lyokha/devel/nginx-log-plugin/module

Description

This is a feature request (with a basic implementation).

My scenario requires to validate server names against names found in the server directive in an upstream. For example,

upstream u1 {
    server su1.blah.com;
    server su2.blah.com;
}

By default, all peers from upstream u1 will be validated against name u1 which is what variable $proxy_host contains. I want to validate them dynamically according to which name is bound to the chosen peer (i.e. su1.blah.com or su2.blah.com).

Currently, this seems to be not feasible. However, this can be achieved with a few additions into Nginx code. Basically, the additions include

  1. A new no-cacheable variable, say $proxy_peer_host, which will contain the server name of the current peer.
  2. Pushing server name available in the round-robin peer structure into the peer_connection structure.

The peer connection data is available at the time of server name validation, therefore proxy_ssl_name $proxy_peer_host; shall work.

I will attach the patch.

Here is an Nginx configuration which I used to test this:

user                    nobody;
worker_processes        1;

events {
    worker_connections  1024;
}

http {
    default_type        application/octet-stream;
    sendfile            on;

    upstream u1 {
        server 127.0.0.1:8080;
        server localhost:8080;
    }

    server {
        listen       8010;
        server_name  main;

        location /u1 {
            proxy_ssl_verify on;
            proxy_ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
            proxy_ssl_name $proxy_peer_host;
            proxy_pass https://u1;
        }
    }

    server {
        listen       8080 ssl;
        server_name  backend;

        ssl_certificate     /home/lyokha/devel/nginx/certs/server/server.crt;
        ssl_certificate_key /home/lyokha/devel/nginx/certs/server/server.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers         HIGH:!aNULL:!MD5;

        location / {
            echo "In $server_name";
        }
    }
}

Attachments (2)

proxy_peer_host.patch (6.6 KB ) - added by lyokha@… 13 months ago.
nginx.conf (997 bytes ) - added by lyokha@… 13 months ago.

Download all attachments as: .zip

Change History (3)

by lyokha@…, 13 months ago

Attachment: proxy_peer_host.patch added

by lyokha@…, 13 months ago

Attachment: nginx.conf added

comment:1 by lyokha@…, 3 months ago

Don't worry. I implemented this in a separate module without patching Nginx. For those who want to have a look, here it is: https://github.com/lyokha/nginx-proxy-peer-host.

Note: See TracTickets for help on using tickets.