How to harden security of Azure Bastion

Bastion Is Your Secure Jump Host — Harden It Properly

Azure Bastion provides secure RDP and SSH access to virtual machines without exposing them to the public internet. However, Bastion itself needs hardening — its subnet requires specific NSG rules, session recordings should capture administrative actions, and access should be restricted to authorized users only. This guide covers every step to lock down your Bastion deployment.

Threat Landscape and Attack Surface

Hardening Azure Bastion requires understanding the threat landscape specific to this service. Azure services are attractive targets because they often store, process, or transmit sensitive data and provide control-plane access to cloud infrastructure. Attackers probe for misconfigured services using automated scanners that continuously sweep Azure IP ranges for exposed endpoints, weak authentication, and default configurations.

The attack surface for Azure Bastion includes several dimensions. The network perimeter determines who can reach the service endpoints. The identity and access layer controls what authenticated principals can do. The data plane governs how data is protected at rest and in transit. The management plane controls who can modify the service configuration itself. A comprehensive hardening strategy addresses all four dimensions because a weakness in any single layer can be exploited to bypass the controls in other layers.

Microsoft’s shared responsibility model means that while Azure secures the physical infrastructure, network fabric, and hypervisor, you are responsible for configuring the service securely. Default configurations prioritize ease of setup over security. Every Azure service ships with settings that must be tightened for production use, and this guide walks through the critical configurations that should be changed from their defaults.

The MITRE ATT&CK framework for cloud environments provides a structured taxonomy of attack techniques that adversaries use against Azure services. Common techniques relevant to Azure Bastion include initial access through exposed credentials or misconfigured endpoints, lateral movement through overly permissive RBAC assignments, and data exfiltration through unmonitored data plane operations. Each hardening control in this guide maps to one or more of these attack techniques.

Compliance and Regulatory Context

Security hardening is not just a technical exercise. It is a compliance requirement for virtually every regulatory framework that applies to cloud workloads. SOC 2 Type II requires evidence of security controls for cloud services. PCI DSS mandates network segmentation and encryption for payment data. HIPAA requires access controls and audit logging for health information. ISO 27001 demands a systematic approach to information security management. FedRAMP requires specific configurations for government workloads.

Azure Policy and Microsoft Defender for Cloud provide built-in compliance assessments against these frameworks. After applying the hardening configurations in this guide, run a compliance scan to verify your security posture against your applicable regulatory standards. Address any remaining findings to achieve and maintain compliance. Export compliance reports on a scheduled basis to satisfy audit requirements and demonstrate continuous adherence.

The Microsoft cloud security benchmark provides a comprehensive set of security controls mapped to common regulatory frameworks. Use this benchmark as a checklist to verify that your hardening effort covers all required areas. Each control includes Azure-specific implementation guidance and links to the relevant Azure service documentation.

Step 1: Choose the Right SKU

Feature Basic Standard Premium
RDP/SSH via Azure portal Yes Yes Yes
Native client support (az cli) No Yes Yes
IP-based connection No Yes Yes
Shareable links No Yes Yes
Session recording No No Yes
Private-only deployment No Yes Yes
# Deploy Bastion with Standard SKU
az network bastion create \
  --name bastion-prod --resource-group rg-network \
  --vnet-name vnet-prod --sku Standard \
  --location eastus --enable-tunneling true

Step 2: Configure Required NSG Rules

Azure Bastion requires specific NSG rules on the AzureBastionSubnet. Missing rules will cause the deployment to fail or sessions to drop.

# Create NSG
az network nsg create --name nsg-bastion --resource-group rg-network

# INBOUND: Allow HTTPS from Internet (portal access)
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowHttpsInbound --priority 100 --direction Inbound \
  --source-address-prefixes Internet --destination-port-ranges 443 \
  --protocol Tcp --access Allow

# INBOUND: Allow Gateway Manager (health probes)
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowGatewayManager --priority 110 --direction Inbound \
  --source-address-prefixes GatewayManager --destination-port-ranges 443 \
  --protocol Tcp --access Allow

# INBOUND: Allow Bastion host communication
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowBastionComm --priority 120 --direction Inbound \
  --source-address-prefixes VirtualNetwork --destination-address-prefixes VirtualNetwork \
  --destination-port-ranges 8080 5701 --protocol '*' --access Allow

# INBOUND: Allow Azure Load Balancer
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowAzureLB --priority 130 --direction Inbound \
  --source-address-prefixes AzureLoadBalancer --destination-port-ranges 443 \
  --protocol Tcp --access Allow

# INBOUND: Deny all other
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name DenyAllInbound --priority 4096 --direction Inbound \
  --source-address-prefixes '*' --destination-port-ranges '*' \
  --protocol '*' --access Deny

# OUTBOUND: Allow SSH/RDP to VMs
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowSshRdp --priority 100 --direction Outbound \
  --destination-address-prefixes VirtualNetwork --destination-port-ranges 22 3389 \
  --protocol '*' --access Allow

# OUTBOUND: Allow Azure Cloud (telemetry, logs)
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowAzureCloud --priority 110 --direction Outbound \
  --destination-address-prefixes AzureCloud --destination-port-ranges 443 \
  --protocol Tcp --access Allow

# OUTBOUND: Allow Bastion host communication
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowBastionComm --priority 120 --direction Outbound \
  --source-address-prefixes VirtualNetwork --destination-address-prefixes VirtualNetwork \
  --destination-port-ranges 8080 5701 --protocol '*' --access Allow

# OUTBOUND: Allow Internet (for session info)
az network nsg rule create --nsg-name nsg-bastion --resource-group rg-network \
  --name AllowGetSessionInfo --priority 130 --direction Outbound \
  --destination-address-prefixes Internet --destination-port-ranges 80 \
  --protocol '*' --access Allow

# Associate NSG
az network vnet subnet update --resource-group rg-network \
  --vnet-name vnet-prod --name AzureBastionSubnet --network-security-group nsg-bastion

Step 3: Deploy Private-Only Bastion

# Bastion without public IP (access via ExpressRoute/VPN only)
az network bastion create \
  --name bastion-private --resource-group rg-network \
  --vnet-name vnet-prod --sku Standard \
  --enable-ip-connect true --private-only true

Private-only Bastion removes the public IP entirely. Users must connect through ExpressRoute, VPN, or peered networks. This is the most secure deployment model for enterprises.

Step 4: Enable Session Recording (Premium SKU)

# Upgrade to Premium and enable session recording
az network bastion update --name bastion-prod --resource-group rg-network \
  --sku Premium --enable-session-recording true

Session recordings are stored in your storage account and capture full video of RDP sessions. This provides an audit trail for all administrative actions performed on VMs.

Step 5: Restrict Access with Azure RBAC

# Grant Bastion access to specific users (Reader role on Bastion + VM)
az role assignment create \
  --assignee admin@contoso.com \
  --role "Reader" \
  --scope "/subscriptions/{sub}/resourceGroups/rg-network/providers/Microsoft.Network/bastionHosts/bastion-prod"

# Users also need VM login roles
az role assignment create \
  --assignee admin@contoso.com \
  --role "Virtual Machine Administrator Login" \
  --scope "/subscriptions/{sub}/resourceGroups/rg-prod"

Identity and Access Management Deep Dive

Identity is the primary security perimeter in cloud environments. For Azure Bastion, implement a robust identity and access management strategy that follows the principle of least privilege.

Managed Identities: Use system-assigned or user-assigned managed identities for service-to-service authentication. Managed identities eliminate the need for stored credentials (connection strings, API keys, or service principal secrets) that can be leaked, stolen, or forgotten in configuration files. Azure automatically rotates the underlying certificates, removing the operational burden of credential rotation.

Custom RBAC Roles: When built-in roles grant more permissions than required, create custom roles that include only the specific actions needed. For example, if a monitoring service only needs to read metrics and logs from Azure Bastion, create a custom role with only the Microsoft.Insights/metrics/read and Microsoft.Insights/logs/read actions rather than assigning the broader Reader or Contributor roles.

Conditional Access: For human administrators accessing Azure Bastion through the portal or CLI, enforce Conditional Access policies that require multi-factor authentication, compliant devices, and approved locations. Set session lifetime limits so that administrative sessions expire after a reasonable period, forcing re-authentication.

Just-In-Time Access: Use Azure AD Privileged Identity Management (PIM) to provide time-limited, approval-required elevation for administrative actions. Instead of permanently assigning Contributor or Owner roles, require administrators to activate their role assignment for a specific duration with a business justification. This reduces the window of exposure if an administrator’s account is compromised.

Service Principal Hygiene: If managed identities cannot be used (for example, for external services or CI/CD pipelines), use certificate-based authentication for service principals rather than client secrets. Certificates are harder to accidentally expose than text secrets, and Azure Key Vault can automate their rotation. Set short expiration periods for any client secrets and monitor for secrets that are approaching expiration.

Step 6: Manage Shareable Links Carefully

Shareable links allow users without Azure portal access to connect to VMs. This is powerful but risky:

  • Only enable for specific VMs that need it
  • Set expiration times on links
  • Monitor link usage via audit logs
  • Disable the feature if not explicitly needed

Step 7: Configure Native Client Tunneling

# Connect using native SSH client through Bastion tunnel
az network bastion ssh \
  --name bastion-prod --resource-group rg-network \
  --target-resource-id "/subscriptions/{sub}/resourceGroups/rg-prod/providers/Microsoft.Compute/virtualMachines/vm-linux" \
  --auth-type ssh-key --username azureuser --ssh-key ~/.ssh/id_rsa

Native client tunneling uses the Bastion tunnel as a secure proxy. This supports SSH key authentication, port forwarding, and file transfers without exposing VMs to the internet.

Step 8: Enable Diagnostic Logging

az monitor diagnostic-settings create \
  --name bastion-diag \
  --resource "/subscriptions/{sub}/resourceGroups/rg-network/providers/Microsoft.Network/bastionHosts/bastion-prod" \
  --workspace law-prod-id \
  --logs '[{"category":"BastionAuditLogs","enabled":true}]'

Bastion audit logs capture: who connected, to which VM, when, session duration, and the source IP. Forward these to Microsoft Sentinel for SIEM integration.

Step 9: Size the Subnet Correctly

The AzureBastionSubnet must be at least /26 (64 addresses). For Standard/Premium with scale units, use /24 (256 addresses). An undersized subnet prevents scaling.

# Create properly sized subnet
az network vnet subnet create \
  --resource-group rg-network --vnet-name vnet-prod \
  --name AzureBastionSubnet --address-prefix 10.0.254.0/24

Step 10: Monitor and Alert

  • Alert on failed connection attempts — potential unauthorized access
  • Alert on connections from unusual locations using Conditional Access
  • Monitor concurrent sessions — unexpected spikes may indicate compromised credentials
  • Review session recordings for compliance audits
  • Apply Conditional Access policies on the Azure portal to require MFA before Bastion access

Defense in Depth Strategy

No single security control is sufficient. Apply a defense-in-depth strategy that layers multiple controls so that the failure of any single layer does not expose the service to attack. For Azure Bastion, this means combining network isolation, identity verification, encryption, monitoring, and incident response capabilities.

At the network layer, restrict access to only the networks that legitimately need to reach the service. Use Private Endpoints to eliminate public internet exposure entirely. Where public access is required, use IP allowlists, service tags, and Web Application Firewall (WAF) rules to limit the attack surface. Configure network security groups (NSGs) with deny-by-default rules and explicit allow rules only for required traffic flows.

At the identity layer, enforce least-privilege access using Azure RBAC with custom roles when built-in roles are too broad. Use Managed Identities for service-to-service authentication to eliminate stored credentials. Enable Conditional Access policies to require multi-factor authentication and compliant devices for administrative access.

At the data layer, enable encryption at rest using customer-managed keys (CMK) in Azure Key Vault when the default Microsoft-managed keys do not meet your compliance requirements. Enforce TLS 1.2 or higher for data in transit. Enable purge protection on any service that supports soft delete to prevent malicious or accidental data destruction.

At the monitoring layer, enable diagnostic logging and route logs to a centralized Log Analytics workspace. Configure Microsoft Sentinel analytics rules to detect suspicious access patterns, privilege escalation attempts, and data exfiltration indicators. Set up automated response playbooks that can isolate compromised resources without human intervention during off-hours.

Continuous Security Assessment

Security hardening is not a one-time activity. Azure services evolve continuously, introducing new features, deprecating old configurations, and changing default behaviors. Schedule quarterly security reviews to reassess your hardening posture against the latest Microsoft security baselines.

Use Microsoft Defender for Cloud’s Secure Score as a quantitative measure of your security posture. Track your score over time and investigate any score decreases, which may indicate configuration drift or new recommendations from updated security baselines. Set a target Secure Score and hold teams accountable for maintaining it.

Subscribe to Azure update announcements and security advisories to stay informed about changes that affect your security controls. When Microsoft introduces a new security feature or changes a default behavior, assess the impact on your environment and update your hardening configuration accordingly. Automate this assessment where possible using Azure Policy to continuously evaluate your resources against your security standards.

Conduct periodic penetration testing against your Azure environment. Azure’s penetration testing rules of engagement allow testing without prior notification to Microsoft for most services. Engage a qualified security testing firm to assess your Azure Bastion deployment using the same techniques that real attackers would employ. The findings from these tests often reveal gaps that automated compliance scans miss.

Hardening Checklist

  1. Standard or Premium SKU (not Basic for production)
  2. Complete NSG rules on AzureBastionSubnet
  3. Private-only deployment via ExpressRoute/VPN
  4. Session recording enabled (Premium)
  5. RBAC with VM login roles (not VM Contributor)
  6. Shareable links disabled or tightly controlled
  7. Native client tunneling with SSH keys
  8. Diagnostic logging to Log Analytics/Sentinel
  9. Subnet sized to /24 for scaling
  10. Conditional Access with MFA for portal access

For more details, refer to the official documentation: What is Azure Bastion?, Azure Bastion FAQ, Troubleshoot Azure Bastion.

Leave a Reply