不指定主机的反向图像代理

Reverse image proxy without specifying host

我的配置中有以下内容作为图像的反向代理:

location ~ ^/image/(.+) {
    proxy_pass http://example.com/;
}

问题是并非所有图像都是 example.com 图像,因此我们需要传入完整的 url。如果我尝试:

location ~ ^/image/(.+) {
    proxy_pass ;
}

我收到一个错误:

invalid URL prefix in "https:/somethingelse.com/someimage.png"

这个问题很模糊,但是,根据错误消息,您要做的是完全根据用户输入执行 proxy_pass,使用完整的 URL在 URI 的 /image/ 前缀之后指定。

基本上,这是一个非常糟糕的主意,因为您正在开放自己成为一个开放的代理人。但是,它在您提供的 conf 中不起作用的原因是 URL 规范化,在您的情况下,将 http://example 压缩为 http:/example (双斜杠变为单斜杠),这在 proxy_pass.

的上下文中是不同的

如果您不关心安全性,您可以将 merge_slashes 从默认的 on 更改为 off:

merge_slashes off;
location …

另一种可能与nginx proxy_pass and URL decoding

有些相关
location ~ ^/image/.+ {
    rewrite ^ $request_uri;
    rewrite ^/image/(.*)  break;
    return 400;
    proxy_pass $uri; # will result in an open-proxy, don't try at home
}

正确的解决方案是实施白名单,可能借助 map 甚至基于前缀的位置指令:

location ~ ^/image/(http):/(upload.example.org)/(.*) {
    proxy_pass :///;
}

请注意,根据开头的解释,上面的位置受 merge_slash 设置的影响,因此默认情况下它永远不会有双重 //,因此需要在 proxy_pass 阶段手动添加双 //

在这种情况下我会使用地图

map $request_uri  $proxied_url {
   # if you don't care about domain and file extension
   ~*/image/(https?)://?(.*)   ://;

   # if you want to limit file extension
   ~*/image/(https?)://?(.*\.(png|jpg|jpeg|ico))$   ://;
   # if you want to limit file extension and domain

   ~*/image/(https?)://?(abc\.xyz\.com/)(.*\.(png|jpg|jpeg|ico))$   ://;
   default "/404";
}

然后在您的代理传递部分,您将使用如下所示的东西

location /image/ {
   proxy_pass $proxied_url;
}

我已经给出了三个不同的例子,具体取决于你想如何处理它