Прокси Nginx для хранилища Azure

Я пытаюсь настроить обратный прокси-сервер nginx для хранилища BLOB-объектов Azure. Я использую nginx:1.13.9-alpine image, и у меня есть простой 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&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" "-"

Я видел несколько противоречивых советов о необходимости включения $is_argsи т. д., но, похоже, ничего из этого не работает. Тот же экземпляр nginx проксирует несколько других ресурсов по другим путям, и все они работают как положено. Что мне не хватает?

редактировать

Я считаю, что это связано с закодированными символами, такими как %2f в пути URL. В этом случае хранилище Azure используется в качестве бэкэнда для реестра Docker, и ему нравится давать имена больших двоичных объектов, такие как %2fdocker/registry/v2/blobs/sha256/e7/e7c1ef..ced394/data, Если я добавлю образец капли в контейнер без ведущих %2fвсе работает как положено.

2 ответа

В вашем файле конфигурации по умолчанию или на сайте. дать URL контейнера BLOB-объекта как 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;
}

Вот что наконец сработало:

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

Я понятия не имею, зачем нужен распознаватель, учитывая, что другие местоположения разрешаются нормально. Это кажется необходимым требованием, когда proxy_pass Команда содержит переменную.

Другие вопросы по тегам