Networking
Azure Bastion : diagnostiquer un échec SSH ou RDP avant d'ouvrir les NSG
Un runbook de production pour séparer session Bastion, NSG, routage, port cible, identité et santé de la VM avant d'exposer SSH ou RDP.
Une session Azure Bastion reste sur Connecting, se ferme après authentification ou échoue uniquement vers certaines VM. La machine est pourtant démarrée et aucune alerte applicative n’est visible. Sous pression, l’action la plus rapide semble être d’autoriser 22 ou 3389 depuis Internet, d’ajouter une règle NSG très large ou de redéployer Bastion.
Ce contournement transforme un incident d’administration en nouvelle surface d’exposition sans prouver la cause. Le cas d’usage de ce runbook est un Bastion partagé qui donne accès à des VM Windows et Linux par adresse privée, dans un réseau hub-and-spoke ou une VNet unique. L’objectif est de localiser la rupture entre le client, le service Bastion, AzureBastionSubnet, le chemin vers la VM, le système invité et l’identité, puis de corriger le niveau fautif avec un rollback explicite.
Figer la tentative qui échoue
Conservez une tentative reproductible avant tout changement. Notez l’heure UTC, l’utilisateur, le mode de connexion, la VM, son IP privée, le port demandé et le message exact. Une session web qui ne s’ouvre pas du tout, une connexion TCP qui expire et une authentification refusée sont trois incidents différents.
Incident: inc-20260815-021
Bastion: bas-hub-prod-weu
Target VM: vm-orders-07
Target private IP: 10.42.6.17
Protocol / port: SSH / 22
Client mode: Azure portal
Attempt time: 2026-08-15T06:35:00Z
Observed result: Connecting puis echec generique
Conserver
Correlation et heure UTC de chaque essai
Bastion SKU et provisioning state
AzureBastionSubnet, NSG et route table associes
NIC, subnet, NSG effectifs et routes de la VM
Etat du service SSH/RDP et du firewall invite
Interdits temporaires
Ne pas publier 22 ou 3389 sur Internet
Ne pas ajouter Allow Any Any
Ne pas supprimer NSG ou UDR pour tester
Ne pas redemarrer la VM avant collecte Rejouez une seule fois avec les mêmes paramètres. Si plusieurs utilisateurs ou VM sont touchés, construisez une petite matrice. « Toutes les VM d’un spoke » oriente vers peering ou routage. « Une seule VM » oriente vers son NIC, son NSG ou l’OS. « Tous les utilisateurs depuis un réseau d’entreprise » peut indiquer un blocage du chemin HTTPS client vers Bastion.
Découper le chemin en cinq contrôles
Azure Bastion ne supprime pas le réseau d’administration ; il le rend privé et médié. Une session traverse cinq plans qu’il faut tester séparément :
- le client atteint l’expérience Bastion en HTTPS ;
- le Bastion est provisionné et son subnet conserve les flux nécessaires au service ;
AzureBastionSubnetatteint l’IP privée de la VM sur le port SSH, RDP ou personnalisé ;- la VM écoute et son firewall invité accepte ce flux ;
- l’utilisateur et la méthode d’authentification sont valides.
Un écran Connecting ne permet pas de choisir entre ces plans. La discipline du runbook consiste à obtenir une preuve par plan avant de modifier une règle.
Vérifier Bastion et son subnet sans mutation
Commencez par inventorier la ressource et l’association réseau. Un état de provisioning différent de Succeeded, un subnet renommé, une IP publique dissociée ou un changement récent de SKU se traite avant la VM cible.
BASTION_RG="rg-connectivity-prod"
BASTION_NAME="bas-hub-prod-weu"
VNET_RG="rg-connectivity-prod"
VNET_NAME="vnet-hub-prod-weu"
az network bastion show --resource-group "$BASTION_RG" --name "$BASTION_NAME" --query '{state:provisioningState,sku:sku.name,dnsName:dnsName,scaleUnits:scaleUnits,ipConfigurations:ipConfigurations[].{subnet:subnet.id,publicIp:publicIPAddress.id}}' --output json
az network vnet subnet show --resource-group "$VNET_RG" --vnet-name "$VNET_NAME" --name AzureBastionSubnet --query '{prefix:addressPrefix,nsg:networkSecurityGroup.id,routeTable:routeTable.id}' --output json Si un NSG protège AzureBastionSubnet, vérifiez l’ensemble de règles attendu, pas seulement la sortie vers 22 ou 3389. Bastion dépend aussi de flux HTTPS de contrôle et de flux internes au service. Une règle de refus plus prioritaire peut masquer un Allow apparemment correct.
NSG_RG="rg-connectivity-prod"
NSG_NAME="nsg-azure-bastion-prod"
az network nsg rule list --resource-group "$NSG_RG" --nsg-name "$NSG_NAME" --include-default --query "sort_by([].{priority:priority,name:name,direction:direction,access:access,source:sourceAddressPrefix,destination:destinationAddressPrefix,port:destinationPortRange,ports:destinationPortRanges}, &priority)" --output table Comparez cet inventaire au contrat Bastion réellement déployé. Pour un Bastion classique protégé par NSG, les flux usuels couvrent notamment HTTPS 443, la communication interne 8080/5701, la sortie vers les VM sur 22/3389 et les dépendances Azure. Ne recopiez pas une règle historique sans vérifier le SKU, les fonctions activées et la documentation du service au moment du changement.
Prouver le flux Bastion vers la VM
Récupérez la NIC principale, son subnet et ses protections. Une règle sur le subnet peut autoriser le trafic tandis qu’une règle sur la NIC le refuse, ou l’inverse. Les règles effectives donnent une meilleure preuve qu’une lecture isolée d’un seul NSG.
VM_RG="rg-workload-prod"
VM_NAME="vm-orders-07"
NIC_ID=$(az vm show --resource-group "$VM_RG" --name "$VM_NAME" --query 'networkProfile.networkInterfaces[0].id' --output tsv)
az network nic show --ids "$NIC_ID" --query '{privateIps:ipConfigurations[].privateIPAddress,subnets:ipConfigurations[].subnet.id,nsg:networkSecurityGroup.id}' --output json
az network nic list-effective-nsg --ids "$NIC_ID" --output json
az network nic show-effective-route-table --ids "$NIC_ID" --output table Le flux cible doit autoriser le CIDR de AzureBastionSubnet vers le port d’écoute réel. Évitez VirtualNetwork comme réponse automatique dans un réseau complexe : ce service tag peut couvrir plus de préfixes que le strict subnet d’administration. Une règle ciblée sur le CIDR Bastion produit un contrat plus lisible.
Contrôlez ensuite le chemin lui-même : peering dans les deux sens, option de trafic transféré si l’architecture l’exige, UDR sur les subnets concernés et retour vers le préfixe Bastion. Une route par défaut injectée par une appliance ou Azure Route Server peut détourner un flux qui fonctionnait auparavant. Si le symptôme est apparu après un changement de routage, comparez la configuration avant/après au lieu d’ajouter une exception NSG.
Séparer réseau, service invité et authentification
Quand les règles et routes sont conformes, vérifiez l’écoute dans la VM. Utilisez Run Command ou la console série uniquement comme canal de récupération borné, avec des commandes de lecture en premier. Une connexion SSH testée depuis une autre VM ne reproduit pas forcément la source Bastion, mais elle confirme si le service écoute.
sudo systemctl status sshd --no-pager || sudo systemctl status ssh --no-pager
sudo ss -lntp | awk '$4 ~ /:22$/'
sudo journalctl -u sshd --since "2026-08-15 06:20:00 UTC" --no-pager
sudo nft list ruleset
sudo iptables -S
df -h / /var
# Pour un port personnalise, remplacer 22 dans l'ecoute et les regles. Pour Windows, contrôlez l’état de TermService, l’écoute sur le port configuré, fDenyTSConnections, le profil du firewall et les événements d’authentification. Un disque plein, un service arrêté ou une politique NLA peut produire un symptôme proche d’un timeout réseau.
Si TCP aboutit mais que l’authentification échoue, cessez de modifier le réseau. Vérifiez le type d’identité présenté, les droits locaux, l’appartenance à Remote Desktop Users pour RDP, la clé SSH attendue, l’état du compte et la méthode Entra si elle est utilisée. Un 401, un refus NLA ou une clé rejetée n’est pas corrigé par une règle NSG plus large.
Corriger au niveau fautif
La correction doit correspondre à la preuve collectée :
- règle Bastion manquante : restaurer seulement la règle exigée et sa priorité ;
- NSG cible trop restrictif : autoriser le CIDR Bastion vers le port réel, sans source Internet ;
- UDR ou peering incohérent : restaurer le chemin symétrique validé ;
- firewall invité : autoriser la source Bastion sur le port d’écoute ;
- service arrêté : corriger sa cause puis le démarrer ;
- authentification : réparer le compte ou la méthode, sans changement réseau.
Appliquez une seule famille de changement à la fois. Associez chaque mutation à l’identifiant d’incident et conservez la règle précédente, sa priorité et son propriétaire. Une ouverture temporaire sans propriétaire ni échéance devient vite permanente.
Valider puis décider le rollback
Rejouez exactement la tentative figée, depuis le même mode client et vers la même IP privée. La validation minimale prouve l’établissement de session, l’identité obtenue, l’absence d’exposition publique de la VM et la stabilité d’une seconde connexion. Vérifiez aussi une VM témoin pour détecter une régression partagée sur Bastion.
Valider la correction
Bastion reste en provisioningState Succeeded
Session ouverte vers la VM cible via IP privee
Source autorisee limitee a AzureBastionSubnet
Aucun inbound Internet sur 22 ou 3389
Service invite et authentification conformes
VM temoin toujours joignable
Rollback
Retirer la nouvelle regle ou restaurer sa priorite precedente
Restaurer route table, peering ou firewall invite anterieur
Rejouer le test cible et le test temoin
Conserver l'acces public ferme
Escalader sans elargir
Tous les controles passent mais Bastion reste en echec
Joindre heures UTC, correlation, inventaire, routes et NSG effectifs
Garder la configuration securisee pendant l'analyse Conclusion
Un échec Azure Bastion n’autorise pas à rouvrir SSH ou RDP sur Internet. Il impose de localiser la rupture entre client, service Bastion, subnet, NSG, routage, port invité et identité. Chaque plan dispose de preuves distinctes ; les mélanger produit des règles trop larges et des diagnostics fragiles.
La sortie d’incident est une décision vérifiable : un flux privé rétabli, une règle limitée à AzureBastionSubnet, une session validée avec l’identité attendue et un rollback documenté. Si la cause reste inconnue, le bon état de sécurité est de conserver les ports publics fermés et d’escalader avec les preuves, pas de transformer le contournement en architecture.