当我浏览到这个 URL 时:http://localhost:8080/foo/%5B-%5Dserver ( nc -l 8080) 按原样接收它:
GET /foo/%5B-%5D HTTP/1.1
Run Code Online (Sandbox Code Playgroud)
但是,当我通过 nginx (1.1.19) 代理此应用程序时:
location /foo {
proxy_pass http://localhost:8080/foo;
}
Run Code Online (Sandbox Code Playgroud)
通过 nginx 端口路由的相同请求转发路径解码:
GET /foo/[-] HTTP/1.1
Run Code Online (Sandbox Code Playgroud)
GET 路径中的解码方括号导致目标服务器中的错误(HTTP 状态 400 - 路径中的非法字符...),因为它们未转义到达。
有没有办法禁用 URL 解码或将其编码回来,以便目标服务器在通过 nginx 路由时获得完全相同的路径?一些巧妙的 URL 重写规则?
是否可以让 Nginx 缓存所有301重定向请求proxy_pass?
例如:
请求 #1:客户端 A 请求 /some/path -> 发送到proxy_pass-> 导致 301 重定向到/some/other/path-> nginx 缓存此响应,因为它是 301 重定向。
请求 #2:客户端 B 请求 /some/path -> nginx 返回缓存的 301 重定向到/some/other/path.
我在主机 B-beta 上运行 OpenNMS,其 URL 如下:
http://b-beta:8980/opennms
Run Code Online (Sandbox Code Playgroud)
我想使用 NginX 来隐藏可从主机 a-alpha 访问的路径,如下所示:
https://a-alpha/omber/nms
Run Code Online (Sandbox Code Playgroud)
所以我想我需要的是重写发送到后端的请求以将路径从 /omber/nms 更改为 /opennms - 但它对用户不可见 - 这是可以完成的事情吗?
HTTPS 已经可以正常工作了。
我看到了这个问题,但它似乎对我不起作用。
目前(工作)情况是:
server {
listen 443 ssl;
server_name updates.example.com;
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
location /update {
proxy_pass "http://localhost:5000";
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_intercept_errors off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Client-Subject $ssl_client_s_dn;
proxy_set_header X-Client-Cert $ssl_client_cert;
}
location / {
proxy_pass "http://localhost:5001";
proxy_connect_timeout 60;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_intercept_errors off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header …Run Code Online (Sandbox Code Playgroud) 类似的问题之前在这里和这里被问过,但没有一个匹配或解决我遇到的问题。经过几个小时的拼命解决问题后,我找到了一个出乎意料但简单的解决方案,我想以问答的方式分享它。
一家公司有两台服务器:反向代理(Ubuntu 20.04 + Nginx 1.17)和上游应用程序服务器(也是 Ubuntu 20.04 + Nginx 1.17)。反向代理处理各种子域,例如通过使用proxy_passhttp://demo.example.com指令将它们映射到上游服务器的目录。http://12.12.12.12:8000/demo/
然后,客户端发出 HTTP 请求,其中路径指向目录,但没有尾部斜杠,例如http://demo.example.com/items。默认的 Nginx 行为是进行 301 重定向到相同的 URL,并添加尾部斜杠,例如位置文档http://demo.example.com/items/中所述。
如果 301 重定向发生在上游应用程序服务器,则正常行为是重定向位置路径变为http://12.12.12.12:8000/demo/items/. 这不是问题,因为默认情况下,反向代理将12.12.12.12:8000/demo/用原始主机替换部分内容,因此客户端会收到正确的 301 重定向到demo.example.com/items/. 这正是我所期望发生的事情。
但是,通过以下配置,客户端收到的重定向位置将变为http://demo.example.com:8000/demo/items/。反向代理似乎只部分重写了重定向 URL。
反向代理的站点配置:
server {
listen 80;
listen [::]:80;
index index.html index.htm;
server_name demo.example.com;
location / {
proxy_pass http://12.12.12.12:8000/demo/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} …Run Code Online (Sandbox Code Playgroud)