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.
    – Tim
    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.

Not the answer you're looking for? Browse other questions tagged .