NGINX : How to configure mutual authentication for TCP Upstream

nginxssltls

The particular feature I am interested about about SSL termination for TCP Upstream. I am evaluating both NGINX Open Source and NGINX Plus.

We have an application which accepts messages (TCP) over TLS from clients. With NGINX, I want to terminate TLS at NGINX and then NGINX will forward the decrypted packets to the application. Please note my application does NOT receive message over HTTP, but over TCP (Hence HTTP(S) related modules are not valid for my use case).

Client(s) –(TLS)–> NGINX –(Decrypted)–> Application

I have configured NGINX for TCP load balancing following this document (Non-SSL). For that I have to build the source code with the following two modules:

  1. ngx_stream_core_module
  2. ngx_stream_ssl_module

Now, I want to enable mutual authentication with SSL between NGINX and the clients. I am seeing this documentation which talks about server side authentication (client verifying server's certificate), but I am not able to find out the steps to configure mutual authentication (both client and server verifying each other's certificates). Could you please help me there? In the "ngx_stream_ssl_module" I don't find any option to mention client certificate.

Following is the content of my nginx.conf:

stream {
      server {
        listen *:5222 ssl;
        proxy_pass backend;
        ssl_certificate      /usr/local/nginx/certs/server.crt;
        ssl_certificate_key  /usr/local/nginx/certs/server.key;
        ssl_protocols         SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers           HIGH:!aNULL:!MD5;
        ssl_session_cache     shared:SSL:20m;
        ssl_session_timeout   4h;
        ssl_handshake_timeout 30s;
      }

      upstream backend {
        server 0.0.0.0:5223;
      }
}

Also I want to allow (SSL handshake) only if client has a specific identity (may be based on the client's identifier/unique name). Is there any way to do it using NGINX or NGINX Plus?

Any other suggestion will be appreciated.

Best Answer

Looks Like the Module ngx_stream_ssl_module doesn't support these directive ssl_client_certificate, ssl_verify_client

stream {
          server {
            listen *:5222 ssl;
            proxy_pass backend;
            ssl_certificate      /usr/local/nginx/certs/server.crt; # Can Include the Chain
            ssl_certificate_key  /usr/local/nginx/certs/server.key;
            ssl_protocols         TLSv1 TLSv1.1 TLSv1.2; # Removed SSLv3
            ssl_ciphers           HIGH:!aNULL:!MD5;
            ssl_session_cache     shared:SSL:20m;
            ssl_session_timeout   4h;
            ssl_handshake_timeout 30s;

            ssl_client_certificate  /usr/local/nginx/certs/ca.chain.cert.pem;
            ssl_verify_client on;
            ssl_verify_depth 2;
          }

          upstream backend {
            server 0.0.0.0:5223;
          }
    }

enter image description here