Интеграция KeyVault с функциями Azure (среда выполнения powershell) не работает

Я пытаюсь следовать этому https://azure.microsoft.com/en-us/blog/simplifying-security-for-serverless-and-web-apps-with-azure-functions-and-app-service/, чтобы безопасно получить секрет из моего хранилища ключей при использовании функций Azure.

В моем хранилище ключей есть политика доступа, которая позволяет получать секреты SYSTEM MANAGED IDENTITY приложения функций.

Вот соответствующие настройки приложения, как показано в расширенном редакторе (не имеет значения, истинно или ложно slotSetting, уже пробовал. Не уверен, что он делает, кстати)

{
    "name": "ultrasecret",
    "value": "@Microsoft.KeyVault(SecretUri=https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>)",
    "slotSetting": true
}

Вот шаблонная версия моей единственной функции. Взгляните на блок IF ниже, чтобы увидеть, как я запрашиваю хранилище ключей косвенно через переменную среды, которая раскрывает секрет хранилища ключей.

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    $status = [HttpStatusCode]::OK
    $secret = $env:ultrasecret
    $body = "Hello $name $secret"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

Когда я делаю запрос GET на

https://<function-app-name>.azurewebsites.net/api/HttpTrigger1?name=john

это то, что возвращается

Hello john @Microsoft.KeyVault(SecretUri=https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>)

По сути, я возвращаю буквальное значение параметра вместо секрета. Это потому, что предварительная версия поддерживает Powershell? У кого-нибудь еще это работает?

Любая помощь приветствуется.


person baouss    schedule 02.09.2019    source источник
comment
Похоже, я не единственный ... вот проблема с github github.com/ MicrosoftDocs / azure-docs / issues / 33480   -  person baouss    schedule 02.09.2019
comment
Я также могу подтвердить, что это не имеет ничего общего с самим MSI. Я успешно могу вручную выполнять вызовы REST (из функции z) к API хранилища ключей, запрашивать секрет и использовать его в своей функции. Поэтому мне может потребоваться (в качестве обходного пути) установить секрет в переменных среды вручную, а не использовать официальный способ.   -  person baouss    schedule 02.09.2019


Ответы (2)


Если вы хотите получить доступ к секрету хранилища ключей в функции Azure, у вас есть два варианта.

  • Установить как переменные среды

Если вы хотите установить секрет хранилища ключей Azure в качестве переменных среды, вы можете завершить это с помощью Azure CLI. Дополнительные сведения см. В https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings.

az functionapp config appsettings set -n testfun08 -g testfun07 --settings "[email protected](SecretUri=<$secretId>)"

введите здесь описание изображения

  • Используйте REST API хранилища ключей Azure

Если вы хотите получить значение своего хранилища ключей Azure с помощью Azure Key Vault REST API, следуйте подробным инструкциям, как показано ниже.

  1. Настроить MSI
  2. Настроить хранилище ключей Azure политика доступа
    Connect-AzAccount

    $app=Get-AzADServicePrincipal -DisplayName "your function app name"

    Set-AzKeyVaultAccessPolicy -VaultName "your key vault name" -ResourceGroupName "your group name" -ObjectId $app.Id -PermissionsToSecrets list, get
  1. Код
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
# get access token with MSI. For more details, please refer to https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity#rest-protocol-examples
    $tokenAuthURI = $Env:MSI_ENDPOINT +"?resource=https://vault.azure.net&api-version=2017-09-01"
   $tokenResponse = Invoke-RestMethod -Method Get -Headers @{"Secret"="$env:MSI_SECRET"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
# get secret value
$headers = @{ 'Authorization' = "Bearer $accessToken" }
$queryUrl = "the url of secret" + "?api-version=7.0"

$keyResponse = Invoke-RestMethod -Method GET -Uri $queryUrl -Headers $headers
$value= $keyResponse.value
Write-Host "$vaule"  
    $status = [HttpStatusCode]::OK
    $body = "Hello $name $value"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

введите здесь описание изображения

Для получения дополнительных сведений см. Возвращает Key Vault. 401 с токеном доступа (приложение MSI PowerShell Function)

Обновить

Как проверить, успешно ли мы установили настройки приложения через Kudu  введите описание изображения здесь введите описание изображения здесь  введите описание изображения здесь

person Jim Xu    schedule 03.09.2019
comment
Спасибо. Я пробовал установить его через аз-кли. Однако мне пришлось ввести az functionapp config appsettings set -n testfun08 -g testfun07 --settings [email protected] (SecretUri = ‹$ secretId› ^^) ‹--- помните о ^^, потому что с ними закрытие) в настройках не выставлялись. Однако результат этой процедуры эквивалентен тому, что у меня уже есть, только через az cli вместо tf. Так что это все еще не работает, мне отображается только буквальное значение параметра @ Microsoft.KeyVault (SecretUri = ...). Ваш второй способ (REST) ​​- это также то, что я подтвердил (см. Комментарий) выше в качестве обходного пути - person baouss; 03.09.2019
comment
тем не менее, я не знаю, почему он работает вручную / REST, но это не так, когда это делается через app_settings (который должен быть официальным и документированным способом) - person baouss; 03.09.2019
comment
Это вы добавляете напрямую через портал Azure? - person ; 03.09.2019
comment
Ни через портал, ни через az cli, ни через развертывание шаблона (terraform) у меня не работает. Работает только вызов API отдыха хранилища ключей вручную. Но тогда у меня нет возможности сохраняться как переменная env, потому что приложение-функция позволяет устанавливать только переменные env области процесса, а не пользователя и не область компьютера. Даже на премиальном плане ... Итак, новая проблема прямо здесь - person baouss; 03.09.2019
comment
Не могли бы вы проверить, успешно ли вы установили настройки приложения? О том, как это сделать, читайте в моем обновлении. - person Jim Xu; 04.09.2019
comment
Настроено правильно. Проблема была в правилах брандмауэра. Приложение-функция не использует частный путь подключения через подсеть, как настроено (хотя функции, определенные в приложении-функции, выполняют ...). Поэтому при запросе хранилища ключей используются общедоступные IP-адреса, которые я не внес в белый список. Дополнительные сведения см. Здесь: github.com/MicrosoftDocs/azure-docs/ вопросы / - person baouss; 05.09.2019
comment
По словам инженера службы поддержки, работающего со мной в этом случае, (нерабочее) поведение, которое я описал выше, считается ошибкой и над этим мы работаем. - person baouss; 09.09.2019

У меня была такая же ошибка в коде, как и у вас, и я обнаружил, что устранение ошибки разрешения решило проблему.

В разделе «Функции платформы» -> «Конфигурация» посмотрите на исходный столбец для своих настроек и проверьте, действительны ли они. Вы можете отредактировать элемент, чтобы получить подробное сообщение об ошибке для записи.

Действительный

Действительный справочник по хранилищу ключей (зеленая галочка)

Ошибка

Недопустимая ссылка на хранилище ключей (красный крестик)

В моем случае приложение-функция не имело разрешения на доступ к хранилищу ключей.

Используя портал Azure, откройте колонку приложения-функции.

  1. Выберите вкладку Возможности платформы.
  2. Выберите Identity.
  3. На вкладке «Назначено системой» установите для параметра «Состояние» значение «Вкл.».
  4. Щелкните Сохранить.
  5. Скопируйте идентификатор объекта в буфер обмена.

Перейдите в хранилище ключей

  1. выберите Политики доступа.
  2. Добавить политику доступа
  3. Под секретами выберите ПОЛУЧИТЬ, СПИСОК.
  4. В разделе «Выбрать принципала» вставьте идентификатор объекта.
  5. Выберите имя приложения-функции.
  6. Щелкните Добавить.
  7. Нажмите "Сохранить".

Вернитесь в приложение-функцию и убедитесь, что ссылка действительна в разделе «Функции платформы» -> «Конфигурация».

См .: Добавление идентификатора, назначенного системой

person John Doty    schedule 16.01.2020