流中的NGINX位置指令

时间:2019-12-02 07:35:27

标签: nginx

我已经在我的一台服务器上安装了Nginx,以便用作我的Rancher应用程序的负载平衡器。 我的配置基于此处找到的配置:https://rancher.com/docs/rancher/v2.x/en/installation/ha/create-nodes-lb/nginx/

所以我的配置是:

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

worker_processes 4;
worker_rlimit_nofile 40000;

events {
    worker_connections 8192;
}

stream {
    upstream rancher_servers_http {
        least_conn;
        server <ipnode1>:80 max_fails=3 fail_timeout=5s;
        server <ipnode2>:80 max_fails=3 fail_timeout=5s;
        server <ipnode3>:80 max_fails=3 fail_timeout=5s;
    }
    server {
        listen     80;

        proxy_pass rancher_servers_http;
    }

    upstream rancher_servers_https {
        least_conn;
        server <ipnode1>:443 max_fails=3 fail_timeout=5s;
        server <ipnode2>:443 max_fails=3 fail_timeout=5s;
        server <ipnode3>:443 max_fails=3 fail_timeout=5s;
    }
    server {
        listen     443;
        proxy_pass rancher_servers_https;
    }
}

我的配置按预期工作,但是我最近在群集上安装了Nextcloud。这给了我以下错误:

  
      
  • 您的Web服务器未正确设置为解析“ /.well-known/caldav”。有关更多信息,请参见   文档。

  •   
  • 您的Web服务器未正确设置为解析“ /.well-known/carddav”。有关更多信息,请参见   文档。

  •   

因此,我想添加一个“位置”指令,但无法执行。 我尝试按照以下方式更新配置:

...

stream {
    upstream rancher_servers_http {
        ...
    }
    server {
        listen     80;
        proxy_pass rancher_servers_http;

        location /.well-known/carddav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
        location /.well-known/caldav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
    }

    upstream rancher_servers_https {
        ...
    }
    server {
        listen     443;
        proxy_pass rancher_servers_https;

        location /.well-known/carddav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
        location /.well-known/caldav {
            return 301 $scheme://$host:$server_port/remote.php/dav;
        }
    }
}

但这是在告诉我

  /etc/nginx/nginx.conf:21

中不允许使用

“位置”指令

假设在流配置中不允许使用位置指令,我试图添加如下所示的http块:

...

stream {
    ...
}

http {
  server {
      listen 443;

      location /.well-known/carddav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
      }
      location /.well-known/caldav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
      }
   }
  server {
      listen 80;

      location /.well-known/carddav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
      }
      location /.well-known/caldav {
        return 301 $scheme://$host:$server_port/remote.php/dav;
      }
   }
}

但是我得到了以下消息:

  

bind()到0.0.0.0:443失败(98:地址已在使用中)

(与端口80相同)。

有人可以帮我吗?如何在不影响我的实际配置的情况下添加location指令?

感谢您阅读。

修改

好象stream指令阻止了我添加其他标准指令。我试图在client_max_body_size内添加server,但遇到相同的问题:

  

此处不允许使用指令

1 个答案:

答案 0 :(得分:0)

现在,您的设置将nginx用作TCP代理。 Nginx的这种配置无需分析即可通过流量-可以是ssh,rdp,无论任何流量,并且无论协议如何都可以工作,因为nginx不会检查流内容。

这就是位置指令在流上下文中不起作用的原因-它是与HTTP协议相关的功能。

要利用高级协议分析,nginx需要知道通过它的协议,即将其配置为HTTP反向代理。

要使其正常工作,服务器指令应放在http作用域而不是流作用域中。

http {
  server {
    listen 0.0.0.0:443 ssl;
    include /etc/nginx/snippets/letsencrypt.conf;
    root /var/www/html;
    server_name XXXX;

    location / {
        proxy_pass http://rancher_servers_http;
    }
    location /.well-known/carddav {
      proxy_pass http://$host:$server_port/remote.php/dav;
    }
    location /.well-known/caldav {
      proxy_pass http://$host:$server_port/remote.php/dav;
    }
  }

  server {
    listen 80 default_server;
    listen [::]:80 default_server;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root /var/www/letsencrypt;
    }
    root /var/www/html;
    server_name xxxx;

    location / {
        proxy_pass http://rancher_servers_http;
    }
  }
}

此方法的缺点是需要重新配置证书管理。 但是您将把ssl加密加载到nginx并基于http查询获得智能平衡。