Score:0

Nginx: Why is $host variable not available in stream directive in nginx.conf?

uy flag

in my nginx.conf I would like to pass the request depending on the requested url to a specific server infrastructure.

Everything works great apart from the $host variable. I get error "nginx: [emerg] unknown "host" variable"

From my understanding is $host a regular variable and I dont have to declare it first.. in fact its used in the http directive above without problems:

http {
    ...
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    ...
}

But in stream it is a problem...

stream {
        map $ssl_server_name $targetBackendSSL {
            test1.example.com  192.168.1.1:22553;
            test2.example.com  192.168.1.2:22553;
        }
        
        map $host $targetBackendNonSSL {
            test1.example.com  192.168.1.9:22553;
            test2.example.com  192.168.1.10:22553;
        }
        
        # ssl
        server {
                listen 8000 ssl;
                listen [::]:8000 ssl;
                ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
                ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem;
                ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem;
                proxy_connect_timeout 300s;
                proxy_pass $targetBackendSSL;
        }
        
        # non-ssl
        server {
                listen 8001;
                listen [::]:8001;  
                proxy_connect_timeout 300s;
                proxy_pass $targetBackendNonSSL;
        }
}

Any help appreciated! :-)

Score:2
jp flag
  1. The stream{} block handles TCP and UDP Load Balancing.

  2. The $host variable comes from a HTTP request.

    $host
    in this order of precedence: host name from the request line, or host name from the “Host” request header field, or the server name matching a request

Such information is not commonly available in TCP or UDP streams, as it is a concept of the HTTP protocol. Therefore, it is impossible to have such a variable.

The $ssl_server_name, on the other hand, comes from the Server Name Indication (SNI), which is a TLS extension (RFC 6066, 3). It is available on protocols that provides this information in the extended client hello. Not all TLS wrapped TCP protocols support SNI; your detection is not reliable.

user3740082 avatar
uy flag
Thank you! Makes total sense now.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.