Pular para o conteúdo principal

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​

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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:

  1. Recebe conexões HTTPS (porta 443) do administrador via navegador
  2. Estabelece a sessão RDP ou SSH com a VM alvo dentro da rede privada
  3. Converte o protocolo: RDP/SSH é transmitido sobre WebSocket (HTTPS), transparente para o usuário
  4. 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 /27 ou 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 /26 no 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:

SKUSessões SimultâneasFuncionalidadesUso Recomendado
DeveloperLimitado (compartilhado)SSH e RDP básicoDesenvolvimento/teste pessoal
Basic25SSH, RDP, copy/pasteAmbientes pequenos
Standard50+ (escalável)Basic + upload/download de arquivos, kerberos auth, IP-based connection, shareable linksProdução
PremiumMais altoStandard + session recording, private-only BastionCompliance 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.

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

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​

100%
Scroll para zoom · Arraste para mover · 📱 Pinch para zoom no celular

5. Funcionamento na Prática​

5.1 Pré-requisitos para implantar o Bastion​

Antes de criar o Bastion, você precisa:

  1. Uma VNet existente onde o Bastion será implantado
  2. A subnet AzureBastionSubnet criada com no mínimo /26
  3. Um IP público (Standard SKU) para o Bastion (criado automaticamente pelo portal ou manualmente)
  4. 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:

PrioridadeSourcePorta DestProtocoloAçãoPropósito
120Internet443TCPAllowAcesso HTTPS do administrador
130GatewayManager443TCPAllowGerenciamento do plano de controle do Azure
140AzureLoadBalancer443TCPAllowProbe de saúde do Load Balancer
150VirtualNetwork8080, 5701AnyAllowComunicação entre instâncias do Bastion

Regras Outbound obrigatórias:

PrioridadeDestinationPorta DestProtocoloAçãoPropósito
100VirtualNetwork22, 3389AnyAllowConexão SSH/RDP às VMs
110AzureCloud443TCPAllowComunicação com serviços Azure (diagnóstico)
120Internet80TCPAllowVerificações de certificado CRL
130VirtualNetwork8080, 5701AnyAllowComunicação entre instâncias

5.3 Conectando via Bastion no Portal​

  1. Navegue até a VM no portal
  2. Clique em Connect > Bastion
  3. Se o Bastion não existir ainda, o portal oferece criação rápida com configurações padrão
  4. Insira as credenciais (usuário/senha ou SSH key)
  5. Escolha o tipo de autenticação (password ou private key)
  6. 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) ou SSH 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:

RolePermissãoEscopo
ReaderVisualizar recursosVM, NIC, Bastion (todos os três)
Bastion ReaderIniciar sessão BastionRecurso 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çãoMelhor escolhaMotivo
VM com IP público e SSH abertoMigrar para BastionSSH aberto na internet é risco crítico
Jump box gerenciada manualmenteBastionElimina overhead de gerenciar VM intermediária
Muitas VMs em múltiplas VNetsBastion Standard em hub + peeringUm Bastion cobre todas as VNets spoke
Acesso de desenvolvedor com cliente SSH localBastion Standard com tunnelingUsa cliente SSH nativo através do túnel
Ambiente com requisito de auditoria de sessãoBastion PremiumSession recording para compliance
Equipe grande sem VPN corporativaBastion Standard + Conditional Access + MFAAcesso via browser com autenticação forte
Rede on-premises com ExpressRouteBastion Premium private-onlySem IP público, acesso apenas interno

8.2 Qual SKU do Bastion escolher​

CenárioSKUMotivo
Desenvolvimento pessoal, uma VMDeveloperSem custo de subnet dedicada
Pequena equipe, acesso eventualBasicCusto menor, funcionalidades suficientes
Produção com múltiplas VMsStandardEscalabilidade, upload/download, tunneling
Ambiente regulated (HIPAA, PCI-DSS)PremiumSession recording, private-only
Arquitetura hub-and-spokeStandardSuporte 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​

ErroPor que aconteceComo evitar
Subnet com nome diferente de AzureBastionSubnetQualquer outro nome falhaO nome é obrigatório e case-sensitive
Subnet menor que /26Bastion não inicia se não houver IPs suficientesCriar subnet com pelo menos /26
NSG na subnet bloqueando tráfego de gerenciamentoRegras de GatewayManager e AzureLoadBalancer ausentesIncluir todas as regras obrigatórias de NSG
IP público Standard ausenteBastion requer IP público Standard, não BasicCriar IP público com SKU Standard explicitamente
Usuário sem permissão Reader na NICConexão Bastion falha mesmo com permissão na VMConceder Reader em VM, NIC e Bastion
Acesso a VMs em VNet pareada falhaSKU Basic não suporta peeringUsar SKU Standard para acesso cross-VNet
Tunneling não funciona--enable-tunneling não habilitadoCriar/atualizar Bastion com tunneling habilitado
Bastion lento com muitas sessõesScale units insuficienteAumentar scale units (Standard SKU)
UDR na AzureBastionSubnetRoteamento personalizado quebra comunicação do BastionNunca 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​

RecursoLimite
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 VNet1
VNets acessíveis via peering (Standard)Sem limite documentado
Regiões suportadasA 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:

  1. Administrador solicita JIT access
  2. JIT abre temporariamente a porta 22/3389 apenas para o IP do Bastion
  3. Administrador conecta via Bastion
  4. 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 AzureBastionSubnet com 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.