skip to Main Content

This is a very reduced configuration for nginx, which should use different configurations for TLS connections, based on SNI names.
Some of them need additional client authentication via client certificates.
When I try to configure it, nging -t claims, that the mapped variable is not valid for ssl_verify_client:
invalid value "$svc" in /etc/nginx/sites-enabled/default:24
The configuration looks like:

stream {
  map $ssl_preread_server_name $name {
    default           server_one;
    two.example.org   server_two;
  }  
  
  map $ssl_preread_server_name $authen_cert {
    default           "/etc/nginx/public.cert";
    two.example.org   "None";
  }  
  
  map $ssl_preread_server_name $svc {
    default           "on";
    two.example.org   "off";
  }

  server {
    listen 127.0.0.1:3128 ssl;
    ssl_protocols TLSv1.2 TLSv1.3; 
    ssl_certificate /etc/letsencrypt/live/$name/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$name/privkey.pem;
    ssl_client_certificate $authen_cert ;
    #set $svc ="off";
    ssl_verify_client $svc ;
    proxy_pass 127.0.0.2:3128;
  }    
}

I tried different names for the variable, guessing that I had an conflict with some predefined stuff, but no matter, how I name this variable, or if I set it explicitly before the statement, the error message is the same.
The position of the map block makes also no difference.
I can map the arguments for all other statements to variables without any problem.
I tried finally also an if-block for both verification related lines, but this also gives an error:
"if" directive is not allowed here
So I am clueless, how I shall configure this.

nginx is: nginx version: nginx/1.22.1
system is: SMP PREEMPT_DYNAMIC Debian 6.1.90-1

Thanks for any hints

Thanks to Lana Codes I could overcome the first error, with ssl_verify_client. But after that was fixed, I got the same error message for ssl_client_certificate . I fixed this with setting a fixed path to a file, containing several client certificates, as verification is now optional.
OK, now the configuration test was ok, but I learned, that the mapping itself is not working. If I omit the default, I get no connection at all.

All, what I want to create, is a simple TLS-Termination service, which passes the unencrypted stream to an unencrypted plain tcp application.

I tried with different variations in the configuration:

  • the keyword ssl behind the listen statement
    like in the above example: I see no SNI name recognition in the logs, but an empty map and finally no certificate found, as the variable is unset
  • without the keyword ssl behind the listen statement
    Now I see a SNI recognition, but no map and no signs, that nginx tries to terminate TLS, the connection fails.
  • I tried to have ssl_pre_read on in the server or the stream block, I tried it in both blocks, all the time the configuration is valid, but not working as expected.

2

Answers


  1. Chosen as BEST ANSWER

    OK, every works, when I just replace $ssl_preread_server_name with $ssl_server_name Thanks again for the help!


  2. Yeah if is not allowed in stream, got to use maps. Try setting ssl_verify_client optional; and the sniffing the $ssl_client_verify variable for a NONE value. This should work or at least get you close.

    stream {
      map $ssl_preread_server_name $name {
        default           server_one;
        two.example.org   server_two;
      }  
      
      map $ssl_preread_server_name $authen_cert {
        default           "/etc/nginx/public.cert";
        two.example.org   "None";
      }  
      map $ssl_client_verify $no_client_cert_sent {
        default           0;
        NONE              1;
      }
      map $ssl_preread_server_name $allow_no_client_cert_server_name {
        default           0;
        two.example.org   1;
      }
      map $no_client_cert_sent$allow_no_client_cert_server_name $proxy {
        default 127.0.0.2:3128; # default proxy along
        # if $ssl_client_verify = NONE && $ssl_preread_server_name NOT IN allow list
        # then proxy to server that only returns 496 cert required
        10      127.0.0.1:8888; 
      }
    
      # dead end proxy for clients that sent no cert without being in the allow map
      server {
        listen 127.0.0.1:8888;
        return 469;
      }
    
      server {
        listen 127.0.0.1:3128 ssl;
        ssl_protocols TLSv1.2 TLSv1.3; 
        ssl_certificate /etc/letsencrypt/live/$name/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/$name/privkey.pem;
        ssl_client_certificate $authen_cert ;
        ssl_verify_client optional;
        proxy_pass $proxy;
      }    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search