web-dev-qa-db-ja.com

nginxを使用して1つのポートで複数のTCPストリームをプロキシする方法

Nginx httpディレクティブを使用すると、同じポートに異なる名前の複数のサーバーを配置できます。

server {
    listen       80;
    server_name server1.example.com;
    location / {
      proxy_pass http://server1.example.com;
    }
}
server {
    listen       80;
    server_name server2.example.com;
    location / {
      proxy_pass http://server2.example.com;
    }
}

Httpの場合のように、nginxプロキシを複数のmysqlサーバーで同じポートに異なる名前で持つことは可能ですか?それらはクラスターの一部ではありません。には、関係のない別のテーブルがあります。

stream {
  upstream db1.example.com {
    server db1.example.com:3306;
    #server_name db1.example.com; "server_name" directive is not allowed here
  }
  upstream db2.example.com {
    server db2.example.com:3306;
  }

  server {
    listen 3306;
    proxy_pass db1.example.com;
  }
  #duplicate "3306" address and port pair
  #server { listen 3306; proxy_pass db2.example.com; }


}
6
joels

残念ながら、TCPにはサーバー名の概念がないため、これは不可能です。これは不可能です。HTTPでのみ機能します。クライアントがリクエストの一部としてアクセスしようとしているホスト名。NGINXが特定のサーバーブロックと照合できるようにします。

URLに基​​づいてTCPトラフィックを誘導することを本当に望んでいたので、非常に動揺しています。

2
fromage9747

nginx ssl preread module。 を使用して、SNIヘッダーに基づいて接続をダイレクトすることができます。

これは、接続を開くときにSNIヘッダーを指定するクライアントに依存します。

以下の例では、nginxはポート443で接続をリッスンします。presence.myglance.org:443への接続はポート4443に転送されます(これはhttpサーバーですが、ここでは表示されていません)。 present-s.myglance.org:443への接続は、ポート5502でリッスンしているストリームサーバーに転送されます。これにより、SSL接続が終了し、ポート6502に転送されます。

stream  {

    ############################################################
    ### logging
    log_format log_stream '$remote_addr [$time_local] $protocol [$ssl_preread_server_name] [$ssl_preread_alpn_protocols] [$internalport] '
        '$status $bytes_sent $bytes_received $session_time';

    error_log   /home/Logs/error.log debug;
    access_log  /home/Logs/access.log log_stream;

    ### https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html

    #########################################################################
    # Connections on 443 could be raw socket or https / wss
    # Distinguish between the two based on the SNI (preread server name)
    # Server names with -s are raw socket connections
    # Server names without -s are https or wss connections
    map $ssl_preread_server_name $internalport {
        presence-s.myglance.org      5502;
        presence.myglance.org        4443;
        default                      glance-no-upstream-instance;
    }

    # Note this does not terminate the ssl connection.  It just reads the SNI
    # header and forwards to the appropriate port
    server {
        listen                  443;
        ssl_preread             on;
        proxy_connect_timeout   20s;  # max time to connect to pserver
        proxy_timeout           30s;  # max time between successive reads or writes
        proxy_pass              127.0.0.1:$internalport;
    }    

    server {
        listen                 5502 ssl;
        ssl_preread            off;
        proxy_pass             127.0.0.1:6502;
    }
}
0
Debby Mendez