How to Build Transparent Encrypted Channels Between Data Centers with mTLS and Nginx
This guide explains how to securely connect two data‑center deployments over the public Internet by using TLS/mTLS, Certificate Authorities, and Nginx proxy configurations, providing step‑by‑step certificate generation, server and client setup, and both HTTP and TCP stream examples.
When deploying services across data centers without a dedicated line, traffic must traverse the public Internet, requiring security measures such as allowing only known IPs and encrypting the traffic.
Only allow known IPs (firewall or iptables).
Encrypt the traffic.
The article explains TLS/SSL fundamentals, the need for asymmetric encryption, how certificates prove identity, the role of Certification Authorities (CAs), and why certificate validation is essential.
TLS/SSL Principles
TLS encrypts data in transit and prevents man‑in‑the‑middle attacks. It uses a public‑key pair: the public key is published in a certificate, the private key remains secret. Data encrypted with the public key can only be decrypted with the private key, and the private key can sign data that anyone can verify with the public key.
During a TLS handshake the client downloads the server’s certificate, encrypts a random value with the server’s public key, and the server decrypts it with its private key, establishing a shared secret for symmetric encryption.
Beyond encryption, the client must also verify that the certificate is issued by a trusted CA and that the certificate belongs to the claimed domain.
Certificate Authority (CA) Role
A CA is a trusted third‑party that signs certificates after verifying the applicant’s ownership of the domain. Clients trust a CA’s root certificate stored locally (e.g., /etc/ssl/certs). The trust chain may include intermediate CAs.
CA responsibilities include protecting its private key, validating certificate requests, and revoking mis‑issued certificates promptly.
Mutual TLS (mTLS)
mTLS adds client authentication: after the server presents its certificate, the client also presents its own certificate, which the server validates against the same trusted CA.
Solution: Transparent Encrypted Channel with Nginx
Two Nginx instances are deployed, one in each data center, and they authenticate each other via mTLS. Applications send plain HTTP to the local Nginx, which encrypts the traffic to the remote Nginx.
Certificate Generation
Generate a CA key (password‑protected) and self‑signed root certificate:
$ openssl genrsa -des3 -out ca.key 4096
$ openssl req -new -x509 -days 365 -key ca.key -out ca.crtGenerate a server key and CSR, then sign it with the CA:
$ 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.crtGenerate a client key and certificate similarly.
Remote Nginx (Server) Configuration
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; }
}Run a FastAPI application on port 8000 behind this Nginx.
Local Nginx (Client) Configuration
upstream remote { server 127.0.0.1:443; }
server {
listen 80;
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;
}
}Clients can now curl the local Nginx (port 80) and the request is encrypted to the remote Nginx without modifying application code.
TCP Stream Proxy Example (Redis)
Replace the HTTP proxy with a TCP stream proxy to forward Redis traffic securely.
stream {
server {
listen 443 ssl;
proxy_pass 127.0.0.1:6379;
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;
}
}Local Nginx forwards port 80 to the remote stream using similar mTLS settings.
References are listed at the end of the original article.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
