Sonntag, 19. August 2018

NGINX as a tls-enabled socket tunnel

The use-case of a TCP-tunnel with TLS might be somewhat esoteric, but nonetheless useful in certain situations. Imagine having two servers that need to talk to each other via TCP sockets, but the application should not be concerned with the extra overhead and configuration hassle of transport layer security. This is where NGINX comes into play. We use NGINX as a reverse proxy on both servers, effectively tunneling the TCP socket from one machine to the other via a TLS secured connection. The server initiating the connection is "Server A".



NGINX configuration on Server A:

stream {
       server {
               listen 127.0.0.1:10000;
               proxy_pass serverB:443;
               proxy_ssl  on;
               proxy_ssl_certificate client.cert.pem;
               proxy_ssl_certificate_key client.key.pem;
       }
}


NGINX configuration on Server B:

stream {
       server {
               listen 443 ssl;
               proxy_pass localhost:10000;
               ssl_certificate server.cert.pem;
               ssl_certificate_key server.key.pem;
               ssl_session_cache  builtin:1000  shared:SSLS:10m;
               ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
               ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
               ssl_prefer_server_ciphers on;
               ssl_client_certificate ca-chain.cert.pem;
               ssl_verify_client on;
               ssl_verify_depth 2;
       }
}

The used certificates can be self-signed, Server A uses client certificates that are signed by the ca-chain used in the configuration of Server B.