如何将 nginx tcp 直通与 ssl 预读和反向代理功能结合起来?

R. *_*ser 6 ssl https tcp reverse-proxy nginx

我正在尝试设置一个 nginx,它可以根据域名将加密的 tcp 流传递到另一个应用程序,或者充当提供自己证书的反向代理。

\n\n

我想归档以下情况:

\n\n
 https://app1.app.com \xe2\x94\x80\xe2\x94\x80\xe2\x96\xba pass-through encrypted tcp to :10001\n https://app2.app.com \xe2\x94\x80\xe2\x94\x80\xe2\x96\xba pass-through encrypted tcp to :10002\n https://app3.app.com \xe2\x94\x80\xe2\x94\x80\xe2\x96\xba serve ssl, reverse-proxy to http://ip:10003\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,在不破坏应用程序 1 和 2 的加密连接的情况下,nginx 应该转发 tcp 数据包。证书将由申请本身提供。主机名检测与 ssl_preread 一起使用。

\n\n

但应用程序 3 只能通过 http 访问,因此 nginx 应该提供证书本身并代理从特定主机名app3.app.com到未加密后端的所有内容。

\n\n

我有一个适用于前两种情况的工作配置,并且可以设置第三种情况,但无法弄清楚如何将这两种情况组合到一个 nginx 配置中。

\n\n

到目前为止我所拥有的:

\n\n
user www-data;\nworker_processes  1;\n\nload_module /usr/lib/nginx/modules/ngx_stream_module.so;\n\nhttp {\n    include       /etc/nginx/mime.types;\n    default_type  application/octet-stream;\n\n    log_format  main  \'$remote_addr - $remote_user [$time_local] "$request" \'\n                      \'$status $body_bytes_sent "$http_referer" \'\n                      \'"$http_user_agent" "$http_x_forwarded_for"\';\n\n    access_log  /var/log/nginx/access.log  main;\n\n    sendfile        on;\n    keepalive_timeout  65;\n}\n\nstream {\n    map $ssl_preread_server_name $name {\n        app1.app.de app1;\n        app2.app.de app2;\n        default default;\n    }\n\n    upstream app1 {\n        server 127.0.0.1:10001 max_fails=3 fail_timeout=10s;\n    }\n\n    upstream app2 {\n        server 127.0.0.1:10002 max_fails=3 fail_timeout=10s;\n    }\n\n    server {\n        listen 8080;\n        proxy_pass $name;\n        ssl_preread on;\n    }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果有人能指出我正确的方向,我将不胜感激!

\n

小智 1

我通过使用 ssl 预读转发流量解决了这个问题,我希望代理服务器能够通过本地主机处理自身:

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;
}
}
Run Code Online (Sandbox Code Playgroud)

然后根据需要在启用站点的conf和代理(或直接服务)中正常监听:

 server {
    listen 444 ssl http2;
    server_name app3.app.de;
    ssl_stuff_goes_here;
    location / {
        proxy_pass http://11.22.33.44:5678;
    }
 }
Run Code Online (Sandbox Code Playgroud)

请注意,我在 444 上设置了监听和转发——我不知道是否ssl_preread足够聪明,不会将东西转发给自己,但我不想尝试找出答案,因为无论如何我认为所有流量都是本地的没关系。