R. Moser
R. Moser

Reputation: 91

How to combine nginx tcp pass-through with ssl-preread and reverse-proxy functionality?

I'm trying to setup an nginx, whitch can, based on the domain name, pass through the encrypted tcp stream to another application or act like a reverse proxy offering own certificates.

I want to archive the following situation:

 https://app1.app.com ──► pass-through encrypted tcp to :10001
 https://app2.app.com ──► pass-through encrypted tcp to :10002
 https://app3.app.com ──► serve ssl, reverse-proxy to http://ip:10003

So without breaking the encrypted connection from Application 1 & 2, nginx should forward the tcp packets. The Certificates will be served by the applications themselves. Hostname Detection works with ssl_preread.

But Application 3 can only be reached over http, so nginx should serve the certificate itself and proxy everything from the specific hostname app3.app.com to the unencrypted Backend.

I have a working config for the first two situations and could set up the third situation, but can't figure out how to combine these two in a single nginx configuration.

What I have so far:

user www-data;
worker_processes  1;

load_module /usr/lib/nginx/modules/ngx_stream_module.so;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;
}

stream {
    map $ssl_preread_server_name $name {
        app1.app.de app1;
        app2.app.de app2;
        default default;
    }

    upstream app1 {
        server 127.0.0.1:10001 max_fails=3 fail_timeout=10s;
    }

    upstream app2 {
        server 127.0.0.1:10002 max_fails=3 fail_timeout=10s;
    }

    server {
        listen 8080;
        proxy_pass $name;
        ssl_preread on;
    }
}

If anyone can point me to the right direction, i'd be grateful!

Upvotes: 6

Views: 3171

Answers (1)

SensibleSalmon
SensibleSalmon

Reputation: 11

I solved this by having ssl-preread forward traffic I wanted the proxying server to handle to itself over localhost:

stream {
map $ssl_preread_server_name $name {
    app1.app.de app1;
    app2.app.de app2;
    app3.app.de localhost;
    default default;
}

upstream app1 {
    server 127.0.0.1:10001 max_fails=3 fail_timeout=10s;
}

upstream app2 {
    server 127.0.0.1:10002 max_fails=3 fail_timeout=10s;
}

upstream localhost {
    server localhost:444;
}
server {
    listen 8080;
    proxy_pass $name;
    ssl_preread on;
}
}

then listen normally in a sites-enabled conf and proxy (or directly serve) stuff as needed:

 server {
    listen 444 ssl http2;
    server_name app3.app.de;
    ssl_stuff_goes_here;
    location / {
        proxy_pass http://11.22.33.44:5678;
    }
 }

Note I set up the listen and forward on 444--I don't know if ssl_preread is clever enough to not forward stuff to itself, but I didn't feel like trying and finding out and since all the traffic is local anyway I figured it wouldn't matter.

Upvotes: 1

Related Questions