Trying to use 'stream' for SSL Passthrough

My issue:

I want to use NGINX as a reverse proxy with SSL Passthrough (this is for an internal purpose and will not be exposed to the world).

I would like to be able to support a small number of different servers (using SNI?) but I’m nowhere near that at present.

I’m not familiar with NGINX so I’ve been relying on a number of internet “How To’s” but without success.

I understand that to use SSL Passthrough I need to configure NGINX in load balancing mode even though I’m only using one instance but, no matter what I do, I can’t seem to use the ‘stream’ directive.

I’ve got a very basic ‘nginx.conf’ (I’ve left the default server unchanged and it has these ‘includes’).

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
}

Based on one of the documents I’ve read I’ve created a new directory, /etc/nginx/tcpconf.d/ to make sure I don’t accidentally include the wrong thing in the ‘http’ section.

In that directory I have a basic config for a load balancer (example.conf):

upstream samplecluster {
server www.example.com:443;
}

server {
listen 443;
server_name www.example.com;

    location / {
            proxy_pass http://samplecluster/;
    }

}

But no matter where I put the ‘stream’; at the end of nginx.conf, in example.conf, elswhere I always get the ‘unknown directive’ message:

sudo nginx -t
nginx: [emerg] unknown directive “stream” in /etc/nginx/nginx.conf:101
nginx: configuration file /etc/nginx/nginx.conf test failed

I checked that nginx had been compiled with the stream options:

nginx -V 2>&1 | grep -o with-stream
with-stream
with-stream
with-stream

Based on another document I installed nginx–mod-stream which created a conf file, and related ‘include’ to load the module but which caused the config to fail.

Obviously I’m not comprehending what I’m reading or I’m missing some basic assumption that will make this all clear.

All suggestions and clarifications welcome. Thanks.

How I encountered the problem:

Solutions I’ve tried:

Version of NGINX or NGINX adjacent software (e.g. NGINX Gateway Fabric):

1.20.1 on AlmaLinux 9.7

Deployment environment:

Minimal NGINX config to reproduce your issue (preferably running on https://tech-playground.com/playgrounds/nginx for ease of debugging, and if not as a code block): (Tip → Run nginx -T to print your entire NGINX config to your terminal.)

NGINX access/error log: (Tip → You can usually find the logs in the /var/log/nginx directory.)

Hello,

I cannot yet understand everything of your issue, but here’s what I can already see to maybe help:

  1. from your nginx.conf extract, I don’t see where and how you put the “stream” directive. Given your explanations, I’d put it that way:

nginx.conf:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;
  include /etc/nginx/conf.d/*.conf;
}

stream {
  include /etc/nginx/tcpconf.d/*.conf;
}

Do you have something like that? Make sure to put the stream directive at the top level of the NGINX conf, and not inside the http block for example.

  1. Also, in your example.conf, I see you included a location / {} block. You cannot do that here: as you’re doing streaming, you’re explicitely telling NGINX not to care about the inside of the TCP packets (which are here encrypted TLS content). Therefore, you cannot tell NGINX to look for the URI requested and pass the requests for HTTP /* paths to your upstream server. Upstream is actually even simpler, you just tell NGINX to pass to the upsteam server, unchanged:

example.conf:

upstream backend {
    server www.example.com:443;
}

server {
  listen 443;
  server_name www.example.com;
  proxy_pass backend;
}

You have examples in the doc: https://nginx.org/en/docs/stream/ngx_stream_core_module.html

Also, for your further needs, you will need to use the NGINX SSL Pre-read module to do SNI routing with SSL Passthrough config. Again, you got simple working examples in the doc: Module ngx_stream_ssl_preread_module
Does it help?

Thanks very much for that.

After I posted, but before the post moved out of ‘Pending’ I finally found something that explicitly said I needed to load the stream module at the very top of nginx.conf ‘load_module /usr/lib64/nginx/modules/ngx_stream_module.so;’

(Not where the installer put the command).

That did the trick. I can now use the stream command. I’ve now got a ‘Permission denied’ message although I don’t know to what or why but that’s a separate question and more reading.

It’s possible that something I’ve done trying to get stream working has caused it.

Thanks for the clear explanation and the links, that gives me a good place to start for the next phase of learning.

Great, happy to hear it worked for you! Regarding the permissions, maybe you’d need to check if you got SELinux violations on your machine?
Anyway, good luck!