【问题标题】:Nginx Multi-Workload Config - Website & Reverse ProxyNginx 多工作负载配置 - 网站和反向代理
【发布时间】:2019-09-12 19:37:42
【问题描述】:

TLDR:我正在尝试将 Nginx 配置为托管网站并同时充当反向代理。该网站位于“www.example.com:443”上,反向代理指向“vpn.example.com:443”上的单独 OpenVPN 服务器。我想我知道答案是“无法将 Nginx 配置为在单个端口上侦听两种不同类型的流量”(网络流量和反向代理流量),但我想我会问那些更有知识的人。

现在,进入更冗长的版本。我确实有一个看起来像这样的工作设置:

               +-----------------------+
               |                       |
               |         Nginx         |
               |    (Rev Proxy Only)   |
               |                       |
               |     192.168.0.100     |
               |  vpn.example.com:443  |
               |  www.example.com:443  |
               |                       |
               +-----------------------+
                 /                   \
                /                     \
+-----------------------+    +-----------------------+
|                       |    |                       |
|        OpenVPN        |    |       LAMP Stack      |
|         (VPN)         |    |        (Website)      |
|                       |    |                       |
|     192.168.0.101     |    |     192.168.0.102     |
|  vpn.example.com:443  |    |  www.example.com:443  |
|                       |    |                       |
+-----------------------+    +-----------------------+

这里有几个注意事项。 Nginx (v1.14.2) 服务器是 CentOS v7.6。它配置了“--with-stream”和“--with-stream_ssl_preread_module”。它还使用 /etc/nginx/nginx.conf 中的所有默认值,除了它包含一个带有 proxy_pass 的 stream{} 块。 conf 文件如下所示:

/etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

include /etc/nginx/proxy.conf;

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;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/proxy.conf

stream {

    map $ssl_preread_server_name $name {
        www.example.com lamp;
        vpn.example openvpn;
        default https_default_backend;
    }

    server {
        listen 192.168.0.100:443;
        proxy_pass $name;
        ssl_preread on;
    }

    upstream lamp {
        server 192.168.0.102:443;
    }

    upstream openvpn {
        server 192.168.0.101:443;
    }

    upstream https_default_backend {
        server 192.168.0.101:443;
    }

    log_format basic '[$time_local] $remote_addr - $protocol '
                     'STATUS: $status BYTES_SENT: $bytes_sent '
                     'BYTES_RECEIVED: $bytes_received '
                     'SENT_TO: $upstream_addr MSECS: $msec '
                     'SESSION_TIME: $session_time '
                     'UPSTREAM_BYTES_SENT: $upstream_bytes_sent '
                     'UPSTREAM_BYTES_RECEIVED: $upstream_bytes_received '
                     'UPSTREAM_CONNECTION_TIME: $upstream_connect_time"';

    access_log /var/log/nginx/stream.mfgs.dev_access.log basic;
    error_log  /var/log/nginx/stream.mfgs.dev_error.log;

}

再一次,这是我当前的配置,这里的一切正常。网站流量流式传输到 Web 服务器,VPN 流量流式传输到 VPN 服务器。所有这些都有效。

我的目标是将 LAMP 堆栈(Linux、Apache、MySQL、PHP)更改为 LEMP 堆栈(Linux、Nginx、MySQL、PHP),并将 Nginx 反向代理和网站组合到同一台服务器上。任何专门针对“www.example.com:443”的流量都会进入 Nginx 网站,其他所有流量都会传递到 VPN 服务器,如下所示:

+-----------------------+
|                       |
|         Nginx         |
| (Website & Rev Proxy) |
|                       |
|     192.168.0.100     |
|  vpn.example.com:443  |
|  www.example.com:443  |
|                       |
+-----------------------+
            |
            |
+-----------------------+
|                       |
|        OpenVPN        |
|         (VPN)         |
|                       |
|     192.168.0.101     |
|  vpn.example.com:443  |
|                       |
+-----------------------+

我尝试在单独的服务器 (192.168.0.105) 上安装 Nginx。我在这台服务器上启动并运行了网站。但是,当我包含 proxy.conf 时,它使用“nginx -t”正确测试,但 Nginx 服务无法在此服务器上重新启动。失败信息是:

nginx: [emerg] bind() to 192.168.0.105:443 failed (98: Address already in use)

我相信这是因为 http 和 stream 块都在侦听同一个 IP 和端口。是否有某种方法可以将 Nginx 配置为特定 FQDN 的 Web 服务器:端口和代理(通过流式传输)其他所有内容到另一台服务器?

提前谢谢你。

【问题讨论】:

    标签: nginx nginx-reverse-proxy nginx-config


    【解决方案1】:

    我认为您正在尝试将 www.example.com 托管在与新 nginx 主机相同的主机中:192.168.0.105

    如果是这样,在启动nginx服务时会遇到address already in use错误。

    这是由于 nginx streamhttp 服务都配置为监听端口:443

    http {
        server {
            listen 192.168.0.105:443;
            server_name www.example.com;
        }
    }
    
    stream {
        server {
            listen 192.168.0.105:443;
            proxy_pass $name;
            ssl_preread on;
        }
    }
    

    http 服务不同,该服务允许基于命名的服务器使用相同的端口。 Nginx 将httpstream 视为不同的服务。

    我有 2 个解决方案来解决同一节点中的主机 streamhttp

    方案一:让www.example.com127.0.0.1:443

    因为大多数节点默认都有一个环回接口。我相信您想直接公开stream:443 服务而不是www.example.com:443。让www.example.com127.0.0.1:443 解决address already in use 问题也不错。

    http {
        server {
            listen 127.0.0.1:443;
            server_name www.example.com;
        }
    }
    

    解决方案 2:让www.example.com 监听一个 unix 套接字

    与解决方案 1 类似,但为 www.example.com 使用 unix 套接字来避免额外的 TCP 开销,从而获得一点性能提升。

    http {
        server {
            listen unix:/var/run/nginx.sock;
            server_name www.example.com;
        }
    }
    

    对于这两种解决方案,请记住使用 127.0.0.1 或 unix 套接字重新配置 stream 部分中的 upstream

    我希望能找到更多的选择,但这是我目前能想到的。

    【讨论】:

      猜你喜欢
      • 2015-02-12
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多