Coo*_*kie 5 reverse-proxy nginx url-rewriting sourcegraph
我正在尝试使用反向代理添加 SSL 证书在我的域的子目录上提供自托管的 sourcegraph 服务器。
目标是让http://example.org/source为 sourcegraph 服务器提供服务
我的重写和反向代理如下所示:
location /source {
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-Scheme $scheme;
rewrite ^/source/?(.*) /$1 break;
proxy_pass http://localhost:8108;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,在调用http://example.org/source 时,我被重定向到http://example.org/sign-in?returnTo=%2F
有没有办法将 sourcegraph 的响应重写到正确的子目录?
另外,我可以在哪里调试重写指令?我想遵循它所做的更改以更好地理解它。
- 编辑:
我知道我的方法使用重写可能是错误的,我现在正在尝试 sub_filter 模块。
我使用 tcpdump 捕获了 sourcegraph 的响应并使用 wireshark 进行了分析,所以我在:
GET /sourcegraph/ HTTP/1.0
Host: 127.0.0.1:8108
Connection: close
Upgrade-Insecure-Requests: 1
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://example.org/
Accept-Encoding: gzip, deflate, br
Accept-Language: de,en-US;q=0.9,en;q=0.8
Cookie: sidebar_collapsed=false;
HTTP/1.0 302 Found
Cache-Control: no-cache, max-age=0
Content-Type: text/html; charset=utf-8
Location: /sign-in?returnTo=%2Fsourcegraph%2F
Strict-Transport-Security: max-age=31536000
Vary: Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Trace: #tracer-not-enabled
X-Xss-Protection: 1; mode=block
Date: Sat, 07 Jul 2018 13:59:06 GMT
Content-Length: 58
<a href="/sign-in?returnTo=%2Fsourcegraph%2F">Found</a>.
Run Code Online (Sandbox Code Playgroud)
mik*_*nik 11
在这里使用重写会导致额外的处理开销并且完全没有必要。
proxy_pass 像这样工作:
proxy_pass 到一个裸url,即在域/ip/端口之后什么都没有,完整的客户端请求uri被添加到最后并传递给代理。
添加任何内容,即使只是一个斜杠,proxy_pass您添加的任何内容都会替换与该位置块的 uri 匹配的客户端请求 uri 部分。
因此,如果您想丢失客户端请求的源代码部分,它需要如下所示:
location /source/ {
proxy_pass http://localhost:8108/;
.....
}
Run Code Online (Sandbox Code Playgroud)
现在请求将像这样被代理:
example.com/source/ -> localhost:8108/
example.com/source/files/file.txt -> localhost:8108/files/file.txt
重要的是要指出 Nginx 不只是/source/从请求中删除,它替换了我的整个proxy_passURI,当它只是一个尾部斜杠时并不清楚,所以为了更好地说明我们是否更改proxy_pass为:
proxy_pass http://localhost:8108/graph/; 那么请求现在是这样处理的:
example.com/source/ -> localhost:8108/graph/
example.com/source/files/file.txt -> localhost:8108/graph/files/file.txt
如果您想知道如果有人请求example.com/source此工作会发生什么,前提是您没有将merge_slashes指令设置为关闭,因为 Nginx 会将尾随 / 添加到代理请求。
如果你的Nginx在另一个网站服务器的前面是对端口8108上运行,并通过服务内容proxy_pass从子目录的一切,例如/subdir,那么你可能有一个在端口8108的服务提供的HTML页面,其中包括资源的问题,呼吁自己的基于绝对 URL 的 API 等。这些调用将省略/subdir前缀,因此它们不会被 nginx 路由到端口 8108 的服务。
一种解决方案是让位于端口 8108 的网络服务器提供包含基本 href 属性的 HTML,例如
<head>
<base href="https://example.com/subdir">
</head>
Run Code Online (Sandbox Code Playgroud)
它告诉客户端所有链接都相对于该路径(参见https://www.w3schools.com/tags/att_base_href.asp)
有时这不是一个选项 - 也许网络服务器是您刚刚由外部 docker 映像提供的东西,或者您可能只是没有看到为什么需要篡改作为独立运行的服务的原因。一个只需要修改前面的nginx的解决方案是使用Refererheader来判断请求是否是由位于 的资源发起的/subdir。如果是这种情况,您可以重写要添加前缀的请求/subdir,然后将客户端重定向到该位置:
location / {
if ($http_referer = "https://example.com/subdir/") {
rewrite ^/(.*) https://example.com/subdir/$1 redirect;
}
...
}
location /subdir/ {
proxy_pass http://localhost:8108/;
}
Run Code Online (Sandbox Code Playgroud)
或者类似的东西,如果您更喜欢正则表达式让您省略主机名:
if ($http_referer ~ "^https?://[^/]+/subdir/") {
rewrite ^/(.*) https://$http_host/subdir/$1 redirect;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17329 次 |
| 最近记录: |