What's Actually Happening
Cannot connect to Azure Virtual Machine via SSH, RDP, or HTTP. Connection times out or is refused.
The Error You'll See
SSH timeout:
```bash $ ssh azureuser@vm-ip
ssh: connect to host vm-ip port 22: Connection timed out ```
RDP error:
Remote Desktop can't connect to the remote computerHTTP connection refused:
```bash $ curl http://vm-ip
curl: (7) Failed to connect to vm-ip port 80: Connection refused ```
Azure portal shows:
VM status: Running
But cannot connectWhy This Happens
- 1.NSG blocking - Network Security Group rules not allowing traffic
- 2.VM not running - VM deallocated or stopped
- 3.Firewall on VM - Guest OS firewall blocking
- 4.Wrong IP - Using private IP instead of public
- 5.Service not running - SSH/RDP service stopped
- 6.DNS resolution - DNS not resolving VM name
Step 1: Check VM Status
```bash # Check VM status with Azure CLI: az vm show -g MyResourceGroup -n MyVM --query "{powerState:powerState}" -o tsv
# List VMs: az vm list -o table
# Check VM power state: az vm list --query "[].{Name:name, Power:powerState, ResourceGroup:resourceGroup}" -o table
# Start VM if stopped: az vm start -g MyResourceGroup -n MyVM
# Restart VM: az vm restart -g MyResourceGroup -n MyVM
# Check VM instance view: az vm get-instance-view -g MyResourceGroup -n MyVM
# Check from portal: # Portal -> Virtual Machines -> MyVM -> Status ```
Step 2: Check Network Security Group
```bash # List NSGs: az network nsg list -o table
# Check NSG rules: az network nsg show -g MyResourceGroup -n MyNSG --query "securityRules[]" -o table
# Check effective rules for VM: az network nic list-effective-nsg -g MyResourceGroup -n MyNic -o table
# Check default rules: az network nsg show -g MyResourceGroup -n MyNSG --query "defaultSecurityRules[]" -o table
# Add SSH rule: az network nsg rule create -g MyResourceGroup --nsg-name MyNSG -n AllowSSH \ --protocol Tcp --priority 100 --source-address-prefixes '*' \ --source-port-ranges '*' --destination-address-prefixes '*' \ --destination-port-ranges 22 --access Allow
# Add HTTP rule: az network nsg rule create -g MyResourceGroup --nsg-name MyNSG -n AllowHTTP \ --protocol Tcp --priority 110 --destination-port-ranges 80 --access Allow
# Add RDP rule: az network nsg rule create -g MyResourceGroup --nsg-name MyNSG -n AllowRDP \ --protocol Tcp --priority 120 --destination-port-ranges 3389 --access Allow
# Check if NSG attached to subnet: az network vnet subnet show -g MyResourceGroup --vnet-name MyVNet -n MySubnet --query "networkSecurityGroup" ```
Step 3: Check Public IP Address
```bash # Check public IP: az vm show -g MyResourceGroup -n MyVM -d --query publicIps -o tsv
# Or: az network public-ip show -g MyResourceGroup -n MyPublicIP --query ipAddress
# List all public IPs: az network public-ip list -o table
# Check if public IP allocated: az network public-ip show -g MyResourceGroup -n MyPublicIP --query "{IP:ipAddress, Method:publicIpAllocationMethod}"
# Create public IP if missing: az network public-ip create -g MyResourceGroup -n MyPublicIP
# Associate with NIC: az network nic ip-config update -g MyResourceGroup --nic-name MyNic \ --public-ip-address MyPublicIP ```
Step 4: Test Network Connectivity
```bash # Use Azure Network Watcher:
# Test connection to VM: az network watcher test-connectivity -g MyResourceGroup \ --source-resource MySourceVM --dest-resource MyDestVM --dest-port 22
# Check IP flow: az network watcher test-ip-flow -g MyResourceGroup --vm MyVM \ --direction Inbound --protocol TCP --local 0.0.0.0:22 --remote 10.0.0.1:50000
# Use ping from another Azure VM: ping vm-private-ip
# Test from local machine: nc -zv vm-public-ip 22 telnet vm-public-ip 22
# Check routing: az network route-table list -g MyResourceGroup -o table
# Check effective routes: az network nic show-effective-route-table -g MyResourceGroup -n MyNic -o table ```
Step 5: Check Guest OS Firewall
```bash # Connect via Azure Serial Console: # Portal -> VM -> Serial Console
# For Linux, check iptables: sudo iptables -L -n
# Check firewalld: sudo firewall-cmd --list-all
# Allow SSH: sudo firewall-cmd --add-service=ssh --permanent sudo firewall-cmd --reload
# Or iptables: sudo iptables -I INPUT -p tcp --dport 22 -j ACCEPT sudo iptables-save
# Check if service running: sudo systemctl status sshd sudo systemctl start sshd
# For Windows, check firewall: netsh advfirewall firewall show rule name=all | findstr 3389
# Enable RDP: netsh advfirewall firewall set rule group="remote desktop" new enable=Yes ```
Step 6: Check SSH Configuration
```bash # Via Serial Console:
# Check SSH service: sudo systemctl status sshd
# Check SSH config: sudo cat /etc/ssh/sshd_config | grep -E "Port|PermitRootLogin|PasswordAuthentication"
# Fix SSH config: # Allow root login: sudo sed -i 's/PermitRootLogin no/PermitRootLogin yes/' /etc/ssh/sshd_config
# Allow password auth: sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
# Restart SSH: sudo systemctl restart sshd
# Check listening: sudo ss -tlnp | grep 22
# Check auth logs: sudo tail -f /var/log/auth.log ```
Step 7: Reset SSH Access
```bash # Reset SSH configuration via Azure: az vm user reset-ssh -g MyResourceGroup -n MyVM
# Or use VM Access extension: az vm extension set -g MyResourceGroup --vm-name MyVM \ --name VMAccessForLinux --publisher Microsoft.OSTCExtensions \ --version 1.5 --settings '{"reset_ssh": true}'
# Reset user password: az vm user update -g MyResourceGroup -n MyVM -u azureuser -p NewPassword123!
# Add new user: az vm user create -g MyResourceGroup -n MyVM -u newuser -p Password123!
# Delete user: az vm user delete -g MyResourceGroup -n MyVM -u olduser
# Regenerate SSH key: az vm user update -g MyResourceGroup -n MyVM -u azureuser --ssh-key-value "$(cat ~/.ssh/id_rsa.pub)" ```
Step 8: Check DNS Resolution
```bash # Check DNS name: az network public-ip show -g MyResourceGroup -n MyPublicIP --query dnsSettings.fqdn
# Test DNS resolution: dig myvm.eastus.cloudapp.azure.com
# Or: nslookup myvm.eastus.cloudapp.azure.com
# Set DNS name: az network public-ip update -g MyResourceGroup -n MyPublicIP --dns-name myvm
# Test with DNS name: ssh azureuser@myvm.eastus.cloudapp.azure.com
# Check if using private IP: az vm show -g MyResourceGroup -n MyVM --query "networkProfile.networkInterfaces[0].id" | xargs -I {} az network nic show --ids {} --query "ipConfigurations[0].privateIPAddress" ```
Step 9: Use Azure Diagnostics
```bash # Run VM diagnosis: az vm diagnose -g MyResourceGroup -n MyVM
# Check boot diagnostics: az vm boot-diagnostics get-boot-log -g MyResourceGroup -n MyVM
# Enable boot diagnostics: az vm boot-diagnostics enable -g MyResourceGroup -n MyVM --storage https://mystorage.blob.core.windows.net/
# Check VM extension status: az vm extension list -g MyResourceGroup --vm-name MyVM -o table
# Check metrics in portal: # Portal -> VM -> Metrics
# Check activity log: az monitor activity-log list --resource-group MyResourceGroup --caller user@example.com -o table ```
Step 10: Azure VM Connection Verification Script
```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-azure-vm.sh #!/bin/bash
RG=${1:-"MyResourceGroup"} VM=${2:-"MyVM"}
echo "=== VM Status ===" az vm show -g $RG -n $VM -d --query "{Name:name, Power:powerState, PublicIP:publicIps, PrivateIP:privateIps}" -o table
echo "" echo "=== NSG Rules ===" NIC=$(az vm show -g $RG -n $VM --query "networkProfile.networkInterfaces[0].id" -o tsv | xargs basename) NSG=$(az network nic show -g $RG -n $NIC --query "networkSecurityGroup.id" -o tsv | xargs basename 2>/dev/null || echo "None") if [ "$NSG" != "None" ]; then az network nsg rule list -g $RG --nsg-name $NSG --query "[].{Name:name, Port:destinationPortRange, Access:access, Priority:priority}" -o table else echo "No NSG attached to NIC" fi
echo "" echo "=== Connectivity Test ===" PUBLIC_IP=$(az vm show -g $RG -n $VM -d --query publicIps -o tsv) if [ -n "$PUBLIC_IP" ]; then echo "Testing SSH (22):" nc -zv -w 5 $PUBLIC_IP 22 2>&1 || echo "SSH not reachable" echo "Testing HTTP (80):" nc -zv -w 5 $PUBLIC_IP 80 2>&1 || echo "HTTP not reachable" else echo "No public IP" fi
echo "" echo "=== Recent Activity ===" az monitor activity-log list --resource-group $RG --resource Microsoft.Compute/virtualMachines --resource-name $VM --max-events 5 -o table
echo "" echo "=== Boot Diagnostics ===" az vm boot-diagnostics get-boot-log -g $RG -n $VM 2>/dev/null | tail -20 || echo "Boot diagnostics not enabled" EOF
chmod +x /usr/local/bin/check-azure-vm.sh
# Usage: /usr/local/bin/check-azure-vm.sh MyResourceGroup MyVM ```
Azure VM Connection Checklist
| Check | Command | Expected |
|---|---|---|
| VM running | az vm show | PowerState/running |
| NSG rules | az network nsg rule list | Port allowed |
| Public IP | az vm show | IP assigned |
| Network flow | az network watcher test | Allowed |
| Guest firewall | iptables -L | Port open |
| SSH service | systemctl status sshd | Active |
Verify the Fix
```bash # After fixing VM connection
# 1. Check VM status az vm show -g MyRG -n MyVM --query powerState // PowerState/running
# 2. Test SSH ssh azureuser@vm-ip // Connected
# 3. Check NSG az network nsg rule list -g MyRG --nsg-name MyNSG // Port 22 allowed
# 4. Test from external nc -zv vm-ip 22 // Connection succeeded
# 5. Check services ssh vm 'systemctl status sshd' // Active: active
# 6. Monitor connections ssh vm 'ss -tnp | grep :22' // SSH connections visible ```
Related Issues
- [Fix Azure VM Not Starting](/articles/fix-azure-vm-not-starting)
- [Fix Azure Network Security Group Not Applying](/articles/fix-azure-network-security-group-not-applying)
- [Fix Azure Public IP Not Assigned](/articles/fix-azure-public-ip-not-assigned)