Fundamentação Teórica: Implement Azure Bastion
1. Intuição Inicial​
Imagine que você precisa acessar remotamente um servidor que fica numa sala trancada dentro de um prédio corporativo. Existem duas abordagens: dar uma cópia da chave de acesso para cada funcionário que precisa entrar (arriscado, difÃcil de controlar) ou criar uma sala de recepção controlada com um segurança, onde todos os visitantes passam antes de ser escoltados até a sala de servidores. O segurança verifica a identidade, registra a visita e não permite acesso direto.
Azure Bastion é essa sala de recepção controlada para VMs no Azure. Em vez de abrir a porta SSH (22) ou RDP (3389) diretamente da internet para as VMs, você acessa todas as VMs através do Bastion, que funciona como um ponto de acesso seguro, gerenciado pela Microsoft, acessÃvel pelo próprio navegador web sem necessidade de clientes RDP/SSH instalados.
A consequência prática mais importante é que suas VMs não precisam de IP público e não precisam ter SSH/RDP abertos na internet. O Bastion faz a ponte de forma segura.
2. Contexto​
2.1 O problema que o Bastion resolve​
Antes do Bastion, para acessar uma VM remotamente, as organizações faziam uma ou mais destas coisas:
- AtribuÃam IP público à VM e abriam porta 22/3389 no NSG (altamente inseguro)
- Implantavam uma "jump box" ou "bastion host" manualmente: uma VM com IP público usada como intermediária, que precisava ser gerenciada, patchada e monitorada
- Usavam VPN para conectar toda a rede corporativa à VNet Azure
O Azure Bastion elimina as duas primeiras opções e complementa a terceira, oferecendo um serviço gerenciado pela Microsoft com alta disponibilidade, sem necessidade de gerenciar o servidor intermediário.
2.2 Posição no ecossistema de segurança​
3. Construção dos Conceitos​
3.1 Como o Bastion funciona tecnicamente​
O Azure Bastion opera como um PaaS (Platform as a Service) implantado dentro da sua VNet. Ele:
- Recebe conexões HTTPS (porta 443) do administrador via navegador
- Estabelece a sessão RDP ou SSH com a VM alvo dentro da rede privada
- Converte o protocolo: RDP/SSH é transmitido sobre WebSocket (HTTPS), transparente para o usuário
- Renderiza a sessão de área de trabalho ou terminal diretamente no navegador
O resultado é que nenhum tráfego RDP/SSH trafega pela internet. O único tráfego externo é HTTPS para o Bastion. O Bastion então faz a conexão RDP/SSH internamente na VNet.
3.2 A AzureBastionSubnet: o requisito mais crÃtico​
O Bastion deve ser implantado em uma subnet com nome obrigatoriamente igual a AzureBastionSubnet. Não é possÃvel usar outro nome. Além disso:
- O tamanho mÃnimo da subnet é
/26(64 IPs), exceto no SKU Developer que aceita/27ou menor - A subnet não pode ter NSG associado (apenas SKU Standard e acima permitem NSG com regras especÃficas)
- A subnet não pode ter UDR (User Defined Routes) que redirecionem tráfego
- A subnet não pode ter outros recursos além do próprio Bastion
Por que
/26no mÃnimo? O Bastion usa múltiplas instâncias internas para alta disponibilidade e escalabilidade. Cada instância precisa de IPs. Com/26, você tem 59 IPs utilizáveis (64 menos 5 reservados pelo Azure), suficientes para escalar.
3.3 SKUs do Azure Bastion​
O Bastion tem quatro SKUs com capacidades crescentes:
| SKU | Sessões Simultâneas | Funcionalidades | Uso Recomendado |
|---|---|---|---|
| Developer | Limitado (compartilhado) | SSH e RDP básico | Desenvolvimento/teste pessoal |
| Basic | 25 | SSH, RDP, copy/paste | Ambientes pequenos |
| Standard | 50+ (escalável) | Basic + upload/download de arquivos, kerberos auth, IP-based connection, shareable links | Produção |
| Premium | Mais alto | Standard + session recording, private-only Bastion | Compliance e auditoria |
Developer SKU: Diferente dos outros, não requer subnet dedicada
AzureBastionSubnet. É implantado de forma mais simples mas com limitações severas de capacidade. Adequado apenas para uso individual em desenvolvimento.
3.4 Conectividade com VMs em VNets pareadas​
Uma das funcionalidades mais valiosas do SKU Standard é o suporte a VNet peering: um único Bastion implantado em uma VNet hub pode acessar VMs em VNets spoke pareadas.
Isso elimina a necessidade de implantar um Bastion em cada VNet, reduzindo custo operacional em arquiteturas hub-and-spoke.
3.5 Funcionalidades do SKU Standard e Premium​
Upload e download de arquivos: Permite transferir arquivos entre a máquina local do administrador e a VM através da sessão Bastion, sem necessidade de storage intermediário.
IP-based connection: Permite conectar a uma VM pelo endereço IP privado em vez de pelo Resource ID do Azure. Útil para VMs não Azure na mesma VNet ou para cenários de automação.
Shareable links: Gera um link de conexão que pode ser compartilhado com outros usuários para acesso à VM via Bastion, com validade configurável.
Kerberos authentication: Permite autenticação integrada com Active Directory ao conectar via RDP em VMs Windows joined ao domÃnio.
Session recording (Premium): Grava sessões RDP/SSH para auditoria e conformidade, armazenando os vÃdeos em Storage Account.
Private-only Bastion (Premium): Desabilita o IP público do Bastion; acesso é feito apenas via rede privada (ExpressRoute/VPN).
4. Visão Estrutural​
5. Funcionamento na Prática​
5.1 Pré-requisitos para implantar o Bastion​
Antes de criar o Bastion, você precisa:
- Uma VNet existente onde o Bastion será implantado
- A subnet
AzureBastionSubnetcriada com no mÃnimo/26 - Um IP público (Standard SKU) para o Bastion (criado automaticamente pelo portal ou manualmente)
- O usuário que iniciará conexões precisa ter permissão de Reader na VM, na NIC, e no Bastion
5.2 O NSG da AzureBastionSubnet​
Embora o Bastion Basic não permita NSG na subnet, o SKU Standard permite e recomenda NSG com as seguintes regras obrigatórias:
Regras Inbound obrigatórias:
| Prioridade | Source | Porta Dest | Protocolo | Ação | Propósito |
|---|---|---|---|---|---|
| 120 | Internet | 443 | TCP | Allow | Acesso HTTPS do administrador |
| 130 | GatewayManager | 443 | TCP | Allow | Gerenciamento do plano de controle do Azure |
| 140 | AzureLoadBalancer | 443 | TCP | Allow | Probe de saúde do Load Balancer |
| 150 | VirtualNetwork | 8080, 5701 | Any | Allow | Comunicação entre instâncias do Bastion |
Regras Outbound obrigatórias:
| Prioridade | Destination | Porta Dest | Protocolo | Ação | Propósito |
|---|---|---|---|---|---|
| 100 | VirtualNetwork | 22, 3389 | Any | Allow | Conexão SSH/RDP às VMs |
| 110 | AzureCloud | 443 | TCP | Allow | Comunicação com serviços Azure (diagnóstico) |
| 120 | Internet | 80 | TCP | Allow | Verificações de certificado CRL |
| 130 | VirtualNetwork | 8080, 5701 | Any | Allow | Comunicação entre instâncias |
5.3 Conectando via Bastion no Portal​
- Navegue até a VM no portal
- Clique em Connect > Bastion
- Se o Bastion não existir ainda, o portal oferece criação rápida com configurações padrão
- Insira as credenciais (usuário/senha ou SSH key)
- Escolha o tipo de autenticação (password ou private key)
- Clique em Connect
Uma nova aba do navegador abre com a sessão RDP ou SSH diretamente no browser.
5.4 Autenticação com chave SSH​
Para VMs Linux usando autenticação por chave:
No formulário de conexão do Bastion:
- Authentication Type:
SSH Private Key from Azure Key Vault(recomendado) ouSSH Private Key from Local File - Se usar Key Vault: especifique o Key Vault e o secret que contém a chave privada
Prática recomendada: Armazene chaves SSH em Azure Key Vault e configure o Bastion para buscar a chave de lá. Isso elimina a necessidade de armazenar chaves privadas localmente ou transferi-las pelo navegador.
6. Formas de Implementação​
6.1 Portal Azure​
Quando usar: Implantação inicial, ambientes com poucas VNets, quando a criação visual é preferida.
Criação rápida (Quick Create):
VM > Connect > Bastion > Create Azure Bastion using defaults
O portal cria automaticamente a AzureBastionSubnet (se não existir, com /26), o IP público e o Bastion com SKU Basic. É a forma mais rápida mas menos controlada.
Criação manual:
Bastion > + Create
Permite escolher VNet, subnet, IP público, SKU e configurações avançadas.
6.2 Azure CLI​
Criando a subnet AzureBastionSubnet:
az network vnet subnet create \
--vnet-name myVNet \
--resource-group myRG \
--name AzureBastionSubnet \
--address-prefix 10.0.10.0/26
Criando IP público para o Bastion:
az network public-ip create \
--resource-group myRG \
--name BastionPublicIP \
--sku Standard \
--allocation-method Static \
--location eastus
Criando o Bastion (SKU Basic):
az network bastion create \
--name myBastion \
--resource-group myRG \
--vnet-name myVNet \
--public-ip-address BastionPublicIP \
--location eastus \
--sku Basic
Criando o Bastion (SKU Standard com funcionalidades extras):
az network bastion create \
--name myBastion \
--resource-group myRG \
--vnet-name myVNet \
--public-ip-address BastionPublicIP \
--location eastus \
--sku Standard \
--enable-tunneling true \
--enable-ip-connect true \
--enable-shareable-link true \
--scale-units 5
Conectando via Bastion pela CLI (tunnel):
Com SKU Standard e --enable-tunneling true, você pode criar um túnel local e usar seu cliente SSH/RDP nativo:
# Criar túnel SSH para VM
az network bastion tunnel \
--name myBastion \
--resource-group myRG \
--target-resource-id <vm-resource-id> \
--resource-port 22 \
--port 50022
# Em outro terminal, conectar via SSH local usando o túnel
ssh -p 50022 adminuser@localhost
Isso permite usar o cliente SSH local (com todas suas funcionalidades, como SSH agent forwarding) através do Bastion.
Conectando via SSH diretamente pelo CLI:
az network bastion ssh \
--name myBastion \
--resource-group myRG \
--target-resource-id <vm-resource-id> \
--auth-type password \
--username adminuser
6.3 Azure PowerShell​
# Criar Bastion
$vnet = Get-AzVirtualNetwork `
-Name "myVNet" `
-ResourceGroupName "myRG"
$publicIp = New-AzPublicIpAddress `
-ResourceGroupName "myRG" `
-Name "BastionPublicIP" `
-Location "eastus" `
-AllocationMethod Static `
-Sku Standard
New-AzBastion `
-ResourceGroupName "myRG" `
-Name "myBastion" `
-PublicIpAddress $publicIp `
-VirtualNetwork $vnet `
-Sku "Standard" `
-ScaleUnit 5
6.4 Bicep​
// Subnet dedicada para Bastion
resource bastionSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-05-01' = {
parent: vnet
name: 'AzureBastionSubnet'
properties: {
addressPrefix: '10.0.10.0/26'
}
}
// IP Público Standard para o Bastion
resource bastionPublicIp 'Microsoft.Network/publicIPAddresses@2023-05-01' = {
name: 'BastionPublicIP'
location: location
sku: {
name: 'Standard'
}
properties: {
publicIPAllocationMethod: 'Static'
}
}
// Azure Bastion SKU Standard
resource bastion 'Microsoft.Network/bastionHosts@2023-05-01' = {
name: 'myBastion'
location: location
sku: {
name: 'Standard'
}
properties: {
enableTunneling: true
enableIpConnect: true
enableShareableLink: true
scaleUnits: 5
ipConfigurations: [
{
name: 'IpConf'
properties: {
subnet: {
id: bastionSubnet.id
}
publicIPAddress: {
id: bastionPublicIp.id
}
}
}
]
}
}
7. Controle e Segurança​
7.1 Controle de acesso ao Bastion​
O acesso ao Bastion é controlado por RBAC no nÃvel de cada recurso:
| Role | Permissão | Escopo |
|---|---|---|
| Reader | Visualizar recursos | VM, NIC, Bastion (todos os três) |
| Bastion Reader | Iniciar sessão Bastion | Recurso do Bastion |
O usuário precisa de pelo menos Reader nos três recursos: a VM de destino, a NIC da VM e o recurso do Bastion. Sem permissão no Bastion, a opção de conexão não aparece.
Para segurança granular, use Azure AD Conditional Access para exigir MFA ao acessar o portal Azure antes de iniciar sessões Bastion.
7.2 Logs e auditoria de sessões​
Todas as sessões iniciadas via Bastion geram logs no Azure Monitor / Activity Log:
# Ver sessões Bastion no Activity Log
az monitor activity-log list \
--resource-group myRG \
--query "[?contains(operationName.value, 'bastionHosts')].{Time:eventTimestamp, Operation:operationName.value, User:claims.upn}" \
--output table
Para auditoria mais detalhada (quem conectou, em qual VM, por quanto tempo), habilite diagnósticos do Bastion:
az monitor diagnostic-settings create \
--name "bastion-audit" \
--resource <bastion-resource-id> \
--logs '[
{"category": "BastionAuditLogs", "enabled": true}
]' \
--workspace <log-analytics-workspace-id>
Os logs de auditoria incluem: usuário, VM de destino, duração da sessão, tipo de conexão (SSH/RDP) e endereço IP de origem.
7.3 Session Recording (SKU Premium)​
Com o SKU Premium, as sessões RDP podem ser gravadas automaticamente em vÃdeo e armazenadas em um Azure Storage Account:
az network bastion create \
--name myBastion \
--resource-group myRG \
--vnet-name myVNet \
--public-ip-address BastionPublicIP \
--sku Premium \
--enable-session-recording true \
--storage-account <storage-account-id>
Session recording é especialmente valorizado em ambientes financeiros e de saúde onde a auditoria de ações administrativas é requisito regulatório.
7.4 Private-only Bastion (SKU Premium)​
Em ambientes de máxima segurança, o Bastion pode ser configurado sem IP público. O acesso é feito apenas via rede privada (VPN ou ExpressRoute):
az network bastion create \
--name myBastion \
--resource-group myRG \
--vnet-name myVNet \
--sku Premium \
--disable-copy-paste false \
--enable-private-only true
Neste modo, administradores precisam estar na rede corporativa (via VPN ou ExpressRoute) para acessar o Bastion, adicionando mais uma camada de segurança.
8. Tomada de Decisão​
8.1 Bastion vs alternativas de acesso remoto​
| Situação | Melhor escolha | Motivo |
|---|---|---|
| VM com IP público e SSH aberto | Migrar para Bastion | SSH aberto na internet é risco crÃtico |
| Jump box gerenciada manualmente | Bastion | Elimina overhead de gerenciar VM intermediária |
| Muitas VMs em múltiplas VNets | Bastion Standard em hub + peering | Um Bastion cobre todas as VNets spoke |
| Acesso de desenvolvedor com cliente SSH local | Bastion Standard com tunneling | Usa cliente SSH nativo através do túnel |
| Ambiente com requisito de auditoria de sessão | Bastion Premium | Session recording para compliance |
| Equipe grande sem VPN corporativa | Bastion Standard + Conditional Access + MFA | Acesso via browser com autenticação forte |
| Rede on-premises com ExpressRoute | Bastion Premium private-only | Sem IP público, acesso apenas interno |
8.2 Qual SKU do Bastion escolher​
| Cenário | SKU | Motivo |
|---|---|---|
| Desenvolvimento pessoal, uma VM | Developer | Sem custo de subnet dedicada |
| Pequena equipe, acesso eventual | Basic | Custo menor, funcionalidades suficientes |
| Produção com múltiplas VMs | Standard | Escalabilidade, upload/download, tunneling |
| Ambiente regulated (HIPAA, PCI-DSS) | Premium | Session recording, private-only |
| Arquitetura hub-and-spoke | Standard | Suporte a VNet peering |
8.3 Custo vs benefÃcio​
O Bastion tem custo por hora de execução mais custo por sessão (outbound data). Para ambientes onde VMs são acessadas raramente, pode ser mais econômico criar e destruir o Bastion sob demanda via IaC:
# Criar Bastion quando necessário
az deployment group create --template-file bastion.bicep ...
# Destruir Bastion quando não mais necessário
az network bastion delete --name myBastion --resource-group myRG
A subnet AzureBastionSubnet pode permanecer mesmo sem o Bastion, sem custo adicional.
9. Boas Práticas​
- Remova IPs públicos das VMs ao implantar Bastion. O objetivo do Bastion é eliminar exposição direta das VMs.
- Feche portas SSH (22) e RDP (3389) nos NSGs das subnets de VMs. Com Bastion, o único tráfego SSH/RDP vem de dentro da VNet.
- Use SKU Standard em produção para suporte a VNet peering e tunneling.
- Centralize o Bastion no hub em arquiteturas hub-and-spoke para evitar custo com múltiplos Bastions.
- Exija MFA via Azure AD Conditional Access antes de acessar o portal e iniciar sessões Bastion.
- Habilite diagnósticos de auditoria em todos os Bastions de produção e envie logs para Log Analytics.
- Use Azure Key Vault para armazenar chaves SSH usadas pelo Bastion.
- Considere destruction on-demand para Bastions em ambientes de desenvolvimento/teste onde acesso é eventual.
- Dimensione scale units adequadamente: cada scale unit suporta ~20 sessões RDP simultâneas.
- Não instale softwares adicionais na AzureBastionSubnet nem coloque outros recursos nela.
10. Erros Comuns​
| Erro | Por que acontece | Como evitar |
|---|---|---|
Subnet com nome diferente de AzureBastionSubnet | Qualquer outro nome falha | O nome é obrigatório e case-sensitive |
Subnet menor que /26 | Bastion não inicia se não houver IPs suficientes | Criar subnet com pelo menos /26 |
| NSG na subnet bloqueando tráfego de gerenciamento | Regras de GatewayManager e AzureLoadBalancer ausentes | Incluir todas as regras obrigatórias de NSG |
| IP público Standard ausente | Bastion requer IP público Standard, não Basic | Criar IP público com SKU Standard explicitamente |
| Usuário sem permissão Reader na NIC | Conexão Bastion falha mesmo com permissão na VM | Conceder Reader em VM, NIC e Bastion |
| Acesso a VMs em VNet pareada falha | SKU Basic não suporta peering | Usar SKU Standard para acesso cross-VNet |
| Tunneling não funciona | --enable-tunneling não habilitado | Criar/atualizar Bastion com tunneling habilitado |
| Bastion lento com muitas sessões | Scale units insuficiente | Aumentar scale units (Standard SKU) |
| UDR na AzureBastionSubnet | Roteamento personalizado quebra comunicação do Bastion | Nunca adicionar UDR à AzureBastionSubnet |
11. Operação e Manutenção​
11.1 Monitorando sessões ativas​
# Ver sessões ativas do Bastion
az network bastion list-sessions \
--name myBastion \
--resource-group myRG \
--output table
11.2 Desconectando sessões ativas​
# Desconectar uma sessão especÃfica
az network bastion delete-session \
--name myBastion \
--resource-group myRG \
--session-ids <session-id>
Útil quando uma sessão fica presa ou quando um usuário precisa ser desconectado imediatamente por razões de segurança.
11.3 Atualizando o SKU do Bastion​
# Atualizar de Basic para Standard
az network bastion update \
--name myBastion \
--resource-group myRG \
--sku Standard \
--enable-tunneling true
A atualização de SKU é possÃvel de Basic para Standard ou Standard para Premium. Não é possÃvel fazer downgrade (de Standard para Basic).
11.4 Limites importantes​
| Recurso | Limite |
|---|---|
| Sessões simultâneas (Basic) | 25 |
| Sessões simultâneas por scale unit (Standard) | ~20 por unit |
| Máximo de scale units (Standard) | 50 |
| Bastions por VNet | 1 |
| VNets acessÃveis via peering (Standard) | Sem limite documentado |
| Regiões suportadas | A maioria das regiões Azure |
12. Integração e Automação​
12.1 Bastion com Just-in-Time (JIT) VM Access​
O Microsoft Defender for Cloud oferece JIT VM Access: portas SSH/RDP são abertas apenas quando necessário, por um tempo limitado, após aprovação. Combinado com Bastion:
- Administrador solicita JIT access
- JIT abre temporariamente a porta 22/3389 apenas para o IP do Bastion
- Administrador conecta via Bastion
- Após o tempo limite, a porta fecha automaticamente
Esta combinação é o padrão de segurança mais elevado para acesso administrativo.
# Habilitar JIT para uma VM
az security jit-policy create \
--resource-group myRG \
--vm-ids <vm-resource-id> \
--name "jit-policy-vm01" \
--ports "[{\"number\": 22, \"protocol\": \"TCP\", \"allowedSourceAddressPrefix\": \"VirtualNetwork\", \"maxRequestAccessDuration\": \"PT3H\"}]"
12.2 Terraform para Bastion​
resource "azurerm_subnet" "bastion" {
name = "AzureBastionSubnet"
resource_group_name = var.resource_group
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.0.10.0/26"]
}
resource "azurerm_public_ip" "bastion" {
name = "BastionPublicIP"
location = var.location
resource_group_name = var.resource_group
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_bastion_host" "main" {
name = "myBastion"
location = var.location
resource_group_name = var.resource_group
sku = "Standard"
tunneling_enabled = true
ip_connect_enabled = true
ip_configuration {
name = "IpConf"
subnet_id = azurerm_subnet.bastion.id
public_ip_address_id = azurerm_public_ip.bastion.id
}
}
12.3 Azure Policy para garantir uso do Bastion​
# Policy: VMs não devem ter IPs públicos (força uso do Bastion)
az policy assignment create \
--name "deny-public-ip-on-vms" \
--policy "83a86a26-fd1f-447c-b59d-daf3f72c3ae1" \
--scope "/subscriptions/<sub-id>/resourceGroups/production-rg"
Esta policy nega a criação de NICs com IPs públicos, forçando o uso do Bastion ou VPN para acesso administrativo.
13. Resumo Final​
Conceitos essenciais:
- Azure Bastion é um serviço PaaS gerenciado que fornece conectividade RDP/SSH segura a VMs via navegador web, sem necessidade de IPs públicos nas VMs e sem abrir portas SSH/RDP na internet.
- O Bastion é implantado em uma subnet obrigatoriamente chamada
AzureBastionSubnetcom tamanho mÃnimo de/26. - A comunicação do usuário com o Bastion é via HTTPS (443); o Bastion conecta à s VMs via SSH/RDP internamente na rede privada.
Diferenças crÃticas entre SKUs:
- Developer: Sem subnet dedicada, uso pessoal, não para produção.
- Basic: Subnet obrigatória
/26, 25 sessões, sem suporte a peering, upload/download ou tunneling. - Standard: Suporte a VNet peering, tunneling, upload/download, IP-based connection, shareable links, escalável.
- Premium: Tudo do Standard mais session recording e private-only (sem IP público).
O que precisa ser lembrado:
- A subnet DEVE se chamar exatamente
AzureBastionSubnet(case-sensitive). - Tamanho mÃnimo da subnet:
/26(exceto Developer SKU). - O IP público do Bastion DEVE ser Standard SKU, não Basic.
- Nunca adicione UDR Ã
AzureBastionSubnet. - O usuário precisa de Reader na VM, na NIC e no recurso do Bastion para iniciar sessões.
- SKU Standard é necessário para acessar VMs em VNets pareadas.
- Não é possÃvel fazer downgrade de SKU (Standard → Basic); apenas upgrade é permitido.
- Feche portas 22/3389 nos NSGs das VMs de produção e remova IPs públicos quando usar Bastion.