Nginx 多工作负载配置 - 网站和反向代理
Nginx Multi-Workload Config - Website & Reverse Proxy
TLDR:我正在尝试配置 Nginx 以托管网站并同时充当反向代理。该网站位于 'www.example.com:443' 上,反向代理指向 'vpn.example.com:443' 上的单独 OpenVPN 服务器。我想我知道答案是 "Nginx cannot be configured to listen on a single port for two different types of traffic"(网络流量和反向代理流量),但我想我会问那些更有知识的人。
现在,进入更冗长的版本。我确实有一个看起来像这样的工作设置:
+-----------------------+
| |
| 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 的流{}块。配置文件如下所示:
/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 和流块都在同一 IP 和端口上侦听。有什么方法可以将 Nginx 配置为特定 FQDN:port 的 Web 服务器并代理(通过流式传输)其他所有内容到另一台服务器?
提前致谢。
我认为您正在尝试将 www.example.com
托管在与您的新 nginx 主机相同的主机中:192.168.0.105
.
如果是这样,您将在启动 nginx
服务时遇到 address already in use
错误。
这是因为 nginx stream 和 http 服务都配置为监听端口: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 将 http
和 stream
视为不同的服务。
我有 2 个 far 解决方案来解决同一节点中的主机 stream
和 http
。
解决方案 1:让 www.example.com
听 127.0.0.1:443
因为大多数节点默认都有一个环回接口。我相信您想直接公开 stream:443
服务而不是 www.example.com:443
。让 www.example.com
听听 127.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 socket
与解决方案 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
。
我希望能找到更多的选择,但这是我目前能想到的。
TLDR:我正在尝试配置 Nginx 以托管网站并同时充当反向代理。该网站位于 'www.example.com:443' 上,反向代理指向 'vpn.example.com:443' 上的单独 OpenVPN 服务器。我想我知道答案是 "Nginx cannot be configured to listen on a single port for two different types of traffic"(网络流量和反向代理流量),但我想我会问那些更有知识的人。
现在,进入更冗长的版本。我确实有一个看起来像这样的工作设置:
+-----------------------+
| |
| 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 的流{}块。配置文件如下所示:
/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 和流块都在同一 IP 和端口上侦听。有什么方法可以将 Nginx 配置为特定 FQDN:port 的 Web 服务器并代理(通过流式传输)其他所有内容到另一台服务器?
提前致谢。
我认为您正在尝试将 www.example.com
托管在与您的新 nginx 主机相同的主机中:192.168.0.105
.
如果是这样,您将在启动 nginx
服务时遇到 address already in use
错误。
这是因为 nginx stream 和 http 服务都配置为监听端口: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 将 http
和 stream
视为不同的服务。
我有 2 个 far 解决方案来解决同一节点中的主机 stream
和 http
。
解决方案 1:让 www.example.com
听 127.0.0.1:443
因为大多数节点默认都有一个环回接口。我相信您想直接公开 stream:443
服务而不是 www.example.com:443
。让 www.example.com
听听 127.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 socket
与解决方案 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
。
我希望能找到更多的选择,但这是我目前能想到的。