Назад | Перейти на главную страницу

Прокси-сервер Nginx в хранилище Azure

Я пытаюсь настроить обратный прокси-сервер nginx для хранилища BLOB-объектов Azure. Я использую 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&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, и ему нравится давать имена BLOB-объектов, например %2fdocker/registry/v2/blobs/sha256/e7/e7c1ef..ced394/data. Если я добавлю в контейнер образец капли без ведущего %2f, все работает как положено.

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

Вот что в итоге сработало:

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

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