Implementing Transparent Encrypted Communication with mTLS Using Nginx and OpenSSL
This article explains how to secure cross‑data‑center traffic by applying TLS principles, setting up a private Certificate Authority, generating self‑signed certificates with OpenSSL, configuring mutual TLS (mTLS) on Nginx proxies for both HTTP and TCP streams, and verifying the setup with curl and redis‑cli commands.
When deploying services across separate data centers without a dedicated line, traffic must traverse the public Internet, requiring two security measures: allowing only known IPs and encrypting the traffic. The article first reviews TLS fundamentals, describing how asymmetric encryption, certificates, and Certificate Authorities (CAs) provide confidentiality and authentication.
It then introduces mutual TLS (mTLS) as a way for both client and server to verify each other's identities, comparing it to SSH key verification and Git's trust model.
Solution Overview : Two Nginx instances (one in each data center) perform mTLS termination. Applications send plain HTTP to the local Nginx, which encrypts the traffic to the remote Nginx, making the encryption transparent to the applications.
Certificate Generation :
openssl genrsa -des3 -out ca.key 4096 openssl req -new -x509 -days 365 -key ca.key -out ca.crt openssl genrsa -out server.key 4096 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crtSimilar steps are repeated to create a client certificate (client.key, client.crt).
Remote Nginx (Server) Configuration (HTTPS version):
server {
listen 443 ssl;
server_name _;
ssl_certificate /home/vagrant/cert/server.crt;
ssl_certificate_key /home/vagrant/cert/server.key;
ssl_verify_client on;
ssl_client_certificate /home/vagrant/cert/ca.crt;
location / { proxy_pass http://127.0.0.1:8000; }
}Local Nginx (Client) Configuration (HTTP to remote HTTPS):
upstream remote{ server 127.0.0.1:443; }
server {
listen 80 default_server;
location / {
proxy_pass https://remote;
proxy_ssl_trusted_certificate /home/vagrant/cert/ca.crt;
proxy_ssl_verify on;
proxy_ssl_server_name on;
proxy_ssl_name proxy.example.com;
proxy_ssl_certificate /home/vagrant/cert/client.crt;
proxy_ssl_certificate_key /home/vagrant/cert/client.key;
}
}Testing with curl shows that a plain HTTP request to the local Nginx is forwarded securely to the remote service, while the client and server certificates are validated automatically.
For TCP streams (e.g., Redis), the same approach is applied using the stream block in Nginx, with analogous server and client configurations.
References to official Nginx documentation, CA best practices, and TLS hand‑shake details are provided at the end of the article.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.