基于域名的Nginx TCP转发

Posted

技术标签:

【中文标题】基于域名的Nginx TCP转发【英文标题】:Nginx TCP forwarding based on domain name 【发布时间】:2017-04-12 22:15:12 【问题描述】:

我正在尝试在 2 个不同的服务器前使用 nginx 代理

example.com , example1.com >> nginx 10.0.0.1 >>>> 10.0.0.2 , 10.0.0.3

 stream 


server 
 listen 1935;
    proxy_pass 10.0.0.2:1936;
          proxy_protocol on;

server 
 listen 1935;
    proxy_pass 10.0.0.3:1936;
          proxy_protocol on;



我已经检查了 tcp load balance guide 但我找不到如何让它工作

【问题讨论】:

提醒一下,load balance guide 用于 NGINX PLUS,它是 NGINX 的商业版本。 【参考方案1】:

虽然TCP/UDP协议中没有server_name,但是你可以根据$server_addr将流量转发到不同的上游。我的例子在这里:https://***.com/a/44821204/5085270

【讨论】:

【参考方案2】:

我认为使用 nginx 不可能做到这一点。然而,这可以通过 HAproxy 轻松完成。 HAProxy 可以通过基于 SNI(服务器名称指示)的加密流量,它是 TLS 协议的扩展。

./haproxy/haproxy.cfg

defaults
  maxconn 1000
  mode http
  log global
  option dontlognull
  timeout http-request 5s
  timeout connect 5000
  timeout client 2000000 # ddos protection
  timeout server 2000000 # stick-table type ip size 100k expire 30s store conn_cur

frontend https
  bind *:443
  mode tcp
  option tcplog
  tcp-request inspect-delay 5s
  tcp-request content accept if  req_ssl_hello_type 1 
  use_backend app1-servers if  req.ssl_sni -i example1.com   # <--- specify domain name here
  use_backend app2-servers if  req.ssl_sni -i example2.com 

backend app1-servers
  mode tcp
  balance roundrobin
  option ssl-hello-chk
  server server1 10.0.0.2:443     # <--- specify IP here

backend app2-servers
  mode tcp
  balance roundrobin
  option ssl-hello-chk
  server server1 10.0.0.3:443

【讨论】:

【参考方案3】:

根据tcp load balancing page of nginx中的例子

试试这个例子:

stream 
  upstream rtmp_servers 
    least_conn;
    server  10.0.0.2:1935;
    server  10.0.0.3:1935;
  


server 
    listen     1935;
    server_name example.com, example1.com;
    proxy_pass rtmp_servers;

【讨论】:

谢谢,但这里不允许“服务器”指令不起作用,我无法在 http 中添加它 你能解释一下你把这段代码放在哪里吗? 在 nginx.conf 中,我有 http server proxy port 80 etc 然后流 code ,尝试代理端口 80 http 和端口 1935 1936 rtmp【参考方案4】:

我们使用 tcp 转发到后端 docker swarm 集群,使用 ha-proxy 在 haproxy.cfg 中使用以下简单配置

global
    log 127.0.0.1 local0 debug

defaults
    log     global
listen l1
    bind 0.0.0.0:443
    mode tcp
    timeout connect  4000
    timeout client   180000
    timeout server   180000
    server swarm_node1 x.x.1.167:443
    server swarm_node2 x.x.1.168:443
    server swarm_node3 x.x.1.169:443

【讨论】:

【参考方案5】:

使用server_name 指令来确定哪个服务器块用于给定请求。

server 
    listen 1935;
    server_name example.com;
    location / 
        proxy_pass 10.0.0.1:1936;

        # the usual proxy_* stuff
    

server 
    listen 1935;
    server_name example1.com;
    location / 
        proxy_pass 10.0.0.2:1936;

        # the usual proxy_* stuff
    

来源:http://nginx.org/en/docs/http/server_names.html

【讨论】:

我已经在端口 80 上使用它,并且流是用于 rtmp 的,它会给出重复的 no? @Tan Hong Tat,如果我错了,请纠正我,但 server_name 仅适用于 http 块,而不是 stream 块,看起来 @Lolak 需要这样做代理 rtmp 连接。 这个例子永远不会起作用,因为 server_name 指令只允许用于 http 块。

以上是关于基于域名的Nginx TCP转发的主要内容,如果未能解决你的问题,请参考以下文章

linux12k8s -->08ingress nginx基于域名的网络转发资源

Nginx虚拟主机配置

nginx配置多域名 https 转发

nginx虚拟主机#yyds干货盘点#

nginx以upstream分组的方式实现tcp反向代理

Nginx使用