I am trying to setup an nginx reverse proxy for Azure blob storage. I'm using the nginx:1.13.9-alpine
image, and I have a simple proxy_pass configured like this:
location /container {
proxy_pass https://account.blob.core.windows.net/container;
proxy_set_header Host account.blob.core.windows.net
}
However, it doesn't quite work. A direct request to the storage account works, so I know the SAS token is good:
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>"
But using the same token through the proxy always returns a 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.
In the server logs I just see:
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" "-"
I've seen some conflicting advice about needing to include $is_args
, etc, but none of it seems to work. The same nginx instance proxies several other resources through other paths, all of which work as expected. What am I missing?
edit
I believe this is related to encoded characters like %2f
in the url path. Azure Storage in this case is being used as the backend for a Docker Registry, and it likes to give blobs names like %2fdocker/registry/v2/blobs/sha256/e7/e7c1ef..ced394/data
. If I add a sample blob in the container without the leading %2f
, everything works as expected.
Best Answer
This is what finally worked:
I have no idea why the resolver is needed, given that other locations resolve OK. It only seems to become a requirement when the
proxy_pass
command contains a variable.