SSH Connection refused vs timed out 차이점과 해결법
SSH 연결 실패 시 발생하는 Connection refused와 Connection timed out의 명확한 차이를 설명합니다. 전자는 서버 서비스의 문제이며 후자는 네트워크 경로의 문제입니다. 각 오류가 발생하는 원인과 진단 방법을 확인하여 서버 접속 문제를 신속하게 해결하십시오.
SSH에서 "Connection refused"와 "Connection timed out"의 의미
SSH connection refused와 SSH connection timed out은 정반대의 실패 상황이므로, 한쪽의 해결책이 다른 쪽의 해결책이 될 수는 없습니다. Refused는 패킷이 서버에 도달했으나 서버 커널이 "여기서 대기 중인 서비스가 없다"고 응답한 경우입니다. Timed out은 패킷이 응답할 대상에게 도달하지 못해 클라이언트가 기다리다 포기한 경우입니다. Refused는 서버 측 서비스의 문제이며, Timed out은 서버 앞단 경로의 문제입니다.
클라이언트가 출력한 정확한 문구를 확인하십시오. 해당 문구 자체가 전체 진단 결과입니다.
ssh: connect to host 203.0.113.10 port 22: Connection refused
ssh: connect to host 203.0.113.10 port 22: Connection timed out응답 시간은 두 번째 단서입니다. Refused는 왕복 시간(round trip) 정도의 짧은 시간 내에 즉시 반환됩니다. Timed out은 클라이언트가 포기하기 전까지 계속 재전송을 시도하므로 수 초 동안 멈춰 있다가 출력됩니다. macOS는 동일한 상태를 Operation timed out로 출력합니다. 프로토콜 자체가 생소하다면, 이 가이드의 배경 지식인 SSH의 작동 원리와 sshd의 역할을 먼저 읽어보시기 바랍니다.
"Connection refused"가 좋은 소식인 이유
Refused는 TCP(transmission control protocol) 리셋을 의미합니다. 클라이언트가 포트 22로 SYN 패킷을 보냅니다. 이 패킷은 인터넷을 거쳐 서버의 네트워크 스택에 도달하지만, 커널이 해당 포트에서 리슨 중인 소켓을 찾지 못하면 RST(reset) 패킷으로 응답합니다. SSH 클라이언트는 이 RST를 Connection refused이라는 문구로 변환하여 보여줍니다.
돌아오는 이 패킷 하나가 많은 것을 증명합니다. 주소는 정확합니다. 호스트는 켜져 있고 라우팅도 정상입니다. 경로상의 어떤 장비도 해당 포트로 향하는 트래픽을 조용히 폐기하지 않습니다. 원격지에서 무언가가 응답했기 때문입니다. 따라서 남은 모든 의심 요소는 서버 내부에 존재합니다.
sshd가 실행 중이지 않습니다. 시작에 실패했거나 활성화되지 않았기 때문입니다.sshd가 다른 포트에서 리슨 중입니다. 보통 보안 강화 작업 이후에 발생합니다.sshd이ListenAddress 127.0.0.1과 같은 특정 주소에만 바인딩되어 있어, 서버 자신만 접근할 수 있습니다.- 방화벽이 패킷을 드롭(drop)하지 않고 리젝트(reject)하도록 설정되어 있어, 호스트를 대신해 방화벽이 RST를 보냅니다. ufw의
reject동작이나reject with tcp reset로 끝나는 nftables 규칙이 모두 이와 같이 동작합니다.
이와 비슷해 보이지만 다른 경우가 하나 더 있습니다. 다른 활성 호스트의 주소를 잘못 입력한 경우입니다. 해당 호스트가 SYN에 응답하지만 포트 22에 SSH가 없으므로 정중하게 거절하는 것입니다. 엉뚱한 서버에서 시간을 낭비하기 전에 주소를 먼저 확인하십시오. Linux에서 리슨 포트의 실제 의미를 이해하면 이 섹션의 나머지 내용을 더 빠르게 파악할 수 있습니다.
Connection refused 해결 방법
SSH 자체가 작동하지 않으므로 SSH를 통해 이 문제를 해결할 수는 없습니다. 제공업체의 웹 콘솔이나 시리얼 콘솔을 열어 로그인한 뒤, 다음 명령어를 순서대로 실행하십시오.
systemctl status ssh
sudo ss -tlnp
sudo sshd -T | grep -Ei '^(port|listenaddress|addressfamily)'systemctl status ssh은 Ubuntu 및 Debian에서 사용하는 유닛 이름입니다. RHEL 및 AlmaLinux와 같은 파생 배포판에서는 유닛 이름이 sshd입니다. ss -tlnp는 리스닝 상태인 모든 TCP 소켓과 해당 소켓을 소유한 프로세스를 나열하며, 이는 가장 확실한 진단 근거가 됩니다. 설정 파일의 내용과 관계없이 sshd를 언급하는 줄이 없다면 아무것도 리스닝하고 있지 않은 것입니다. sshd -T은 모든 Include 파일이 병합된 후의 최종 설정을 출력합니다. 여기서 /etc/ssh/sshd_config.d/에 잊고 있던 포트 설정이 있는지 확인할 수 있습니다.
주소 열을 주의 깊게 확인하십시오. 0.0.0.0:22은 서버의 모든 IPv4 주소를 의미합니다. [::]:22은 모든 IPv6 주소를 의미합니다. 127.0.0.1:22은 루프백 주소만 의미하므로, 로컬에서의 ssh localhost 접속은 완벽하게 작동하더라도 외부에서의 모든 원격 접속은 거부됩니다.
아무것도 리스닝하고 있지 않다면 서비스를 시작하고, 시작되지 않을 때 출력되는 오류 메시지를 확인하십시오.
sudo sshd -t
sudo systemctl enable --now ssh
sudo journalctl -u ssh -n 50 --no-pagersshd -t은 실행 중인 서비스에 영향을 주지 않고 설정을 구문 분석하여 잘못된 지시어의 파일 경로와 줄 번호를 출력합니다. 설정이 거부되면 sshd가 시작 시 종료되어 다음 접속이 거부되므로, 재시작 전에는 항상 이 명령어를 실행하십시오.
Ubuntu의 소켓 활성화 함정
Ubuntu 24.04는 OpenSSH를 위한 systemd 소켓 유닛을 포함하여 배포됩니다. 해당 유닛이 활성화된 상태라면 systemd가 리스닝 포트를 점유하고 연결마다 sshd를 실행하므로, Port 2222의 sshd_config를 수정해도 아무런 변화가 없으며 서버는 기존 포트로 계속 응답합니다. 설정을 변경하기 전에 현재 어떤 모드로 동작 중인지 확인하십시오.
systemctl is-enabled ssh.socket
systemctl status ssh.socket소켓이 활성화되어 있다면 sshd_config이 아닌 소켓 유닛에서 포트를 설정해야 합니다.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222빈 ListenStream= 줄은 반드시 필요합니다. systemd의 리스트 설정은 기존 설정에 값을 추가하는 방식이기 때문입니다. 이 줄을 생략하면 서버는 두 포트 모두에서 리스닝을 수행합니다. sudo systemctl daemon-reload와 sudo systemctl restart ssh.socket을 사용하여 변경 사항을 적용한 뒤, sudo ss -tlnp을 통해 새로운 포트가 정상적으로 점유되었는지 확인하십시오. 포트 변경은 VPS의 SSH 보안 강화 과정에서 일반적인 단계이지만, 사용자가 서버 접속을 차단당하는 가장 흔한 원인이기도 합니다.
"Connection timed out" 오류가 응답 없음을 의미하는 이유
타임아웃은 침묵을 의미합니다. 클라이언트가 SYN 패킷을 보낸 뒤 1~2분 동안 여러 번 재전송했음에도, 서버로부터 단 하나의 패킷도 받지 못한 상태입니다. 서버로부터 아무런 응답을 듣지 못했으므로, 서버의 상태에 대해서는 아무것도 증명된 바가 없습니다.
침묵은 DROP 규칙이 만들어내는 결과이며, 패킷을 버리는(dropping) 행위는 의도된 것입니다. 거부(rejection) 응답은 스캔을 수행하는 대상에게 해당 호스트가 존재함을 알리기 때문에, ufw와 모든 클라우드 제공업체의 네트워크 방화벽은 원치 않는 패킷을 폐기하고 아무런 응답도 보내지 않습니다. 타임아웃은 보통 열려 있어야 할 포트에서 방화벽이 자신의 역할을 수행하고 있을 때 발생합니다.
- 주소가 잘못된 경우: DNS 레코드가 이미 재구축한 서버를 가리키고 있거나, 아무도 사용하지 않는 주소로 연결되는 오타가 있는 경우입니다.
- 호스트가 실행 중이 아닌 경우: 전원이 꺼져 있거나 재부팅이 진행 중인 상태입니다. 요금 미납으로 인한 서비스 제공업체의 정지 조치도 외부에서는 동일하게 보입니다.
- 호스트 방화벽이 22번 포트를 차단하는 경우: 허용 규칙이 생성되기 전에
ufw enable가 먼저 실행된 경우가 가장 흔합니다. - 인스턴스 앞단의 제공업체 방화벽이 패킷을 차단하는 경우: 운영 체제는 해당 패킷을 전혀 전달받지 못합니다.
- 사용자의 네트워크가 22번 포트의 아웃바운드 연결을 차단하는 경우: 사무실이나 호텔 네트워크에서 흔히 발생하는 현상입니다.
연결의 반대편에서 테스트 실행하기
가장 많은 시간을 낭비하게 만드는 실수는 다음과 같습니다. 패킷이 도달하지 않는 서버 내부에서는 패킷 유실 문제를 진단할 수 없습니다. 명령어를 실행하기 위해 서버에 로그인할 수 있다면, 애초에 이 문제는 발생하지 않았을 것입니다. 이 섹션의 모든 명령어는 사용자의 로컬 머신에서 실행합니다.
getent hosts vps.example.com
ssh -G vps.example.com | grep -Ei '^(hostname|port|user)'
ssh -vvv -o ConnectTimeout=10 user@vps.example.com
nc -vz -w 5 203.0.113.10 22getent hosts은 사용자의 머신이 실제로 사용할 주소를 보여주며, 이를 통해 오래된 DNS 레코드를 즉시 찾아낼 수 있습니다. ssh -G은 ~/.ssh/config를 읽은 뒤 클라이언트가 적용하는 설정을 출력하므로, 호스트명, 포트, 사용자 정보를 조용히 재작성하는 오래된 Host 블록을 찾아냅니다. ssh -vvv는 연결 시도가 어디까지 진행되었는지 보여줍니다. 주소 연결에 관한 마지막 줄이 출력된 뒤 긴 지연이 발생하면 타임아웃이며, 원격 OpenSSH 버전을 보고하는 줄이 나타난다면 TCP 연결은 성공했으나 인증 단계에서 문제가 발생한 것입니다. Windows 환경의 PowerShell에서는 nc 대신 Test-NetConnection 203.0.113.10 -Port 22를 사용합니다.
호스트가 아닌 포트를 테스트하십시오. ping 실패는 아무것도 증명하지 못합니다. 많은 제공업체가 네트워크 경계에서 ICMP(internet control message protocol)를 차단하기 때문입니다. 성공적인 핑(ping) 역시 아무것도 증명하지 못합니다. 포트 22번의 상태에 대해서는 아무런 정보를 주지 않기 때문입니다.
그다음, 어떤 명령어로도 바꿀 수 없는 유일한 변수인 네트워크를 변경해 보십시오. 휴대폰 핫스팟을 사용하여 다시 시도하십시오. 핫스팟으로는 연결되는데 사무실 네트워크로는 연결되지 않는다면, 인터넷 경로상에서 차단되었거나 사무실 IP 주소가 서버에서 차단된 것입니다.
서버에서 보이지 않는 제공업체 방화벽
대부분의 VPS 패널은 인스턴스 상단에서 실행되며 자체 규칙 목록을 유지하는 네트워크 방화벽(보안 그룹 또는 클라우드 방화벽이라고도 함)을 제공합니다. 서버 내부의 ufw status는 이를 볼 수 없으므로 "이미 포트 22를 허용했는데 왜 안 되지?"라는 말이 흔히 나옵니다. 서버에서 규칙을 하나라도 수정하기 전에 패널을 열어 해당 목록을 먼저 확인하십시오.
이 문제를 해결하는 명령은 단 하나이며, 이를 위해서는 콘솔 접근 권한이 필요합니다. 서버에서 명령을 실행한 다음, 실행되는 동안 노트북에서 연결을 시도하십시오.
sudo tcpdump -ni any tcp port 22클라이언트가 연결을 시도하는 동안 아무런 반응이 없다면, 패킷이 운영체제에 도달하기 전에 폐기되는 것이므로 제공업체 방화벽이나 호스트로 향하는 경로에 문제가 있는 것입니다. SYN 패킷은 도착하는데 응답이 나가지 않는다면, 로컬에서 차단되는 것이며 ufw 또는 nftables의 문제입니다. 이 간단한 테스트 하나로 타임아웃의 원인을 절반으로 좁힐 수 있으므로, 콘솔에 접속할 가치가 충분합니다.
ufw 순서, IPv6, 그리고 스스로 차단하는 경우
ufw 설정 순서 오류는 이 가이드에서 가장 많은 사용자를 접속 불가 상태로 만드는 원인입니다. sudo ufw enable는 즉시 기본 수신 거부 정책을 적용하므로, SSH 규칙을 설정하지 않은 상태에서 활성화하면 기존 세션은 유지되지만 새로운 연결은 모두 시간 초과로 실패합니다. 반드시 허용 규칙을 먼저 추가한 뒤 활성화하십시오.
sudo ufw allow OpenSSH
sudo ufw status verboseOpenSSH 애플리케이션 프로필은 22번 포트만 포함합니다. SSH 포트를 2222로 변경할 계획이라면, 포트를 변경하기 전에 sudo ufw allow 2222/tcp 규칙을 먼저 추가해야 합니다. 더 광범위한 규칙 설정은 VPS를 위한 ufw 방화벽 기초에서 다루며, 안전한 설정 순서는 새 VPS를 대여한 후 첫 10분 동안 해야 할 일의 일부입니다.
IPv6는 초자연적인 시간 초과 현상을 유발합니다. 호스트네임에 AAAA 레코드가 있으면 클라이언트는 IPv6를 우선 시도하므로, IPv6 규칙이 누락된 서버는 IPv4 접속이 정상임에도 불구하고 연결이 지연됩니다. 두 프로토콜을 각각 수동으로 설정하십시오.
ssh -4 user@vps.example.com
ssh -6 user@vps.example.com-4로는 연결되지만 -6으로는 연결되지 않는다면, 서버의 IPv6 규칙에 문제가 있는 것이며 ufw에서 IPv6를 위해 동일한 포트 열기를 통해 해결할 수 있습니다.
스스로를 차단했을 가능성도 있습니다. fail2ban은 인증 로그를 감시하며 반복적으로 실패하는 주소에 대해 방화벽 규칙을 추가하므로, 잘못된 키를 사용하거나 백그라운드에서 재시도하는 스크립트가 사무실 전체 IP를 차단할 수 있습니다. 패킷을 드롭하는 차단은 시간 초과처럼 보이며, 거부(reject)하는 차단은 No route to host를 반환합니다. 콘솔에서 다음을 확인하십시오:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 198.51.100.24자신의 주소를 ignoreip에 추가하는 방법은 Ubuntu 24.04에서 정상적으로 작동하는 fail2ban 설정에서 확인할 수 있습니다.
거부되거나 타임아웃되지 않은 오류
No route to host은 ICMP 도달 불가 메시지가 반환되었음을 의미합니다. 로컬 머신에 해당 네트워크로 향하는 경로가 없거나, 경로상의 장비가 관리적 거부 응답을 보낸 경우입니다. iptables의 REJECT 규칙이 이 응답을 보냅니다.
Network is unreachable은 로컬 머신이 직접 응답하는 경우입니다. 해당 주소 체계에 대한 경로가 전혀 없을 때 발생하며, IPv4 전용 연결에서 호스트명이 IPv6 주소로만 해석될 때 주로 나타납니다.
kex_exchange_identification: Connection closed by remote host은 TCP 연결은 성공했으나 키 교환이 완료되기 전에 서버가 연결을 끊었음을 의미합니다. 포트는 열려 있고 sshd도 정상 작동 중이므로, 서버 부하 상태, MaxStartups, 또는 연결 도중 적용된 차단 정책을 확인하십시오.
Permission denied (publickey)은 인증 단계까지 도달했으나 인증에 실패했음을 의미합니다. 네트워크와 방화벽은 정상 상태이므로 이 가이드의 내용은 적용되지 않습니다. 대신 SSH에서 Permission denied (publickey) 해결하기를 참조하십시오.
다시 접속하는 방법과 재차 잠기는 상황을 방지하는 법
모든 신뢰할 만한 VPS 호스팅 업체는 게스트 네트워크에 의존하지 않는 콘솔을 제공합니다. 시리얼 콘솔이나 브라우저 기반의 VNC 화면이 이에 해당합니다. 이 콘솔은 sshd가 중단되었거나 방화벽 규칙이 모든 패킷을 폐기하는 상황에서도 작동하므로, 이 가이드의 두 경로 모두에서 복구 수단이 됩니다. 호스팅 업체의 제어판에서 콘솔을 찾아 root 또는 일반 사용자 계정으로 로그인한 뒤, 앞서 설명한 점검 사항을 수행하십시오. root 비밀번호를 설정하지 않았다면 대부분의 제어판에서 비밀번호를 재설정할 수 있습니다.
콘솔을 사용할 수 없는 경우, 제공업체의 구조 모드(rescue mode)가 최후의 수단입니다. 이 모드는 소규모 복구 시스템으로 부팅하여 디스크를 마운트하므로, 오프라인 상태에서 /etc/ssh/sshd_config을 수정하거나 방화벽 규칙을 삭제한 뒤 재부팅할 수 있습니다.
다음 잠김 사고를 방지하려면 두 가지 습관을 들여야 합니다. sshd나 방화벽을 수정할 때는 항상 두 번째 SSH 세션을 열어 두십시오. 기존 세션은 연결 상태가 유지되므로, 새로운 세션으로 테스트하는 동안 안전장치가 됩니다. 또한 위험한 방화벽 변경을 수행하기 전에 자동 복구 명령을 예약하십시오.
sudo systemd-run --unit=ufw-rollback --on-active=10min /usr/sbin/ufw disable
sudo systemctl stop ufw-rollback.timer첫 번째 줄은 10분 뒤에 ufw가 스스로 꺼지도록 예약합니다. 새로운 규칙을 적용하고, 새 SSH 세션을 열어 정상 작동을 확인한 뒤, 두 번째 줄을 실행하여 롤백을 취소하십시오. 만약 실수로 접속이 차단되었다면 10분을 기다리십시오. 방화벽이 스스로 해제됩니다. 이 상태에서는 ufw를 다시 활성화하기 전까지 서버가 필터링 없이 노출되므로, 이 방법은 영구적인 설정이 아니라 키보드 앞에 앉아 작업하는 동안에만 사용하십시오.
작업 순서
- 오류 메시지를 읽고 해당 오류가 발생하기까지 걸린 시간을 확인합니다.
- Refused 오류가 발생하면 콘솔로 이동하여
sudo ss -tlnp명령으로 리스닝 소켓, 포트, 바인딩된 주소를 확인합니다. - Timed out 오류가 발생하면 본인의 머신에서 해당 주소로 접속을 시도하고, 제공업체의 방화벽 설정과 서버 내부의 호스트 방화벽 설정을 차례로 확인합니다.
- 위 두 가지 오류가 아니라면 이미 TCP 연결이 성립된 상태입니다. 이 경우 네트워크 문제가 아닌 인증 문제나 서버 부하 문제로 간주하고 대응합니다.
FAQ
sshd가 실행 중인데 왜 SSH에서 "Connection refused"가 발생합니까?
연결 거부는 서비스가 아닌 소켓에서 발생하며, sshd가 실행 중이라도 연결을 거부할 수 있기 때문입니다. 제공업체의 콘솔을 열고 sudo ss -tlnp을 실행하십시오. 127.0.0.1:22의 소켓은 루프백 주소에만 바인딩되어 있으므로 모든 원격 클라이언트의 연결을 거부합니다. 다른 포트의 소켓은 여전히 22번 포트를 사용하는 모든 클라이언트의 연결을 거부합니다. systemd 소켓 활성화가 사용 중이라면 포트는 sshd_config이 아닌 ssh.socket에서 결정되므로 systemctl is-enabled ssh.socket도 함께 확인하십시오. ufw의 reject 규칙 또한 호스트를 대신하여 연결 거부를 반환할 수 있으므로, 결론을 내리기 전에 sudo ufw status verbose를 읽어보십시오.
ufw에서 22번 포트를 허용했는데 왜 SSH 연결 시간이 초과됩니까?
시간 초과는 응답이 돌아오지 않았음을 의미하며, ufw가 경로상의 유일한 방화벽이 아니기 때문입니다. 대부분의 VPS 패널은 인스턴스 앞단에서 네트워크 방화벽을 운영하며, 운영체제는 해당 방화벽이 차단한 패킷을 전혀 볼 수 없습니다. 콘솔에서 sudo tcpdump -ni any tcp port 22을 실행한 상태로 노트북에서 연결을 시도하십시오. 패킷이 도착하지 않는다면 패널의 상위 단계에서 차단된 것입니다. 패킷은 도착하지만 응답이 나가지 않는다면 ufw나 nftables 등 로컬에서 차단된 것입니다.
ping 실패가 곧 VPS가 다운되었음을 의미합니까?
아닙니다. 많은 제공업체가 네트워크 경계에서 ICMP를 필터링하므로, 정상적으로 트래픽을 처리하는 서버라도 모든 ping 요청을 무시할 수 있습니다. 반대로 ping이 성공한다고 해서 22번 포트가 열려 있다는 보장은 없으므로, ping 결과만으로는 서버 상태를 판단하기 어렵습니다. 자신의 컴퓨터에서 nc -vz -w 5 203.0.113.10 22을 사용하거나, Windows의 PowerShell에서 Test-NetConnection 203.0.113.10 -Port 22를 사용하여 포트 자체를 테스트하십시오.
SSH 포트를 변경했는데 연결이 되지 않습니다. 무엇이 문제입니까?
두 가지 순서상의 문제로 인해 발생합니다. 방화벽에 새 포트에 대한 규칙이 추가되지 않았다면 새 포트로의 연결은 시간 초과가 발생하고 22번 포트는 연결을 거부하므로, sudo ufw allow 2222/tcp은 포트 변경 후가 아닌 변경 전에 수행해야 합니다. 서버가 SSH를 위해 systemd 소켓 활성화를 사용 중이라면 sshd_config의 Port 2222는 무시되며 systemd가 계속 이전 포트를 점유하게 됩니다. 이는 systemctl is-enabled ssh.socket으로 확인할 수 있습니다. 제공업체 콘솔을 통해 복구하고 해당되는 문제를 수정한 뒤, sudo ss -tlnp에서 새 소켓이 확인되면 ssh -p 2222 user@203.0.113.10로 연결하십시오.