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:

bash
Remote Desktop can't connect to the remote computer

HTTP connection refused:

```bash $ curl http://vm-ip

curl: (7) Failed to connect to vm-ip port 80: Connection refused ```

Azure portal shows:

bash
VM status: Running
But cannot connect

Why This Happens

  1. 1.NSG blocking - Network Security Group rules not allowing traffic
  2. 2.VM not running - VM deallocated or stopped
  3. 3.Firewall on VM - Guest OS firewall blocking
  4. 4.Wrong IP - Using private IP instead of public
  5. 5.Service not running - SSH/RDP service stopped
  6. 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

CheckCommandExpected
VM runningaz vm showPowerState/running
NSG rulesaz network nsg rule listPort allowed
Public IPaz vm showIP assigned
Network flowaz network watcher testAllowed
Guest firewalliptables -LPort open
SSH servicesystemctl status sshdActive

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 ```

  • [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)