在实际工作中,遇到一个问题:由于客户数据保密性较高,所以需要使用VPN访问其网络。为减少漏洞筛查风险,只开放了一个8080端口。
但我们部署了产品(端口为8082)和OnlyOffice插件(端口为8088),需要使用Nginx反向代理,将端口转发。
经过一段时间的摸索,终于成功配置,做一个记录。
我们的所有服务都采用docker部署,部署nginx时,将宿主机的8080端口映射到了nginx的80端口上,由于server中默认监听端口是80,因此未再配置listen。如需配置,请自行在Server下配置监听。
部署nginx语句如下:
docker run --name nginx-test -p 8080:80 -d nginx
进入nginx容器,进入/etc/nginx/目录下,编辑nginx.conf文件。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
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;
map $http_host $this_host {
"" $host;
default $http_host;
}
map $http_x_forwarded_proto $the_scheme {
default $http_x_forwarded_proto;
"" $scheme;
}
map $http_x_forwarded_host $the_host {
default $http_x_forwarded_host;
"" $this_host;
}
map $http_upgrade $proxy_connection {
default upgrade;
"" close;
}
server {
location /app {
proxy_pass http://1.2.3.4:8082/app;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "upgrade";
}
location /example/ {
proxy_pass http://1.2.3.4:8088/example/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /web-apps/ {
proxy_pass http://1.2.3.4:8088/web-apps/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /7.1.1-23(换成自己的OnlyOffice版本)/ {
proxy_pass http://1.2.3.4:8088/7.1.1-23/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /cache/ {
proxy_pass http://1.2.3.4:8088/cache/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-Host $the_host;
proxy_set_header X-Forwarded-Proto $the_scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
下面是每个指令的作用:
全局设置
user nginx;
指定运行Nginx进程的用户为nginx。
worker_processes auto;
设置工作进程的数量为自动,Nginx会根据系统的CPU核心数自动调整。
error_log /var/log/nginx/error.log notice;
定义错误日志的路径和日志级别为notice。
pid /var/run/nginx.pid;
定义存放Nginx进程ID的文件路径。
events模块
worker_connections 1024;
每个工作进程可以打开的最大连接数。
http模块
include /etc/nginx/mime.types;
包含MIME类型定义文件。
default_type application/octet-stream;
如果Nginx无法确定文件的MIME类型,则使用此默认值。
log_format main …;
定义日志格式。
access_log /var/log/nginx/access.log main;
定义访问日志的路径和格式。
sendfile on;
允许sendfile方式传输文件,提高传输效率。
keepalive_timeout 65;
长连接超时时间设置为65秒。
map指令
-
map $http_host $this_host
这个map指令根据
$http_host
变量的值来设置$this_host
变量的值。
- 如果
$http_host
是空的(“”),则$this_host
被设置为$host
的值。- 对于其他所有情况(default),
$this_host
的值就是$http_host
的值。这通常用于处理反向代理场景,当$http_host
可能为空或来自不可信来源时,可以确保$this_host
始终有一个有效的值。
-
map http_x_forwarded_proto the_scheme
这个map指令根据
$http_x_forwarded_proto
变量的值来设置$the_scheme
变量的值。
如果
$http_x_forwarded_proto
是空的(“”),则$the_scheme
被设置为$scheme
的值。这通常表示原始请求是HTTP还是HTTPS。对于其他所有情况(default),
$the_scheme
的值就是$http_x_forwarded_proto
的值。这常用于处理通过反向代理传递的X-Forwarded-Proto头,以获取原始请求的协议。
-
map http_x_forwarded_host the_host
这个map指令根据
$http_x_forwarded_host
变量的值来设置$the_host
变量的值。
如果
$http_x_forwarded_host
是空的(“”),则$the_host
被设置为$this_host
的值(这个值在第一个map
指令中定义)。对于其他所有情况(default),
$the_host
的值就是$http_x_forwarded_host
的值。与第二个map
指令类似,这用于处理通过反向代理传递的X-Forwarded-Host头,以获取原始请求的主机名。
-
map $http_upgrade $proxy_connection
这个map指令根据
$http_upgrade
变量的值来设置$proxy_connection
变量的值。
- 如果
$http_upgrade
是空的(“”),则$proxy_connection
被设置为close
。- 对于其他所有情况(default),
$proxy_connection
的值就是upgrade
。这通常用于处理WebSocket连接或其他需要升级的HTTP连接。当客户端请求升级连接时,$proxy_connection
会被设置为upgrade
,以允许Nginx维持与后端的连接。
这些map指令是Nginx配置中非常有用的工具,特别是在处理反向代理和HTTP连接升级时。它们允许你根据请求头或其他变量动态地设置其他变量的值。
server模块
location /app {…}
定义了一个针对/app路径的代理设置,将请求转发到http://1.2.3.4:8082/app,并设置相关代理头部。
location /example/ {…}
定义了一个针对/example/路径的代理设置,将请求转发到http://1.2.3.4:8088/example/,并设置更详细的代理头部,包括X-Forwarded-Host和X-Forwarded-Proto,以便后端服务可以正确识别请求的原始信息。
……
以location /example/{…}为例:
这段Nginx配置中的location指令定义了一个特定的位置块,用于处理所有以/example/开头的URL请求。
在这个位置块中,定义了一系列与代理相关的指令,用于将请求转发到另一个服务器(在这个例子中是http://1.2.3.4:8088/example/)。
下面是对每个指令的详细解释:
-
proxy_pass http://1.2.3.4:8088/example/;
这条指令告诉Nginx将匹配到的请求转发到http://1.2.3.4:8088/example/。
注意这里的URL末尾的斜杠/很重要,它表示如果原始请求中有额外的路径部分,它们将被追加到proxy_pass指定的URL后面。 -
proxy_set_header Upgrade $http_upgrade;
这条指令用于设置转发给代理服务器的
Upgrade
请求头。它使用了先前定义的map指令中的$http_upgrade
变量。如果原始请求中包含了Upgrade
头,它的值将被传递给代理服务器,这通常用于支持WebSocket连接或其他需要升级的协议。 -
proxy_set_header Connection $proxy_connection;
这条指令用于设置转发给代理服务器的
Connection
请求头。它使用了先前定义的map指令中的$proxy_connection
变量。这允许Nginx根据原始请求中的Upgrade
头来决定是否应该保持与代理服务器的持久连接。 -
proxy_set_header X-Forwarded-Host $the_host;
这条指令用于设置
X-Forwarded-Host
请求头,其值来自$the_host
变量。这个头通常用于表示原始请求的主机名,这在反向代理场景中很有用,因为代理服务器可能会看到不同的主机名。 -
proxy_set_header X-Forwarded-Proto $the_scheme;
这条指令设置
X-Forwarded-Proto
请求头,其值来自$the_scheme
变量。这个头用于表示原始请求使用的协议(通常是http或https),这有助于后端服务器知道原始请求是否通过加密连接。 -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
这条指令设置
X-Forwarded-For
请求头,用于表示原始请求的客户端IP地址。$proxy_add_x_forwarded_for
变量通常包含客户端IP以及任何之前代理的IP地址(如果存在的话),这有助于后端服务器跟踪请求的原始来源。
总结
这个Nginx配置主要用于设置全局参数和定义多个代理位置。它允许Nginx根据请求的URL路径将请求转发到不同的后端服务,并设置必要的代理头部,以便后端服务可以正确识别和处理请求。