Устранение сбоев подключения Бастион Azure, вызванных маршрутизацией и принудительным туннелированием

Сводка

Эта статья содержит пошаговые инструкции по диагностике для выявления и устранения сбоев при подключении к Бастион Azure, вызванных определяемыми пользователем маршрутами (UDR), принудительным туннелированием, внедрением маршрута по умолчанию службой Azure Route Server или конфликтующими частными зонами DNS.

Подключения Бастион Azure завершаются сбоем, если путь к плоскости управления платформы нарушен из-за маршрутов, определяемых пользователем (UDR), маршрутов по умолчанию (0.0.0.0/0), распространяемых через Border Gateway Protocol (BGP) из Azure Route Server или локальной VPN-сети, конфликтующих частных зон DNS, которые перекрывают необходимые конечные точки управления Бастион Azure, или асимметричной маршрутизации, вызванной внедрением сетевого виртуального устройства (NVA) в подсеть виртуальной машины (VM).

Симптомы

Вы можете столкнуться с одним или несколькими из следующих симптомов:

  • Подключение к виртуальной машине через Бастион Azure перестает отвечать на этапе Connecting и в конечном итоге завершается по тайм-ауту.
  • На портале Бастион Azure отображается Failed to connect to the virtual machine или общее сообщение об ошибке подключения.
  • Бастион Azure ранее работал, но перестал работать после изменения в сети (например, таблицы маршрутов, пиринга с Route Server, связи с частной зоной DNS или развертывания NVA).
  • Недавно развернутый Бастион Azure никогда не устанавливает сеанс, несмотря на доступ к виртуальной машине из других путей.
  • На порталеSucceeded Azure отображается ресурс Бастион Azure в состоянии подготовки, но сеансы по-прежнему завершаются сбоем.

Note

Эти симптомы идентичны тем, которые вызваны блоками портов NSG или брандмауэра. Если диагностика этой статьи проходит без поиска причины, см. статью "Устранение неполадок Бастион Azure подключений, вызванных заблокированными портами".

Необходимые условия

Чтобы устранить эту проблему, вам потребуется следующее:

  • Необходимые разрешения:Network Contributor разрешения для группы ресурсов, содержащей хост Бастион Azure и его виртуальную сеть (VNet), или эквивалентные разрешения на чтение.
  • Средства: Azure CLI 2.x или агент ИИ с доступом Azure CLI.
  • Обязательные переменные и примеры этих переменных, как показано в следующей таблице
Variable Description Example
SUBSCRIPTION Идентификатор подписки Azure xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
RG Группа ресурсов, содержащая хост Бастион Azure myResourceGroup
BASTION_NAME имя ресурса Бастион Azure myBastionHost

СОВЕТ: Каждый скрипт, предоставленный в следующих разделах, запрашивает необходимые значения в интерактивном режиме. Чтобы открыть Cloud Shell и ответить на запросы, нажмите кнопку "Попробовать". Значения кэшируются для этого сеанса. Поэтому вы вводите их только один раз.

Этапы диагностики

Note

Эти действия предназначены исключительно для ознакомления ("только для чтения"). Они не вносят изменения в среду.

Шаг 1

Проверьте, существует ли ресурс Бастион Azure, находится ли он в исправном состоянии подготовки и в какой VNet и подсети он развернут.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$RG" ] && read -rp "Resource Group:   " RG
[ -z "$BASTION_NAME" ] && read -rp "Bastion Name:     " BASTION_NAME

az network bastion show \
  --name "$BASTION_NAME" \
  --resource-group "$RG" \
  --subscription "$SUBSCRIPTION" \
  --query "{provisioningState:provisioningState, sku:sku.name, subnetId:ipConfigurations[0].subnet.id}" \
  --output json

Интерпретация результатов

Если вы видите... Meaning Дальнейшие действия
"provisioningState": "Succeeded". Бастион Azure подготовлен. Выполните шаг 2a.
"provisioningState": "Failed". Сбой развертывания Бастион Azure. Проблемы с маршрутизацией или подсетью могут привести к сбою. Сначала устраните ошибку подготовки ресурсов с помощью Устранение неполадок при сбоях развертывания узла Бастион Azure, а затем повторно выполните Шаг 1.
"provisioningState": "Updating". Бастион Azure в середине обновления. Дождитесь завершения операции, а затем повторно запустите шаг 1.
ResourceNotFound Ошибка. Неверно указаны подписка, группа ресурсов или имя Бастион Azure. Проверьте переменные и повторно запустите шаг 1.

subnetId Запишите значение. Он содержит имя виртуальной сети и подтверждает, что подсеть имеет значение AzureBastionSubnet. Извлеките имя виртуальной сети и группу ресурсов из идентификатора подсети для последующего использования.

Шаг 2a

Проверьте, связана ли таблица маршрутов (UDR) и AzureBastionSubnet , если да, какие маршруты он содержит. Любой маршрут, перенаправляющий 0.0.0.0/0 в обход Internet, нарушает работу Бастион Azure.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$RG" ] && read -rp "Resource Group:   " RG
[ -z "$BASTION_NAME" ] && read -rp "Bastion Name:     " BASTION_NAME

# Derive the VNet name and subnet from the Bastion resource
BASTION_SUBNET_ID=$(az network bastion show \
  --name "$BASTION_NAME" \
  --resource-group "$RG" \
  --subscription "$SUBSCRIPTION" \
  --query "ipConfigurations[0].subnet.id" \
  --output tsv)

VNET_NAME=$(echo "$BASTION_SUBNET_ID" | sed -n 's|.*/virtualNetworks/\([^/]*\)/.*|\1|p')
VNET_RG=$(echo "$BASTION_SUBNET_ID" | sed -n 's|.*/resourceGroups/\([^/]*\)/.*|\1|p')

echo "VNet: $VNET_NAME (RG: $VNET_RG)"

# Check the AzureBastionSubnet for a route table association
az network vnet subnet show \
  --name "AzureBastionSubnet" \
  --vnet-name "$VNET_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "{routeTable:routeTable.id, addressPrefix:addressPrefix}" \
  --output json

Интерпретация результатов

Если вы видите... Meaning Дальнейшие действия
"routeTable": null. Нет UDR в AzureBastionSubnet. Выполните шаг 3.
"routeTable" содержит идентификатор ресурса таблицы маршрутов. UDR связан с AzureBastionSubnet. Выполните шаг 2b.

Шаг 2b

Проверьте маршруты в таблице маршрутов, связанной с AzureBastionSubnet, и отключено ли распространение маршрутов BGP.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION

# Extract route table name and RG from the route table ID found in Step 2
# If you already know the route table name, enter it at the prompt instead
[ -z "$RT_NAME" ] && read -rp "Route Table Name (from Step 2): " RT_NAME
[ -z "$RT_RG" ] && read -rp "Route Table Resource Group:      " RT_RG

az network route-table show \
  --name "$RT_NAME" \
  --resource-group "$RT_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "{name:name, disableBgpRoutePropagation:disableBgpRoutePropagation, routes:routes[].{name:name, addressPrefix:addressPrefix, nextHopType:nextHopType, nextHopIpAddress:nextHopIpAddress}}" \
  --output json

Интерпретация результатов

Если вы видите... Meaning Дальнейшие действия
Маршрут с "addressPrefix": "0.0.0.0/0" и "nextHopType" — это VirtualAppliance, VirtualNetworkGateway или None. Маршрут по умолчанию принудительно направляет весь трафик Бастион Azure через NVA, шлюз или чёрную дыру. Это условие приводит Бастион Azure к неработоспособности. Выполните вариант A.
Маршруты существуют, но ни один из них не перекрывает 0.0.0.0/0 и "disableBgpRoutePropagation": true. UDR имеет только определенные маршруты, и распространение BGP отключено. UDR не является причиной. Выполните шаг 3.
Маршруты существуют, но ни один из них не перекрывает 0.0.0.0/0 и "disableBgpRoutePropagation": false. UDR разрешает распространение BGP. Маршрут 0.0.0.0/0, полученный через BGP, по-прежнему может обращаться к Бастион Azure. Выполните шаг 3.
Таблица маршрутов существует, но не содержит маршрутов. Пустая таблица маршрутов. Проверьте, отключено ли распространение BGP. Если disableBgpRoutePropagation это trueтак, выполните шаг 3. Если false, выполните шаг 3, чтобы проверить наличие маршрутов по умолчанию BGP.

Шаг 3

Проверьте, внедряет ли сервер маршрутизации, VPN или шлюз Azure ExpressRoute маршрут по умолчанию 0.0.0.0/0 в виртуальную сеть Бастион Azure через BGP. Это условие является наиболее распространенным сценарием принудительного туннелирования.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group: " VNET_RG

# Check for Route Server in the same resource group as the VNet
az network routeserver list \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "[].{name:name, provisioningState:provisioningState, allowBranchToBranchTraffic:allowBranchToBranchTraffic}" \
  --output json

Если найден сервер маршрутизации, проверьте, какие маршруты анонсируют его BGP-пиры:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group: " VNET_RG
[ -z "$RS_NAME" ] && read -rp "Route Server Name:           " RS_NAME

# List peerings
az network routeserver peering list \
  --routeserver "$RS_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "[].{name:name, peerAsn:peerAsn, peerIp:peerIp}" \
  --output table

# For each peering, check learned routes for 0.0.0.0/0
[ -z "$PEERING_NAME" ] && read -rp "Peering Name (from above): " PEERING_NAME

az network routeserver peering list-learned-routes \
  --name "$PEERING_NAME" \
  --routeserver "$RS_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --output json

Интерпретация результатов

Если вы видите... Meaning Дальнейшие действия
Сервер маршрутов не найден (результат: []). Нет сервера маршрутизации в этой группе ресурсов. Внедрение маршрутов BGP по умолчанию из сервера маршрутизации не является причиной. Выполните шаг 4.
Сервер маршрутов существует, но обучаемые маршруты не содержат 0.0.0.0/0. Сервер маршрутов присутствует, но маршрут по умолчанию не объявляется. Выполните шаг 4.
Маршруты, полученные сервером маршрутизации, содержат 0.0.0.0/0 от BGP-пира. Одноранговый узел BGP внедряет маршрут по умолчанию в виртуальную сеть. Этот маршрут достигает AzureBastionSubnet и прерывает Бастион Azure. Выполните разрешение B.
Нет сервера маршрутизации, но в виртуальной сети существует VPN-шлюз или шлюз ExpressRoute. Локальная среда может рекламировать 0.0.0.0/0 через шлюз. Проверьте выученные маршруты шлюза или действующие маршруты на сетевой карте виртуальной машины (NIC) в той же сети VNet на наличие маршрута 0.0.0.0/0 с источником VirtualNetworkGateway. При наличии выполните разрешение B.

Tip

Если сервер маршрутизации отсутствует, проверьте наличие шлюза Azure VPN Gateway или ExpressRoute в виртуальной сети, который может распространять локальный маршрут по умолчанию. Запустите команду az network vnet-gateway list --resource-group "$VNET_RG" --subscription "$SUBSCRIPTION" --output table, чтобы проверить.

Шаг 4

Проверьте, связаны ли частные зоны DNS с именами, конфликтующими с необходимыми конечными точками управления Бастион Azure, с виртуальной сетью Бастион Azure. Бастион Azure должен разрешать несколько конечных точек служб Azure через общедоступную систему DNS. Частная зона DNS с тем же именем перекрывает общедоступную DNS-запись и нарушает работу службы.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group: " VNET_RG
[ -z "$VNET_NAME" ] && read -rp "Bastion VNet Name:          " VNET_NAME

# List all private DNS zones in the subscription and check for conflicting names
# Known conflicting zone names for Azure Bastion:
BLOCKED_ZONES="management.azure.com blob.core.windows.net core.windows.net vault.azure.net"

echo "Checking for private DNS zones linked to VNet: $VNET_NAME"
echo "---"

VNET_ID=$(az network vnet show \
  --name "$VNET_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "id" \
  --output tsv)

# List all private DNS zones in the subscription
az network private-dns zone list \
  --subscription "$SUBSCRIPTION" \
  --query "[].{name:name, resourceGroup:resourceGroup}" \
  --output json | \
  jq -r '.[] | "\(.resourceGroup) \(.name)"' | \
  while read ZONE_RG ZONE_NAME; do
    # Check if this zone is linked to the Bastion VNet
    LINKS=$(az network private-dns link vnet list \
      --zone-name "$ZONE_NAME" \
      --resource-group "$ZONE_RG" \
      --subscription "$SUBSCRIPTION" \
      --query "[?virtualNetwork.id=='$VNET_ID'].{linkName:name, registrationEnabled:registrationEnabled}" \
      --output json 2>/dev/null)
    if [ "$LINKS" != "[]" ] && [ -n "$LINKS" ]; then
      for BLOCKED in $BLOCKED_ZONES; do
        if [ "$ZONE_NAME" = "$BLOCKED" ]; then
          echo "⚠ CONFLICT: Private DNS zone '$ZONE_NAME' (RG: $ZONE_RG) is linked to the Bastion VNet"
          echo "  Link details: $LINKS"
        fi
      done
    fi
  done

echo "---"
echo "Check complete."

Note

Полный список имен частных DNS-зон, которые нарушают работу Бастион Azure, может включать дополнительные зоны помимо перечисленных здесь. См. последние вопросы и ответы по Бастион Azure, чтобы получить самую актуальную информацию.

Интерпретация результатов

Если вы видите... Meaning Дальнейшие действия
Check complete. без ⚠ CONFLICT строк. Конфликтующие частные зоны DNS не связаны с виртуальной сетью Бастион Azure. Выполните шаг 5.
Одна или несколько ⚠ CONFLICT строк с описанием частной зоны DNS. Частная зона DNS перекрывает конечную точку, которую Бастион Azure должен разрешить. Это условие нарушает работу тракта плоскости управления. Выполните операцию C.

Шаг 5

Проверьте, не приводит ли маршрутизация в подсети целевой виртуальной машины к асимметричным путям или промежуточным устройствам NVA, которые нарушают подключение Бастион Azure к виртуальной машине. Это условие применяется, когда шаг 1шаг 4 не выявили проблем, но сеансы по-прежнему не удаются.

Выполните следующие команды в Azure CLI:

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VM_NAME" ] && read -rp "Target VM Name:   " VM_NAME
[ -z "$VM_RG" ] && read -rp "Target VM Resource Group: " VM_RG

# Get the VM's primary NIC
VM_NIC_ID=$(az vm show \
  --name "$VM_NAME" \
  --resource-group "$VM_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "networkProfile.networkInterfaces[0].id" \
  --output tsv)

echo "VM NIC: $VM_NIC_ID"

# Show effective routes on the VM's NIC
az network nic show-effective-route-table \
  --ids "$VM_NIC_ID" \
  --subscription "$SUBSCRIPTION" \
  --output table

Интерпретация результатов

Просмотрите маршруты с адресом назначения, соответствующим префиксу адреса AzureBastionSubnet (из шага 2a) или более широкому префиксу, который включает его.

Если вы видите... Meaning Дальнейшие действия
Трафик от виртуальной машины к AzureBastionSubnet маршрутизируется через VirtualNetwork (следующий переход: VNetLocal). Прямой путь. NVA не мешает. Все проверки диагностики маршрутизации пройдены. Проверьте заблокированные порты далее, а затем отправьте запрос поддержка Azure, если он по-прежнему неразрешен.
Трафик от виртуальной машины к AzureBastionSubnet направляется через VirtualAppliance (следующий переход — IP-адрес NVA). NVA находится на обратном пути между виртуальной машиной и Бастион Azure. Это условие приводит к асимметричной маршрутизации и разрывает сеанс. Выполните Resolution D.
Маршрут 0.0.0.0/0 через VirtualAppliance в подсети виртуальной машины, а не более конкретный маршрут для подсети Бастион Azure. Весь трафик ВМ, включая обратный трафик Бастион Azure, принудительно направляется через NVA. Выполните Resolution D.

Карта принятия решений

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

Результат диагностики Дальнейшие действия
UDR AzureBastionSubnet содержит маршрут 0.0.0.0/0, указывающий на NVA, шлюз или None. Выполните вариант A.
UDR на AzureBastionSubnet содержит маршрут, переопределяющий трафик, направленный в Интернет Выполните вариант A.
Сервер маршрутизации, VPN или шлюз ExpressRoute анонсирует маршрут 0.0.0.0/0 в виртуальную сеть Бастион Azure. Выполните разрешение B.
Частная зона DNS с заблокированным именем привязана к виртуальной сети Бастион Azure. Выполните операцию C.
NVA или UDR в подсети виртуальной машины разбивает путь возврата к Бастион Azure. Выполните Resolution D.
Все диагностические проверки пройдены, но проблемы сохраняются. Дополнительные сведения и рекомендации см. в статье об устранении неполадок Бастион Azure подключений, вызванных заблокированными портами. Затем отправьте запрос поддержка Azure, если он по-прежнему неразрешен.

Разрешение A

Маршрут, определяемый пользователем (UDR), на AzureBastionSubnet перенаправляет трафик в обход следующего перехода через Интернет. Бастион Azure требует прямого доступа к Интернету для обмена данными на уровне управления. Любой маршрут, который переопределяет системный маршрут по умолчанию 0.0.0.0/0 в Интернет, нарушает этот маршрут.

Note

В Azure средство защиты платформы RouteTableCannotBeAttachedForAzureBastionSubnet блокирует подключение таблицы маршрутов к AzureBastionSubnet, если таблица содержит маршрут 0.0.0.0/0 со следующим переходом, отличным от Интернета. Этот сценарий по-прежнему применяется к развертываниям, в которых таблица маршрутов была связана до появления охранника или где проблематичный маршрут был добавлен после сопоставления.

Выполните следующие команды в Azure CLI.

  1. Подтвердите проблемную таблицу маршрутизации и её маршруты.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$RT_NAME" ] && read -rp "Route Table Name:             " RT_NAME
[ -z "$RT_RG" ] && read -rp "Route Table Resource Group:    " RT_RG

az network route-table show \
  --name "$RT_NAME" \
  --resource-group "$RT_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "{name:name, routes:routes[].{name:name, addressPrefix:addressPrefix, nextHopType:nextHopType, nextHopIpAddress:nextHopIpAddress}}" \
  --output json

Запишите имена маршрутов, содержащих addressPrefix из 0.0.0.0/0 или любой префикс, который может перехватывать трафик Бастион Azure на уровне управления.

  1. Используйте один из двух следующих вариантов, чтобы удалить проблемные маршруты из подсети Бастион Azure.

Important

Следующие команды — это все операции записи, требующие утверждения, прежде чем их можно будет запустить.

Вариант 1: Полностью отвязать таблицу маршрутов от AzureBastionSubnet (предпочтительно, если таблица маршрутов используется только для принудительного туннелирования)

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_NAME" ] && read -rp "Bastion VNet Name:            " VNET_NAME
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group:   " VNET_RG

az network vnet subnet update \
  --name "AzureBastionSubnet" \
  --vnet-name "$VNET_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --route-table "" \
  --output json

Вариант 2. Удаление только обижающего маршрута 0.0.0.0/0 (если таблица маршрутов содержит другие необходимые маршруты)

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$RT_NAME" ] && read -rp "Route Table Name:             " RT_NAME
[ -z "$RT_RG" ] && read -rp "Route Table Resource Group:    " RT_RG
[ -z "$ROUTE_NAME" ] && read -rp "Route Name to Delete (from A.1): " ROUTE_NAME

az network route-table route delete \
  --route-table-name "$RT_NAME" \
  --resource-group "$RT_RG" \
  --subscription "$SUBSCRIPTION" \
  --name "$ROUTE_NAME"
  1. Повторно выполните шаг 2a. Подтвердите "routeTable": null (вариант 1) или что маршрут 0.0.0.0/0 отсутствует (вариант 2). Затем проверьте подключение Бастион Azure.

Если проблема сохраняется, перейдите к шагу 3 , чтобы проверить наличие маршрутов по умолчанию, распространяемых BGP.

Разрешение B

Маршрут по умолчанию 0.0.0.0/0 распространяется в виртуальную сеть Бастион Azure через BGP либо от Route Server (где одноранговый узел NVA объявляет маршрут по умолчанию), либо из локальной сети через VPN-шлюз или шлюз ExpressRoute. Этот маршрут направляет трафик плоскости управления Бастион Azure по пути, где он отбрасывается.

Выполните следующие команды в Azure CLI.

  1. Определите источник маршрута 0.0.0.0/0.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group: " VNET_RG

# Check for Route Server
az network routeserver list \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "[].{name:name}" \
  --output table

# Check for VPN/ExpressRoute gateways
az network vnet-gateway list \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "[].{name:name, gatewayType:gatewayType}" \
  --output table
  1. Используйте один из двух следующих вариантов в соответствии с вашим сценарием.

Вариант 1: источником является Route Server Настройте одноранговый BGP-узел NVA так, чтобы он прекратил анонсирование 0.0.0.0/0, или отключите распространение маршрутов BGP в таблице маршрутов AzureBastionSubnet, чтобы маршруты, полученные через BGP, не передавались в Бастион Azure.

Important

Следующие команды — это все операции записи, требующие утверждения, прежде чем их можно будет запустить.

Чтобы отключить распространение BGP в сети AzureBastionSubnet, сначала убедитесь, что таблица маршрутов связана (создайте ее при необходимости), а затем отключите распространение. Azure требует, чтобы любая таблица маршрутов, связанная с AzureBastionSubnet, содержала маршрут от 0.0.0.0/0 до Internet. Следующий скрипт добавляет этот маршрут перед привязкой таблицы.

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_NAME" ] && read -rp "Bastion VNet Name:            " VNET_NAME
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group:   " VNET_RG

# Check if a route table is already associated
EXISTING_RT=$(az network vnet subnet show \
  --name "AzureBastionSubnet" \
  --vnet-name "$VNET_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "routeTable.id" \
  --output tsv)

if [ -z "$EXISTING_RT" ] || [ "$EXISTING_RT" = "None" ]; then
  echo "No route table on AzureBastionSubnet. Creating one..."
  az network route-table create \
    --name "rt-AzureBastionSubnet" \
    --resource-group "$VNET_RG" \
    --subscription "$SUBSCRIPTION" \
    --disable-bgp-route-propagation true \
    --output json

  az network route-table route create \
    --route-table-name "rt-AzureBastionSubnet" \
    --resource-group "$VNET_RG" \
    --subscription "$SUBSCRIPTION" \
    --name "allow-internet" \
    --address-prefix "0.0.0.0/0" \
    --next-hop-type "Internet"

  az network vnet subnet update \
    --name "AzureBastionSubnet" \
    --vnet-name "$VNET_NAME" \
    --resource-group "$VNET_RG" \
    --subscription "$SUBSCRIPTION" \
    --route-table "rt-AzureBastionSubnet" \
    --output json
else
  echo "Route table already associated: $EXISTING_RT"
  RT_NAME_EXTRACTED=$(echo "$EXISTING_RT" | sed -n 's|.*/routeTables/\(.*\)|\1|p')
  RT_RG_EXTRACTED=$(echo "$EXISTING_RT" | sed -n 's|.*/resourceGroups/\([^/]*\)/.*|\1|p')
  az network route-table update \
    --name "$RT_NAME_EXTRACTED" \
    --resource-group "$RT_RG_EXTRACTED" \
    --subscription "$SUBSCRIPTION" \
    --disable-bgp-route-propagation true \
    --output json

  # Ensure a 0.0.0.0/0 → Internet route exists (required by Azure for AzureBastionSubnet)
  HAS_INTERNET_ROUTE=$(az network route-table route list \
    --route-table-name "$RT_NAME_EXTRACTED" \
    --resource-group "$RT_RG_EXTRACTED" \
    --subscription "$SUBSCRIPTION" \
    --query "[?addressPrefix=='0.0.0.0/0' && nextHopType=='Internet'].name | [0]" \
    --output tsv)

  if [ -z "$HAS_INTERNET_ROUTE" ] || [ "$HAS_INTERNET_ROUTE" = "None" ]; then
    echo "Adding required 0.0.0.0/0 → Internet route..."
    az network route-table route create \
      --route-table-name "$RT_NAME_EXTRACTED" \
      --resource-group "$RT_RG_EXTRACTED" \
      --subscription "$SUBSCRIPTION" \
      --name "allow-internet" \
      --address-prefix "0.0.0.0/0" \
      --next-hop-type "Internet"
  fi
fi

Вариант 2. VPN или Шлюз ExpressRoute является источником

Исправление зависит от структуры сети. Выполните один из следующих шагов:

  • Отключите распространение AzureBastionSubnet маршрутов BGP (те же команды в варианте 1).
  • Переместите Бастион Azure в отдельную виртуальную сеть, которая не подключена к маршруту принудительного туннелирования, и настройте пиринг с виртуальной сетью рабочей нагрузки.
  1. Убедитесь, что распространение BGP отключено на AzureBastionSubnet.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VNET_NAME" ] && read -rp "Bastion VNet Name:            " VNET_NAME
[ -z "$VNET_RG" ] && read -rp "Bastion VNet Resource Group:   " VNET_RG

RT_ID=$(az network vnet subnet show \
  --name "AzureBastionSubnet" \
  --vnet-name "$VNET_NAME" \
  --resource-group "$VNET_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "routeTable.id" \
  --output tsv)

az network route-table show \
  --ids "$RT_ID" \
  --subscription "$SUBSCRIPTION" \
  --query "{name:name, disableBgpRoutePropagation:disableBgpRoutePropagation}" \
  --output json

Подтвердите "disableBgpRoutePropagation": true. Затем проверьте подключение Бастион Azure.

Если проблема сохраняется, перейдите к шагу 4 , чтобы проверить наличие частных конфликтов DNS.

Резолюция C

Частная зона DNS с именем, которая соответствует одной из обязательных конечных точек управления Бастион Azure, связана с виртуальной сетью Бастион Azure. Эта конфигурация приводит к тому, что внутреннее разрешение DNS Бастион Azure возвращает частные IP-адреса (или NXDOMAIN) вместо общедоступных конечных точек службы Azure, необходимых ей.

Известные конфликтующие имена частных зон DNS включают:

  • management.azure.com
  • blob.core.windows.net
  • core.windows.net
  • vault.azure.net

Note

Полный список имен частных DNS-зон, которые нарушают работу Бастион Azure, может включать дополнительные зоны помимо перечисленных здесь. См. последние вопросы и ответы по Бастион Azure, чтобы получить самую актуальную информацию.

Выполните следующие команды в Azure CLI.

  1. Определите конфликтующую ссылку на зону.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$ZONE_NAME" ] && read -rp "Conflicting DNS Zone Name (from Step 4): " ZONE_NAME
[ -z "$ZONE_RG" ] && read -rp "DNS Zone Resource Group:                  " ZONE_RG

az network private-dns link vnet list \
  --zone-name "$ZONE_NAME" \
  --resource-group "$ZONE_RG" \
  --subscription "$SUBSCRIPTION" \
  --output table

Запишите имя ссылки, указывающее на виртуальную сеть Бастион Azure.

  1. Отвяжите конфликтующую частную зону DNS. Это действие не удаляет зону или не влияет на другие виртуальные сети, связанные с ней.

Important

Следующие команды — это все операции записи, требующие утверждения, прежде чем их можно будет запустить.

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$ZONE_NAME" ] && read -rp "Conflicting DNS Zone Name:    " ZONE_NAME
[ -z "$ZONE_RG" ] && read -rp "DNS Zone Resource Group:       " ZONE_RG
[ -z "$LINK_NAME" ] && read -rp "VNet Link Name (from C.1):    " LINK_NAME

az network private-dns link vnet delete \
  --name "$LINK_NAME" \
  --zone-name "$ZONE_NAME" \
  --resource-group "$ZONE_RG" \
  --subscription "$SUBSCRIPTION" \
  --yes

Tip

Если другие службы в виртуальной сети Бастион Azure зависят от этой частной зоны DNS, рассмотрите возможность перемещения Бастион Azure в отдельную виртуальную сеть (с пирингом виртуальной сети в виртуальную сеть рабочей нагрузки), где конфликтующая зона не связана.

  1. Повторно выполните шаг 4. Убедитесь, что строки ⚠ CONFLICT не отображаются. Затем проверьте подключение Бастион Azure.

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

Разрешение D

UDR или NVA в подсети целевой виртуальной машины заставляют обратный трафик (от виртуальной машины обратно к Бастион Azure) проходить через промежуточное устройство или по альтернативному маршруту. Эта настройка создает асимметричный маршрут. Бастион Azure отправляет трафик непосредственно на виртуальную машину через магистраль Azure, но ответ виртуальной машины проходит через NVA. Эта конфигурация удаляет трафик, применяет преобразование сетевых адресов (NAT) или сбрасывает подключение.

Выполните следующие команды в Azure CLI.

  1. Подтвердите маршрут NVA в подсети виртуальной машины.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VM_NAME" ] && read -rp "Target VM Name:   " VM_NAME
[ -z "$VM_RG" ] && read -rp "Target VM Resource Group: " VM_RG

# Get the VM's subnet
VM_SUBNET_ID=$(az vm show \
  --name "$VM_NAME" \
  --resource-group "$VM_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "networkProfile.networkInterfaces[0].id" \
  --output tsv | xargs -I{} az network nic show --ids {} --subscription "$SUBSCRIPTION" --query "ipConfigurations[0].subnet.id" --output tsv)

echo "VM Subnet: $VM_SUBNET_ID"

# Check route table on VM subnet
az network vnet subnet show \
  --ids "$VM_SUBNET_ID" \
  --subscription "$SUBSCRIPTION" \
  --query "{routeTable:routeTable.id}" \
  --output json
  1. Добавьте в таблицу маршрутов подсети виртуальной машины конкретный маршрут, чтобы трафик с назначением AzureBastionSubnet направлялся напрямую через виртуальную сеть (в обход NVA), а остальной трафик по-прежнему направлялся через NVA.

Important

Следующие команды — это все операции записи, требующие утверждения, прежде чем их можно будет запустить.

# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VM_RT_NAME" ] && read -rp "VM Subnet Route Table Name:     " VM_RT_NAME
[ -z "$VM_RT_RG" ] && read -rp "VM Subnet Route Table RG:        " VM_RT_RG
[ -z "$BASTION_SUBNET_PREFIX" ] && read -rp "AzureBastionSubnet CIDR (from Step 2, e.g. 10.0.1.0/26): " BASTION_SUBNET_PREFIX

az network route-table route create \
  --route-table-name "$VM_RT_NAME" \
  --resource-group "$VM_RT_RG" \
  --subscription "$SUBSCRIPTION" \
  --name "direct-to-bastion-subnet" \
  --address-prefix "$BASTION_SUBNET_PREFIX" \
  --next-hop-type "VnetLocal"
  1. Убедитесь, что новый маршрут активен в сетевом адаптере виртуальной машины.
# ── Collect inputs (cached if already set in this session) ──
[ -z "$SUBSCRIPTION" ] && read -rp "Subscription ID:  " SUBSCRIPTION
[ -z "$VM_NAME" ] && read -rp "Target VM Name:   " VM_NAME
[ -z "$VM_RG" ] && read -rp "Target VM Resource Group: " VM_RG

VM_NIC_ID=$(az vm show \
  --name "$VM_NAME" \
  --resource-group "$VM_RG" \
  --subscription "$SUBSCRIPTION" \
  --query "networkProfile.networkInterfaces[0].id" \
  --output tsv)

az network nic show-effective-route-table \
  --ids "$VM_NIC_ID" \
  --subscription "$SUBSCRIPTION" \
  --query "value[?contains(addressPrefix[0], '$(echo $BASTION_SUBNET_PREFIX | cut -d/ -f1)')]" \
  --output table

Убедитесь, что для маршрута до префикса AzureBastionSubnet в качестве следующего перехода указан VnetLocal. Затем проверьте подключение Бастион Azure.

Если проблема сохраняется после проверки всех четырех решений, маршрутизация не является проблемой. Продолжите устранение сбоев подключения Бастион Azure, вызванных блокировкой портов. Если и эта статья не помогла решить проблему, отправьте запрос в службу поддержки Azure.

References