Nginx SSL pass through

In most of the configuration we terminate the SSL at the load balancer and use http connection from load balancer to the server when it is in internal network. But in some situation we needed SSL pass through such as if the server is handling the SSL certificates.

For example, in my home network, I use nginx server inside my DMZ zone and then redirect the applicable traffic to my docker swarm network. Inside my docker swarm network I run Traefik load balancer and it auto detect services and handles SSL certificate generation and renewal. So I wanted to use the SSL pass through from my nginx load balancer to avoid creating configuration manually for services in my docker stacks.

For nginx SSL pass through we need to use stream server block not the http server block. For the you need to have the nginx stream module installed. Use the following command to see if you have the stream module installed.

ls /etc/nginx/modules-available

In the above command if you see a file listed with name “50-mod-stream.conf” or similar you have the stream module available to you.

If the module is not available, install the nginx additional modules using below command.

apt-get install nginx-extras

Please list the files again in modules-available directory to make sure the mod-stream module is available now using below command.

ls /etc/nginx/modules-enabled

Enable the stream module by creating a link from modules-available directory to the modules-enabled directory using below command.

ln -s /etc/nginx/modules-available/50-mod-stream.conf /etc/nginx/modules-enabled/50-mod-stream.conf

Now we need to create a stream block. Please edit the /etc/nginx/nginx.conf to include statement outside of the http block. We do this because we need to include configuration for the stream block, which signals to Nginx to expect TCP traffic. We can’t use stream inside of an http block.

http {
    # ...

# Add this include statement
include /etc/nginx/tcpconf.d/*;

Now create a directory tcpconf.d using below command.

mkdir -p /etc/nginx/tcpconf.d

Now create and open a configuration file lb.conf using below command

nano /etc/nginx/tcpconf.d/lb.conf

Add below content inside the created file. You can add multiple server under upstream web_server if you want to load balance between many servers. Also inside the server block the upstream defined is referred.

stream {
    upstream web_server {

    server {
        listen 443;
        proxy_pass web_server;

Test whether configuration looks fine using below command

nginx -t

If the result is successful, reload the nginx server and test whether your reverse proxy server is hit when you access the server.

nginx -s reload

After this if you send any traffic to the nginx server it will be routed to your targetted server in the stream block. SSL connections will be handled by the targetted server and nginx server is not aware of the content passed through as the connections are handled as TCP stream traffic.

If you are planning to terminate the traffic in nginx then you don’t have to follow the above steps, you can simply define your upstream inside http server block. Your nginx server needs to handle the ssl certificates.


Leave a Reply

Your email address will not be published. Required fields are marked *