Phi*_*ßen 7 firewall nginx proxy cache
我的问题是关于使用 Nginx 作为另一个代理背后的代理。(有点混乱。)
我想设置 Nginx,以便它充当 npm 镜像的缓存代理服务器。这是链接:http : //eng.yammer.com/a-private-npm-cache/
在我的本地机器上,不受防火墙限制,以下配置工作正常:
proxy_cache_path /var/cache/npm/data levels=1:2 keys_zone=npm:20m max_size=1000m
inactive=365d;
proxy_temp_path /var/cache/npm/tmp;
server {
listen 80;
server_name classen.abc.lan;
location / {
proxy_pass http://registry.npmjs.org/;
proxy_cache npm;
proxy_cache_valid 200 302 365d;
proxy_cache_valid 404 1m;
sub_filter 'registry.npmjs.org' 'classen.abc.lan';
sub_filter_once off;
sub_filter_types application/json;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想将它应用到位于附加防火墙后面的服务器。在日志中,我可以确认它访问了正确的上游 IP,但由于内部防火墙,请求失败。
我们有一个内部代理,我可以用它绕过防火墙,例如:
$ curl http://registry.npmjs.org
curl: (7) couldn't connect to host
$ http_proxy=http://proxy.abc.lan:1234/ curl http://registry.npmjs.org
... succeeds ...
Run Code Online (Sandbox Code Playgroud)
这个技巧不适用于 Nginx,因为它忽略了http_proxy
环境变量。看了文档,还是想不通怎么修改配置,让它内部可以使用代理。
是否可以结合两种解决方案?重要的是缓存仍然有效,否则,您可以直接使用外部镜像 registry.npmjs.org。
也许,Nginx 应该使用内部代理(proxy.abc.lan)作为proxy_pass
,但是内部代理如何知道应该将请求发送到外部 npm 镜像(http://registry.npmjs.org)?
更新 Lukas 答案
我尝试了 Lukas 解决方案:
rewrite ^(.*)$ "http://registry.npmjs.org$1" break;
proxy_pass http://proxy.abc.lan:1234;
Run Code Online (Sandbox Code Playgroud)
日志显示 URL 被重写,但导致重定向(由 触发curl classen.abc.lan/test-url
):
2014/03/24 11:31:16 [notice] 13827#0: *2 rewritten redirect: "http://registry.npmjs.org/test-url", client: 172.18.40.33, server: classen.abc.lan, request: "GET /test-url HTTP/1.1", host: "classen.abc.lan"
Run Code Online (Sandbox Code Playgroud)
curl 调用的结果不是来自http://registry.npmjs.org的预期 JSON 字符串,而是由 Nginx 生成的 html 页面:
$ curl classen.abc.lan/test-url
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.4.7</center>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Lukas 解决方案的问题是HttpRewriteModule,它会自动将前面带有 http(s) 的所有内容转换为 302。
如果您改为分两个阶段进行重写 - 第二个“中断” - 它应该可以工作。例如
rewrite ^(.*)$ "://registry.npmjs.org$1";
rewrite ^(.*)$ "http$1" break;
proxy_pass http://proxy.abc.lan:1234;
Run Code Online (Sandbox Code Playgroud)
我怀疑有一种更好的方法可以做到这一点,但它似乎有效。
当向代理发出请求时,绝对 URI 形式是必需的。
[...]
请求行示例如下:Run Code Online (Sandbox Code Playgroud)GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
因此,您应该做的就是使用这些修改后的指令将请求传递给代理:
rewrite ^(.*)$ "http://registry.npmjs.org$1" break;
proxy_pass http://proxy.abc.lan:1234;
Run Code Online (Sandbox Code Playgroud)
根据nginx 文档, usingrewrite ... break;
将强制 nginx 使用重写的 URI(现在是协议要求的绝对 URI),而不是尝试从指令构建它proxy_pass
。
归档时间: |
|
查看次数: |
9250 次 |
最近记录: |