有办法获取运行的托管计算机的 IP 地址范围吗?
这与发布管道 -> 托管代理有关。
问题:连接时访问被拒绝,因为连接被防火墙拒绝。需要将此请求的 IP 地址范围列入白名单,该请求来自 DevOps 上的发布管道。
我在一个版本中有一个步骤,可以通过以下方式在 powershell 中获取托管代理 IP 地址:
Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
希望有帮助。
对于 Windows 构建代理,使用 powershell 路线更安全:
steps:
- task: AzurePowerShell@5
displayName: 'Add buildserver public ip'
inputs:
azureSubscription: test
ScriptType: InlineScript
Inline: |
$ip = (Invoke-WebRequest -uri "http://ifconfig.me/ip").Content
New-AzSqlServerFirewallRule -ResourceGroupName "group" -ServerName "database-server-name" -FirewallRuleName "azuredevops" -StartIpAddress $ip -EndIpAddress $ip
azurePowerShellVersion: LatestVersion
该池每周都会从 Microsoft 获得更新。因此,无法维护它。
对于这个问题,我创建了一个新的 Bash 任务。该任务从代理获取当前 IP,并将其列入 AWS 安全组白名单。在完成管道之前,我已经撤销了上述IP。
Current_IP=$(curl ipinfo.io/ip)
echo $Current_IP
# Authorize access
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxxxxx \
--protocol tcp \
--port 9000 \
--cidr $Current_IP/32
# Revoke access
aws ec2 revoke-security-group-ingress \
--group-id sg-xxxxxxx \
--protocol tcp \
--port 9000 \
--cidr $Current_IP/32
为了使 aws-cli 命令发挥作用,我们还需要一个受限制的 aws 策略,该策略将允许上述命令以有限的访问权限运行。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:ModifySecurityGroupRules"
],
"Resource": "arn:aws:ec2:us-east-2:xxxxxx:security-group/sg-xxxxx"
}
]
}
使用管道中的脚本步骤获取当前外部 IP 并将其列入白名单。管道完成后,使用另一个脚本步骤进行清理。
不幸的是,这是唯一的方法(对于托管代理)。
查看 Azure DevOps 的此附加组件 (https://marketplace.visualstudio.com/items?itemName=MartijnQuekel.AzureAppServiceIPRestrictions)。它允许您在构建管道期间更改应用服务 IP 限制。
我们需要将下面提到的列表中的 Azure 数据中心使用的 IP 地址列入白名单: https://www.microsoft.com/en-nz/download/details.aspx?id=41653
注意:此列表每周都会更新,因此请在部署规划期间注意这一点
我同意@4c74356b41所提到的。
我一直在使用以下解决方案将 Azure DevOps IP 地址添加到 Azure Kubernetes 服务的授权 IP 范围。您可以修改此解决方案以将其用于任何 Azure 服务。
您需要添加两个“Azure Cli”任务 - 一个用于添加 Azure DevOps 代理 IP 地址,另一个用于删除 Azure DevOps 代理 IP 地址。
在 Kubernetes 任务之前添加第一个任务:
我使用“Azure Cli”在 Azure DevOps 管道中添加了一个新任务,并将以下命令添加为内联脚本:
echo "Get Azure DevOps IP address"
azdoip=`curl -s icanhazip.com`
echo "Azure DevOps IP Address: $azdoip"
echo "Set Azure Subscription to MYSUBSCRIPTION"
az account set --subscription "MYSUBSCRIPTION"
echo "Get credentials for AKS Cluster Admin"
az aks get-credentials --resource-group MYAKSRG --name MYAKSCLUSTER --admin --file ~/.kube/config
Echo "Get existing authorized ip ranges"
authorizedips=`az aks show --resource-group MYAKSRG --name MYAKSCLUSTER --query apiServerAccessProfile |jq -r '.authorizedIpRanges | join(",")'`
echo "Update Azure DevOps IP Address in AKS Cluster Authorized IP Ranges"
az aks update --resource-group MYAKSRG --name MYAKSCLUSTER --api-server-authorized-ip-ranges $authorizedips,$azdoip
完成所有 kubernetes 任务后,在末尾添加另一个“Azure Cli”任务以删除 Azure DevOps IP。
echo "Set Azure Subscription to MYSUBSCRIPTION"
az account set --subscription "MYSUBSCRIPTION"
echo "Get credentials for AKS Cluster Admin"
az aks get-credentials --resource-group MYAKSRG --name MYAKSCLUSTER --admin --file ~/.kube/config
echo "Get New Authorized IP Ranges"
newauthorizedips=`az aks show --resource-group MYAKSRG --name MYAKSCLUSTER --query apiServerAccessProfile |jq -r '.authorizedIpRanges | join(",")'`
echo "Remove AzDo IP and store it as a variable" #Removes last element from the array of IPs
authorizedips=`echo $newauthorizedips | awk 'BEGIN{FS=OFS=","}NF--'`
echo "Update AKS by restoring Authorized IPs"
az aks update --resource-group MYAKSRG --name MYAKSCLUSTER --api-server-authorized-ip-ranges $authorizedips
您可能遇到的问题是,IP 不仅每次运行都会变化,而且每周都会变化。
这对我们来说是一个问题,因为我们需要将这些 IP 的白名单添加到 Terraform 中的安全组中,以便管道可以通过 SSH 进入我们的容器并进行部署。我们确实考虑过使用类似上面的方法,通过调用第 3 方从机器获取 IP 并将其存储为 var,但这很棘手,因为我们需要在 Terraform 中应用它
更多问题包括:
如果您或任何人正在使用 Terraform,这就是我们的想法:
terraform/.../security.tf
data "external" "azure_devops_ip_ranges" {
program = ["bash", "${path.root}/../azure_devops_get_ip_ranges.sh"]
}
resource "...._security_group" "azuredevops" {
name = "azuredevops"
description = "access from azuredevops"
}
resource "...._security_group_rules" "azuredevops" {
security_group_id = ...._security_group.azuredevops.id
## had to increase the timeout here because the amount of IPs from Azure Devops was in the hundreds and it took time
timeouts {
create = "15m"
update = "15m"
delete = "5m"
}
## So yep, this looks a little ugly. We get the data from the external call with data.external.azure_devops_ip_ranges.result.ips. Then replace quotes with nothing so its just the IPs.
## Then split over a new line
ingress {
protocol = "TCP"
ports = ["22"]
cidr_list = split("\n", replace(data.external.azure_devops_ip_ranges.result.ips, "\"", ""))
}
}
terraform/azure_devops_get_ip_ranges.sh
#!/bin/bash
## Scrape the download page for the download link
DOWNLOAD_LINK=$(curl -sS https://www.microsoft.com/en-us/download/confirmation.aspx\?id\=56519 | egrep -o 'https://download.*?\.json' | uniq)
## curl the download link and use jq to get the IPs we need. For pipelines you need AzureCloud and our region was uksouth
IPS=$(curl ${DOWNLOAD_LINK} | jq '.values[] | select(.name=="AzureCloud.uksouth") | .properties.addressPrefixes'[])
## because using external data in terraform expects JSON, output JSON
jq -n \
--arg ips "$IPS" \
'{"ips":$ips}'
希望这可以帮助别人
如果您来这里是因为在尝试使用 Azure DevOps 进行 MSBuild 并部署到 Azure SQL 服务器时遇到此错误,并且有点生气,因为互联网上似乎没有任何内容,而且人们都在考虑使用 power shell脚本来找出服务器的 IP 地址和白名单等...,那么您可能最好在 yml 文件以及 MSBuild 中使用名为“Azure SQL 数据库部署”的任务,如下所示:
- task: MSBuild@1
displayName: Build the database project
inputs:
solution: '**/projectname.sqlproj'
msbuildArguments: '/t:Restore /t:Build '
- task: SqlAzureDacpacDeployment@1
inputs:
azureSubscription: ''
AuthenticationType: 'server'
ServerName: '.database.windows.net'
DatabaseName: ''
SqlUsername: ''
SqlPassword: ''
deployType: 'DacpacTask'
DeploymentAction: 'Publish'
DacpacFile: '**/projectname.dacpac'
IpDetectionMethod: 'AutoDetect'
auto 的 IpDetectionMethod 对我有用,它确实允许您轻松输入自己的值(尽管我还没有尝试过)
您应该能够将脚本部分添加到 yml 管道中,并通过快速行获取 IP 来完成它。然后当然就像其他人所说的那样,将 Azure 中需要的 IP(可能是网络安全组)列入白名单。
- script: |
curl https://ipinfo.io/ip