Linux 강좌 / 네트워크 연결 문제를 계층별로 진단하기

리눅스 연결 문제는 인터페이스와 주소에서 시작해 경로, 이름 확인, 전송 연결, 애플리케이션 응답 순서로 확인하면 원인을 좁히기 쉽습니다. ping 하나의 성공이나 실패만으로 인터넷·웹 서비스 전체의 상태를 판단하지 마세요.

주소와 기본 경로를 해석할 때는 IP 주소·DNS·포트의 역할을 참고하세요. SSH에서만 실패한다면 SSH 접속과 파일 전송의 포트·키·호스트 확인도 필요합니다.

시스템 설정 실습의 기준은 Ubuntu 26.04 LTS와 Rocky Linux 9 계열의 일반 설치 VM입니다. 컨테이너·WSL·다른 릴리스에서는 서비스와 패키지 구성이 다를 수 있습니다. 가상 머신 실습 환경 만들기에서 콘솔 복구와 버전 확인을 먼저 준비하세요.

장애의 범위와 비교 조건부터 기록하기

어느 컴퓨터에서 어느 주소·포트로 언제부터 접속이 안 되는지 기록합니다. 모든 사이트인지 한 사이트인지, 같은 네트워크의 다른 장치도 실패하는지, IP 버전이나 VPN·프록시가 다른지 비교하세요. 직전에 바꾼 설정과 실제 오류 문구를 함께 남기면 추측을 줄일 수 있습니다. 운영 서버에서는 네트워크를 재시작하기 전에 콘솔이나 별도 관리 경로를 확보합니다.

인터페이스·주소·경로를 확인하기

ip -brief link
ip -brief address
ip route
ip -6 route

UP은 인터페이스가 관리상 활성화됐다는 정보이며 목적지까지 통신된다는 보장은 아닙니다. LOWER_UP 같은 링크 정보, 예상한 주소의 존재, 목적지에 맞는 경로를 함께 보세요. 가상 머신이라면 가상 NIC가 연결되어 있는지, NAT·브리지 중 의도한 모드인지 호스트의 가상화 설정도 확인합니다. 인터페이스 이름을 eth0으로 단정하지 마세요.

실제 목적지 주소를 알아낸 뒤 ip route get 실제IPv4주소를 실행하면 선택되는 인터페이스·다음 홉·출발지 주소를 볼 수 있습니다. “Network is unreachable”은 이름 확인 오류와 다르게 경로 문제를 먼저 시사합니다. 경로가 출력되어도 다음 홉이나 그 이후 장치가 응답한다는 뜻은 아닙니다.

ping은 도달성의 한 단서로 사용하기

ping -c 3 127.0.0.1
ping -c 3 example.com

첫 명령은 루프백에 ICMP Echo를 보내고 둘째는 이름 확인 후 대상에 보냅니다. 대상이나 중간 장비가 ICMP를 차단하면 웹 접속이 정상이어도 ping은 실패할 수 있습니다. 반대로 ping 성공은 해당 웹 포트, 인증서와 HTTP 응답의 정상 여부를 확인하지 못합니다. 외부 대상에 반복 트래픽을 보내기보다 허용된 실습 대상에서 소수 회만 확인하세요.

이름 확인 실패와 연결 실패를 분리하기

getent ahosts example.com
curl -I -v --connect-timeout 5 --max-time 15 https://example.com/
printf "exit=%s\n" "$?"

getent 결과가 없으면 먼저 이름 서비스 설정을 확인합니다. curl의 자세한 출력에서는 주소 선택, 연결, TLS 교환, 응답 순서를 살펴봅니다. 종료 코드 6은 일반적으로 호스트 이름 확인 실패, 7은 연결 실패, 28은 시간 초과를 나타냅니다. 코드 60은 인증서 검증 문제로, 방화벽을 열거나 DNS를 바꾸는 것으로 해결되지 않을 수 있습니다. -k로 검증을 끄는 것을 해결책으로 삼지 마세요.

기본 curl은 HTTP 404나 500 응답을 받아도 전송 자체가 성공하면 종료 상태 0을 반환할 수 있습니다. HTTP 오류를 실패로 처리하려면 지원되는 curl에서 --fail-with-body 또는 --fail 사용을 검토하고, 응답 코드와 종료 상태를 따로 읽으세요. 자세한 출력에는 쿠키·헤더·내부 주소가 담길 수 있으므로 공유 전 가립니다.

서버에서는 대기 주소와 포트를 확인하기

ss -lnt
ss -lnu
sudo ss -lntp

127.0.0.1:8080에만 대기하면 같은 서버에서만 직접 접근할 수 있습니다. 0.0.0.0:8080은 모든 IPv4 인터페이스를 대상으로 하며, [::]:8080의 IPv4 동시 수신 여부는 소켓과 시스템 설정에 따라 달라집니다. 프로세스 정보는 권한에 따라 제한됩니다. UDP는 TCP의 LISTEN과 의미가 같지 않으므로 UDP 목록만으로 요청 응답을 보장할 수 없습니다.

관찰 결과에 맞는 변경 한 가지만 적용하기

관찰 우선 확인
로컬 접속도 실패 서비스 실행·설정·대기 포트
로컬 성공, 원격 실패 바인딩 주소·호스트 방화벽·클라우드 보안 규칙
연결은 되지만 인증서 오류 서버 이름·인증서 체인·시각
HTTP 오류 응답 웹 서버·애플리케이션 로그와 요청 경로

변경 전에 원래 값을 기록하고 한 항목만 바꾼 뒤 같은 클라이언트·주소·포트로 다시 시험합니다. 효과가 없으면 원래 값으로 돌린 다음 다른 가설을 확인하세요. 이렇게 해야 여러 변경 중 무엇이 원인이었는지 놓치지 않고, 문제 해결 과정에서 새로운 장애를 만들 가능성도 줄일 수 있습니다.

외부 사이트에 의존하지 않고 HTTP 오류를 구분하려면 실습 VM에 python3와 curl이 있는지 확인합니다. 없으면 배포판의 패키지 관리자로 설치합니다. 새 터미널에서 아래 서버를 실행하고 그대로 둡니다. 18080 포트 사용 중 오류가 나면 다른 빈 포트를 골라 두 명령의 번호를 함께 바꾸세요.

lab=$(mktemp -d "$HOME/linux-http-check.XXXXXX") &&
python3 -m http.server 18080 --bind 127.0.0.1 --directory "$lab"

서버가 정상 시작된 뒤 같은 VM의 다른 터미널에서 아래를 실행합니다. HTTP 404가 표시되고 curl 종료 상태는 22가 됩니다. 이는 이 요청에서 TCP 연결과 HTTP 응답은 도착했지만 파일이 없다는 뜻입니다. 서버 터미널에서 Ctrl+C로 종료한 뒤 다시 요청하면 수신 서버가 없으면 보통 연결 실패인 curl 상태 7이 되며, 연결 시도가 시간 제한까지 대기하는 환경에서는 상태 28이 될 수도 있습니다. 상태값은 바로 확인하며 새 서버가 같은 포트를 사용하지 않는지도 점검하세요.

curl --fail --show-error --connect-timeout 2 --max-time 5 http://127.0.0.1:18080/missing-file
printf "exit=%s\n" "$?"

공식 문서