Opened 2 years ago

Closed 2 years ago

#1593 closed defect (wontfix)

Error selecting client certificate for proxy service

Reported by: Sergey Owned by:
Priority: major Milestone:
Component: nginx-module Version: 1.15.x
Keywords: Cc:
uname -a: Linux host1 3.16.0-5-amd64 #1 SMP Debian 3.16.51-3+deb8u1 (2018-01-08) x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.15.1
built by gcc 4.9.2 (Debian 4.9.2-10+deb8u1)
built with OpenSSL 1.0.1t 3 May 2016
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/nginx.pid --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 --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='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

Description

Test case

Certificate Verification Server

# cat debug_cert.conf

log_format ssl '[$time_local] rem_adr=$remote_addr upst_adr=$upstream_addr $upstream_status: $request response_time $upstream_response_time msec $msec request_time $request_time ssl: $ssl_client_s_dn';

server {
    listen 443 ssl;
    server_name localhost;
    ssl_certificate      /etc/nginx/ssl/server.crt;
    ssl_certificate_key  /etc/nginx/ssl/server.nopass.key;
    ssl_client_certificate /etc/nginx/ssl/ca.crt;
    ssl_verify_client on;



    client_max_body_size 3m;

    fastcgi_param SSL_VERIFIED $ssl_client_verify;
    fastcgi_param SSL_CLIENT_SERIAL $ssl_client_serial;
    fastcgi_param SSL_CLIENT_CERT $ssl_client_cert;
    fastcgi_param SSL_DN $ssl_client_s_dn;

    access_log /var/log/nginx/debug.access.log  ssl;
    error_log /var/log/nginx/debug.error.log;

    location / {
        root /var/www/html;
        index index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

Proxy

server {
  listen 9999;
  server_name host1;

  access_log   /var/log/nginx/test_access.log upstreamlog;
  error_log   /var/log/nginx/test_error.log;

    location /test1 {
        proxy_pass https://localhost:443/test1;
        proxy_ssl_certificate /etc/nginx/ssl/client01.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/client01.key;
    }
    location /test2 {
        proxy_pass https://localhost:443/test2;
        proxy_ssl_certificate /etc/nginx/ssl/client02.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/client02.key;
    }
}

We periodicaly call from the browser different locations (/test1 and /test2)

# curl http://host1:9999/test1
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.1</center>
</body>
</html>

# curl http://host1:9999/test2
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.1</center>
</body>
</html>

According to the configuration, the location test1 corresponds to the Client01 certificate. Location test2 corresponds to the Client02 certificate

But in logs for Certificate Verification Server the location does not always match the certificate

[09/Jul/2018:10:04:38 +0300] rem_adr=127.0.0.1 upst_adr=- -: GET /test1 HTTP/1.0 response_time - msec 1531119878.304 request_time 0.000 ssl: emailAddress=support@site.com,CN=etc,OU=Client02,O=Companyname,L=Moscow,ST=Moscow,C=RU
[09/Jul/2018:10:04:39 +0300] rem_adr=127.0.0.1 upst_adr=- -: GET /test2 HTTP/1.0 response_time - msec 1531119879.551 request_time 0.000 ssl: emailAddress=support@site.com,CN=etc,OU=Client02,O=Companyname,L=Moscow,ST=Moscow,C=RU

[09/Jul/2018:10:06:36 +0300] rem_adr=127.0.0.1 upst_adr=- -: GET /test1 HTTP/1.0 response_time - msec 1531119996.240 request_time 0.000 ssl: emailAddress=support@site.com,CN=etc,OU=Client01,O=Companyname,L=Moscow,ST=Moscow,C=RU
[09/Jul/2018:10:06:39 +0300] rem_adr=127.0.0.1 upst_adr=- -: GET /test2 HTTP/1.0 response_time - msec 1531119999.504 request_time 0.000 ssl: emailAddress=support@site.com,CN=etc,OU=Client01,O=Companyname,L=Moscow,ST=Moscow,C=RU

Change History (1)

comment:1 by Maxim Dounin, 2 years ago

Resolution: wontfix
Status: newclosed

Both locations use localhost:443 as an upstream server, and hence can reuse each other SSL sessions. As such, in the configuration provided the certificate (as well as other SSL parameters) will be determined by the location where the session was initially negotiated.

Switching off proxy_ssl_session_reuse should resolve this. Alternatively, the configuration can be changed to use distinct upstream names and hence distinct SSL session caches:

upstream localhost1 {
    server 127.0.0.1:443;
}

upstream localhost2 {
    server 127.0.0.1:443;
}

server {
    ...

    location /test1 {
        proxy_pass https://localhost1/test1;
        proxy_set_header Host localhost;
        proxy_ssl_certificate /etc/nginx/ssl/client01.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/client01.key;
    }
    location /test2 {
        proxy_pass https://localhost2/test2;
        proxy_set_header Host localhost;
        proxy_ssl_certificate /etc/nginx/ssl/client02.crt;
        proxy_ssl_certificate_key /etc/nginx/ssl/client02.key;
    }
}
Note: See TracTickets for help on using tickets.