3

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&amp;se=2018-04-11T01%3A57%3A00Z&amp;sp=rl&amp;sv=2015-12-11&amp;sr=b&amp;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.

1
  • Why are you trying to set up this proxy? Tell us what you're trying to achieve, not just your method. Please edit your question rather than replying in a comment. Commented Apr 6, 2018 at 4:16

2 Answers 2

4

In your default or site's config file. give blob container url as proxy_pass and set base url of your container as 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

This is what finally worked:

location /files/ { resolver 8.8.8.8; if ($request_uri ~* "/files/(.*)") { proxy_pass https://account.blob.core.windows.net/container/$1; } } 

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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.