首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用can和防火墙保护时,Azure DevOps构建管道无法从密钥库获取机密

使用can和防火墙保护时,Azure DevOps构建管道无法从密钥库获取机密
EN

Stack Overflow用户
提问于 2019-09-15 07:39:37
回答 3查看 2.6K关注 0票数 5

使用vnet和防火墙保护密钥库时,无法从密钥库获取密钥。

我想使用DevOps构建管道任务中存储在密钥库中的秘密,我想深入了解安全最佳实践和防御。作为安全最佳实践,我希望可以从选定的虚拟网络、选定的azure服务和可信的互联网ip访问密钥库。当然,我会使用服务主体和适当的权限(list/get)。

不幸的是,Azure DevOps不是一个受信任的服务。因此,我的替代方案是将DevOps IP列入白名单。我发现我的DevOps在美国东部2地区,我下载了Azure数据中心IP(用US East2过滤)。在US East 2中大约有285个IP。Key Vault firewall有您可以添加的防火墙规则的数量限制,它是127!所以,我倒霉了!

目前,只有在允许所有网络的情况下,我才能从build pipeline的密钥库中获取秘密!是的,我仍然需要进行身份验证才能获得秘密,但我在深度防御上输了。我真的需要将密钥库锁定到可信网络,但我做不到。为什么?我不能添加超过127条防火墙规则(覆盖该地区),而且DevOps不是值得信任的azure服务之一!

EN

回答 3

Stack Overflow用户

发布于 2019-12-11 00:09:29

我想我应该在Prodip提供的解决方案上加上一点。这依赖于这样一个事实,即当您请求密钥时,az客户端会很友好地告诉您客户端的IP地址是什么,即:

代码语言:javascript
复制
az keyvault secret show -n "a-known-client-secret" --vault-name "$keyVaultName"

Attempting to get value for known secret from key vault: '******'
ERROR: Client address is not authorized and caller is not a trusted service.
Client address: 1.1.1.1
Caller: appid=***;oid=****;iss=https://sts.windows.net/***/
Vault: ******;location=******

下面是我的bash脚本(whitelist-agent-for-key-vault.sh):

代码语言:javascript
复制
#!/usr/bin/env bash

## By default the Azure DevOps IP addresses are NOT whitelisted for key vault access. So even if the service principal has access, you won't get past the firewall.
## The solution is to temporarily add the build agent IP address to the key vault firewall, and remove it when the pipeline is complete. 

if [[ $(uname -s) == "Linux" ]]; then
    azcmd="az"
else
    # If we're in a bash shell on Windows, az commands don't work, but we can call the az.cmd batch file directly from git Bash if we can find it...
    azcmd=$(where az.cmd)
fi

# Are we removing rather than setting?
if [[ $1 == "-r" ]]; then
    if [[ -z "$3" ]]; then
        echo "Build agent IP address is empty, no whitelist entry to remove from key vault: '$2'"
    else
        echo "Removing key vault '$2' network rule for DevOps build agent IP address: '$3'"

        # Remember to specify CIDR /32 for removal
        "$azcmd" keyvault network-rule remove -n $2 --ip-address $3/32
    fi
    exit 0
fi

keyVaultName=$1

########################################################################
##### This is the known secret which we request from the key vault #####
########################################################################

knownSecret="<My known secret>"

echo "Attempting to get value for known secret from key vault: '$keyVaultName'"

# Attempt to show secret - if it doesn't work, we are echoed our IP address on stderror, so capture it
secretOutput=$("$azcmd" keyvault secret show -n "$knownSecret" --vault-name "$keyVaultName" 2>&1)
buildAgentIpAddress=$(echo $secretOutput | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b")

set -euo pipefail

if [[ ! -z "$buildAgentIpAddress" ]]; then
    # Temporarily whitelist Azure DevOps IP for key vault access.
    # Note use of /32 for CIDR = 1 IP address. If we omit this Azure adds it anyway and fails to match on the IP when attempting removal.
    echo "Azure DevOps IP address '$buildAgentIpAddress' is blocked. Attempting to whitelist..."
    "$azcmd" keyvault network-rule add -n $keyVaultName --ip-address $buildAgentIpAddress/32

    # Capture the IP address as an ADO variable, so that this can be undone in a later step
    echo "##vso[task.setvariable variable=buildAgentIpAddress]$buildAgentIpAddress"
else
    # We didn't find the IP address - are we already whitelisted?
    secretValue=$(echo $secretOutput | grep -o "value")

    if [[ -z "$secretValue" ]]; then
        echo "Unexpected response from key vault whitelist request, json attribute 'value' not found. Unable to whitelist build agent - response was: '$secretOutput'"
        exit 1
    fi
fi

下面是我如何将IP添加到白名单中:

代码语言:javascript
复制
  # Add agent IP to key vault white list
  - task: AzureCLI@2
    displayName: Add Azure DevOps build agent IP to key vault white list
    inputs:
      azureSubscription: ${{ parameters.azureSubscription }}
      scriptType: bash
      scriptLocation: scriptPath
      scriptPath: $(Pipeline.Workspace)/server-build-tools/drop/build-scripts/whitelist-agent-for-key-vault.sh
      arguments: '$(keyVaultName)'

下面是我从白名单中删除IP的方法

代码语言:javascript
复制
      - task: AzureCLI@2
        displayName: Remove Azure DevOps build agent IP from key vault white list
        condition: always()
        inputs:
          azureSubscription: ${{ parameters.azureSubscription }}
          scriptType: bash
          scriptLocation: scriptPath
          scriptPath: $(Pipeline.Workspace)/server-build-tools/drop/build-scripts/whitelist-agent-for-key-vault.sh
          arguments: '-r "$(keyVaultName)" "$(buildAgentIpAddress)"'

注意事项:

  • 这依赖于已被授予对密钥存储区的读取访问权限的Azure DevOps服务主体使用您已知的密钥

的名称读取knownSecret

奖励:

这使用Azure CLI工作,并且已经在Azure DevOps for Linux和Windows构建代理上进行了测试,后者在Git bash下运行。通常,如果你尝试在Git Bash中运行'az‘命令,你只会得到'Command not found’。我想要一个在两者上都能工作的解决方案,因为由于Linux / Windows构建要求,我需要共享代码。

票数 5
EN

Stack Overflow用户

发布于 2019-09-21 13:09:23

您可以在构建定义中添加一个步骤,将代理IP地址列入白名单,然后在构建结束时将其从白名单中删除。这不是一个解决方案,而是在Azure产品团队将Azure DevOps添加为可信服务之前的一个变通方法。感谢@DanielMann提供了这个想法。

解决方案很简单,但我不会信任ipify.org作为REST API端点来获取构建代理的ip地址。取而代之的是,我在Azure Function- GetClientIP创建了我自己的(并且值得信任的)服务。DevOps不是我的日常工作,我很难弄清楚如何分配和使用用户定义的变量,并将它们传递到流水线中的下一步/任务/阶段!微软关于变量用法的文档没有给我足够的帮助,但在多次不成功的运行后,我发现了这一点!

在我的博客- Azure DevOps Build Pipeline- use keys and secrets from Key Vault上可以看到完整的解决方案。

票数 4
EN

Stack Overflow用户

发布于 2019-09-19 14:00:25

唯一的解决方案是使用self-hosted agent

您可以创建一个VM并在其中安装代理客户端。然后,您可以在DevOps代理池中添加它的新代理并使用它。

因为自代理正在Azure VM中运行,而Azure VM肯定位于虚拟网络中。这样,您就可以将虚拟网络添加到您的密钥库防火墙白名单中。

事实上,我不认为你需要这样做。因为没有访问策略,任何人都无法访问您的密钥库。因此,从理论上讲,它是足够安全的。

但是,如果您必须使用防火墙和网络规则保护密钥库,则可以使用自托管代理。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57940062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档