VM 에 SSH, RDP 접속이 안 될 때 (증상, 원인, 해결)
Azure VM 에 SSH 나 RDP 가 연결되지 않을 때 네트워크 경로(공용 IP, NSG, JIT, Bastion), 게스트 OS(방화벽, sshd, RDP 설정, 디스크 꽉 참, fstab), 인증(키, 비밀번호, Entra 로그인)으로 나눠 확인하는 순서와 부트 진단, 직렬 콘솔, Run Command, VMAccess 로 복구하는 방법을 정리합니다.
증상
ssh: connect to host 20.x.x.x port 22: Connection timed out
ssh: connect to host 20.x.x.x port 22: Connection refused
Permission denied (publickey).
원격 데스크톱에서 원격 컴퓨터에 연결할 수 없습니다.메시지마다 의심할 곳이 다릅니다. 먼저 어디서 막혔는지 갈래를 나눕니다.
| 증상 | 뜻 | 먼저 볼 곳 |
|---|---|---|
| Connection timed out | 패킷이 VM 까지 못 가거나 응답이 안 옴 | 네트워크 경로 (원인 1~3) |
| Connection refused | VM 까지 갔지만 포트에서 듣는 프로세스가 없음 | 게스트 OS 서비스 (원인 4) |
| Permission denied, 로그인 실패 | 연결은 됐고 인증 실패 | 인증 (원인 6) |
| 포털에서 VM 상태가 실행 중이 아님, 부팅 화면 멈춤 | OS 가 안 올라옴 | 부트 진단 (원인 5) |
먼저 확인: VM 자체 상태
# 전원 상태와 프로비저닝 상태
az vm get-instance-view -g rg-shop-prod -n vm-web-01 \
--query "{power:instanceView.statuses[1].displayStatus, agent:instanceView.vmAgent.statuses[0].displayStatus}" -o table- VM deallocated: 할당 해제 상태입니다. 동적 공용 IP 는 시작 후 바뀔 수 있습니다.
- VM 에이전트 Not Ready: 게스트 안의 에이전트가 응답하지 않습니다. OS 가 멈췄거나, 에이전트가 168.63.129.16 에 닿지 못하는 경우입니다. 이 상태에서는 Run Command 와 확장(VMAccess)도 동작하지 않으므로 직렬 콘솔로 갑니다.
원인과 해결
원인 1. 공용 경로가 없음
공용 IP 가 없는 VM 에 인터넷에서 직접 SSH 할 수는 없습니다. 운영 VM 은 공용 IP 를 붙이지 않는 것이 원칙이므로, 경로는 보통 다음 셋 중 하나입니다.
| 경로 | 특징 |
|---|---|
| Azure Bastion | 브라우저(포털)나 네이티브 클라이언트로 RDP, SSH. VM 에 공용 IP 불필요 |
| VPN, ExpressRoute | 사내망에서 사설 IP 로 접속 (하이브리드 연결) |
| JIT VM 액세스 | 공용 IP 가 있는 VM 의 관리 포트를 요청할 때만 잠깐 열기 |
Bastion 은 SKU 에 따라 기능이 다릅니다. Developer SKU 는 별도 서브넷 없이 쓰는 무료 SKU 로 개발, 테스트용이고, Basic 이상은 AzureBastionSubnet(/26 이상)이 필요합니다. 로컬 ssh, mstsc 같은 네이티브 클라이언트 연결과 IP 기반 연결은 Standard 이상에서 됩니다. 정확한 SKU 별 기능은 공식 문서의 비교표를 확인합니다.
원인 2. NSG 가 막음
NSG 는 서브넷과 NIC 양쪽에 붙을 수 있고, 들어오는 트래픽은 둘 다 통과해야 합니다. 한쪽만 고치고 다른 쪽에 막혀 있는 경우가 흔합니다. Bastion 으로 접속할 때는 VM 쪽 NSG 가 Bastion 서브넷 대역에서 22, 3389 를 허용해야 합니다.
# NIC 에 실제로 적용되는 규칙 (서브넷 + NIC 합산)
az network nic list-effective-nsg -g rg-shop-prod -n vm-web-01-nic -o table
# Network Watcher IP 흐름 확인: 이 패킷이 허용되나, 어느 규칙이 결정했나
az network watcher test-ip-flow --vm vm-web-01 -g rg-shop-prod --direction Inbound \
--protocol TCP --local 10.1.2.4:22 --remote 10.0.1.68:50000IP 흐름 확인은 막은 규칙 이름을 알려 줍니다. JIT 를 켜 둔 VM 이면 관리 포트를 막는 JIT 규칙이 자동으로 들어가 있으니, 요청을 승인받았는지와 요청한 원본 IP 가 맞는지 봅니다. JIT 는 Defender for Servers Plan 2 기능입니다 (보안 운영).
원인 3. 경로(UDR)와 방화벽, 비대칭 라우팅
스포크 서브넷에 0.0.0.0/0 을 허브 방화벽으로 보내는 UDR 이 있고, VM 에 공용 IP 로 들어온 접속이 있으면 응답이 방화벽으로 나가 버려 연결이 끊깁니다. 들어온 길과 나가는 길이 다르면 상태 기반 방화벽이 패킷을 버립니다.
해결: 공용 IP 로 직접 접속하지 말고 Bastion 이나 VPN 을 씁니다. 꼭 필요하면 관리 출발지 대역에 Internet 다음 홉 경로를 따로 둡니다. Network Watcher 의 다음 홉과 연결 문제 해결로 경로를 확인합니다.
원인 4. 게스트 OS 의 서비스, 방화벽
네트워크는 열려 있는데 Connection refused 라면 VM 안의 문제입니다.
- Linux:
sshd가 죽었거나,sshd_config를 잘못 고쳐 재시작에 실패했거나, 포트를 바꿔 둠.ufw,firewalld,iptables가 22 를 막음. - Windows: RDP 가 꺼짐, Windows 방화벽 규칙, RDP 포트 변경, 인증서 문제, 원격 데스크톱 서비스(TermService) 중지.
이때는 네트워크 없이 VM 안에서 명령을 실행하는 Run Command 를 씁니다(VM 에이전트가 Ready 여야 함).
# Linux: sshd 상태와 설정 문법 확인
az vm run-command invoke -g rg-shop-prod -n vm-web-01 --command-id RunShellScript \
--scripts "systemctl status sshd --no-pager; sshd -t; ss -ltnp | grep :22"
Windows 는 EnableRemoteDesktop, ResetRDPCert 같은 기본 제공 Run Command 로 RDP 를 되살립니다. 포털 VM 화면의 암호 재설정(Reset password) 에서 "구성만 재설정" 모드를 고르면 RDP 설정을 기본값으로 되돌릴 수 있습니다.
원인 5. OS 가 부팅되지 않음
VM 은 실행 중인데 아무 응답이 없다면 OS 부팅을 의심합니다.
- 부트 진단: 포털 VM 화면의 "부트 진단" 에서 스크린샷(Windows)과 직렬 로그(Linux)를 봅니다. 관리 스토리지 계정으로 켜 두면 따로 스토리지를 만들 필요가 없습니다.
- 직렬 콘솔: 부트 진단이 켜져 있으면 포털에서 VM 의 직렬 포트에 직접 붙습니다. 네트워크와 상관없이 로그인 프롬프트를 받을 수 있지만, 비밀번호가 있는 로컬 계정이 있어야 로그인됩니다(SSH 키만 있는 계정은 불가).
Linux 의 대표적인 부팅 실패입니다.
| 직렬 로그에 보이는 것 | 원인 | 해결 |
|---|---|---|
emergency mode, Dependency failed for /data | /etc/fstab 의 디스크를 못 찾음 (UUID 변경, 분리된 데이터 디스크) | 직렬 콘솔에서 해당 줄에 nofail 추가 또는 주석 |
No space left on device 로 서비스 시작 실패 | OS 디스크 꽉 참 | 로그 정리, OS 디스크 확장 |
커널 패닉, grub> 프롬프트 | 커널 업데이트 실패 | 이전 커널로 부팅 |
직렬 콘솔로도 안 되면 복구 VM 방식으로 갑니다. vm-repair CLI 확장의 az vm repair create 가 OS 디스크 사본을 붙인 복구 VM 을 만들고, 거기서 파일을 고친 뒤 az vm repair restore 로 원래 VM 에 디스크를 바꿔 끼웁니다.
원인 6. 인증 실패
| 상황 | 해결 |
|---|---|
SSH 키를 잃어버림, authorized_keys 꼬임 | az vm user update --ssh-key-value (VMAccess 확장이 키를 다시 넣음) |
| 비밀번호를 잊음 | az vm user update --password 또는 포털의 "암호 재설정" |
| Entra ID 로그인 VM 에서 거부 | VM 에 Virtual Machine Administrator Login 또는 Virtual Machine User Login 역할 확인 |
| sshd 설정을 망침 | az vm user reset-ssh 로 SSH 설정 초기화 |
# 공개 키 다시 넣기 (사용자 없으면 만듦)
az vm user update -g rg-shop-prod -n vm-web-01 -u azureuser --ssh-key-value ~/.ssh/id_ed25519.pub
# Entra ID 로 SSH (AADSSHLoginForLinux 확장이 설치된 VM)
az ssh vm -g rg-shop-prod -n vm-web-01Entra 로그인은 키 배포 없이 역할과 조건부 액세스로 통제할 수 있어 권장됩니다. 역할이 있는데도 거부되면 AuthorizationFailed 문서의 역할 반영 지연을 확인합니다.
접속은 되는데 VM 이 인터넷에 못 나감
apt update, dnf, Windows 정품 인증이 실패한다면 인바운드가 아니라 아웃바운드 문제입니다. 2026-03-31 이후 API 버전으로 만든 새 VNet 의 서브넷은 기본이 프라이빗 서브넷이라 공용 IP 없는 VM 이 받던 기본 아웃바운드 IP 가 없습니다(2026-10 기준). NAT Gateway, 방화벽 경유, Standard Load Balancer 아웃바운드 규칙 중 하나를 명시합니다 (VM 문서, VNet 과 NSG).
예방
- 운영 VM 에는 공용 IP 를 두지 않고 Bastion 이나 VPN 으로만 접속합니다.
- 모든 VM 에 부트 진단(관리 스토리지) 을 켜 둡니다. 꺼져 있으면 직렬 콘솔도 쓸 수 없습니다.
- 비상용 로컬 계정 비밀번호는 Key Vault 에, 데이터 디스크 fstab 항목에는
nofail을. - VM 에이전트와 168.63.129.16 통신을 막지 않습니다. 이 주소가 막히면 확장, Run Command, 상태 보고가 모두 멈춥니다.