我正在尝试为 Azure blob 存储设置 nginx 反向代理。我正在使用图像nginx:1.13.9-alpine
,并且我配置了一个简单的 proxy_pass,如下所示:
location /container {
proxy_pass https://account.blob.core.windows.net/container;
proxy_set_header Host account.blob.core.windows.net
}
但是,它不太管用。直接向存储帐户发出请求是有效的,所以我知道 SAS 令牌是有效的:
curl -v "https://account.blob.core.windows.net/container/file?st=2018-04-02T01%3A57%3A00Z&se=2018-04-11T01%3A57%3A00Z&sp=rl&sv=2015-12-11&sr=b&sig=<sig>"
但通过代理使用相同的令牌总是返回 403:
curl -v "https://proxy.mydomain.com/container/file?st=2018-04-02T01%3A57%3A00Z&se=2018-04-11T01%3A57%3A00Z&sp=rl&sv=2015-12-11&sr=b&sig=<sig>"
...snip...
< HTTP/1.1 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
在服务器日志中我只看到:
10.240.0.4 - - [06/Apr/2018:04:07:30 +0000] "GET /container/file?st=2018-04-02T01%3A57%3A00Z&se=2018-04-11T01%3A57%3A00Z&sp=rl&sv=2015-12-11&sr=b&sig=<sig> HTTP/1.1" 403 621 "-" "curl/7.54.0" "-"
我看到了一些关于需要包含$is_args
等的相互矛盾的建议,但似乎都不起作用。同一个 nginx 实例通过其他路径代理了其他几个资源,所有这些都按预期工作。我遗漏了什么?
编辑
我相信这与 url 路径中的编码字符有关%2f
。在这种情况下,Azure 存储被用作 Docker Registry 的后端,它喜欢给 blob 命名,例如%2fdocker/registry/v2/blobs/sha256/e7/e7c1ef..ced394/data
。如果我在容器中添加一个不带前导 的示例 blob %2f
,则一切都会按预期工作。
答案1
在您的默认或站点的配置文件中,将 blob 容器 URL 指定为,proxy_pass
并将容器的基本 URL 设置为proxy_set_header Host
location /images {
proxy_pass https://YOURACCOUNT.blob.core.windows.net/images;
proxy_set_header Host YOURACCOUNT.blob.core.windows.net;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
答案2
这是最终奏效的方法:
location /files/ {
resolver 8.8.8.8;
if ($request_uri ~* "/files/(.*)") {
proxy_pass https://account.blob.core.windows.net/container/$1;
}
}
proxy_pass
我不知道为什么需要解析器,因为其他位置解析正常。只有当命令包含变量时,它才成为必需。