← 글 목록

SSH 접속 문제 해결 과정 총정리

/ 7분 분량

SSH 접속이 갑자기 되지 않아 당황스러웠던 경험을 공유합니다. 복잡하게 느껴졌던 문제였지만, 단계별로 원인을 파악하고 해결책을 찾아가는 과정을 통해 시스템 오류 해결 능력을 키울 수 있었습니다.

SSH 접속 문제 해결 과정 총정리

SSH 접속이 갑자기 되지 않아 당황스러웠던 경험을 공유합니다. 복잡하게 느껴졌던 문제였지만, 단계별로 원인을 파악하고 해결책을 찾아가는 과정을 통해 시스템 오류 해결 능력을 키울 수 있었습니다.

학습 주제

  • 공부 주제: SSH 접속 불가 문제 해결 및 자동화 플레이북 수정
  • 대화 제목: SSH 접속 문제 해결 과정 정리
  • 학습 날짜: 2026년 6월 30일

질문과 탐구

처음에는 외부에서 SSH 접속 시 Connection timed out 오류가 발생했습니다. 이는 요청이 서버에 전혀 도달하지 못하고 있다는 것을 의미했습니다. Windows PowerShell의 Test-NetConnection으로 포트 연결 테스트를 수행했으나, TcpTestSucceeded : False, PingSucceeded : False라는 결과를 얻으며 네트워크 또는 하드웨어 레벨의 문제임을 확인했습니다.

이후 몇 가지 가능성을 염두에 두고 탐구를 진행했습니다.

  • IP 주소 변경 여부 확인
  • 공유기의 포트포워딩 오류 가능성
  • ISP(KT)의 CGNAT 차단 가능성
    하지만 이러한 외부 요인보다는 서버 자체의 상태를 먼저 확인해야 한다는 결론에 도달했습니다.

핵심 학습 내용

1. 증상 확인 및 초기 진단

  • 증상: SSH 접속 시 Connection timed out 오류 발생. Connection refused와 달리 요청 자체가 도달하지 않음을 시사.
  • 진단 도구: Test-NetConnection -ComputerName <IP> -Port <Port> (PowerShell)
  • 결과: TcpTestSucceeded : False, PingSucceeded : False → 네트워크/하드웨어 문제 확인.

2. 하드웨어 문제 발견

  • 서버 기기가 라즈베리 파이임을 확인.
  • 라즈베리 파이의 전원 상태(PWR LED, ACT LED) 확인 및 전원 케이블 재연결.
  • 해결: 물리적으로 전원을 재인가하자 라즈베리 파이가 정상적으로 켜짐.

3. 자동화 스크립트 분석

  • 크론탭 확인: 매일 새벽 1시에 ansible-playbook을 실행하는 run-update.sh 스크립트가 자동화되어 있었음.
  • 스크립트 내용: 타임스탬프 기반 로그 파일 저장.
  • 로그 분석: 6월 27일 이후 로그가 끊긴 것을 발견.

4. 근본 원인 규명

  • system-update.yml 플레이북 분석: 패키지 업데이트 후 reboot 태스크가 /var/run/reboot-required 파일 존재 여부에 따라 실행되도록 설정되어 있었음.
  • 문제점: 라즈베리 파이 OS(Debian 기반)에는 /var/run/reboot-required 파일을 자동으로 생성하는 도구(update-notifier-common 등)가 기본 탑재되어 있지 않음. 따라서 시스템 업데이트 후에도 재부팅이 영원히 건너뛰어졌음.
  • dpkg.log를 통한 물증 확보: 6월 27일 업데이트된 linux-libc-dev 패키지가 핵심 문제였음을 확인. 이 패키지 업데이트로 인해 메모리에 올라온 구버전 커널 구조와 새로 설치된 패키지(Docker) 간 충돌이 발생하여 네트워크 드라이버가 다운된 것으로 추정.
  • 추가 확인: last reboot 명령으로 6월 6일 이후 재부팅 기록이 없었음을 확인.

5. 플레이북 수정

  • 기존 /var/run/reboot-required 파일 체크 방식을 삭제.
  • 새로운 재부팅 조건: upgrade_res.changed (패키지 업데이트가 실제로 변경되었는지) 및 커널, 펌웨어, libc, docker 등 핵심 패키지 업데이트 여부를 upgrade_res.stdout에서 확인하여 재부팅을 실행하도록 수정.

이해한 내용

이번 학습을 통해 SSH 접속 문제가 단순한 네트워크 설정 오류가 아닌, 시스템 업데이트와 재부팅 메커니즘의 불일치에서 비롯될 수 있음을 명확히 이해했습니다. 특히, 특정 OS 환경에 따라 기본적으로 제공되는 기능이 다를 수 있다는 점을 알게 되었습니다. /var/run/reboot-required 파일의 존재 여부가 재부팅을 결정하는 중요한 트리거가 된다는 사실과, 이 파일이 없을 경우 재부팅이 필요한 업데이트에도 불구하고 건너뛰어질 수 있다는 점을 배웠습니다. 또한, dpkg.log와 같은 시스템 로그를 분석하여 문제의 근본 원인을 추적하는 방법을 익혔습니다.

실전 적용

이 지식은 다음과 같은 상황에 적용할 수 있습니다.

  • 서버 관리: 원격 서버 접속 불가 시, 단순히 네트워크 문제를 넘어 시스템 업데이트 및 재부팅 정책을 우선적으로 점검할 수 있습니다.
  • 자동화 스크립트 개선: Ansible, Chef, Puppet 등 설정 관리 도구를 사용하여 시스템 업데이트를 자동화할 때, OS별 재부팅 정책을 고려한 플레이북 작성이 가능해집니다.
  • 문제 해결 능력 향상: 복잡한 시스템 오류 발생 시, 로그 분석 및 시스템 상태 점검을 통해 근본 원인을 체계적으로 파악하는 능력을 기를 수 있습니다.

실습 계획:

  • 개인 서버(예: Raspberry Pi)에 자동화된 시스템 업데이트 스크립트를 적용해보고, 재부팅 관련 로직을 직접 수정하며 테스트할 예정입니다.
  • 다양한 Linux 배포판 환경에서 /var/run/reboot-required 파일이 어떻게 관리되는지 비교 학습할 계획입니다.

추가 학습 계획

  • 커널 업데이트 및 재부팅 메커니즘 심화 학습: Linux 커널이 업데이트될 때 어떤 과정으로 시스템에 영향을 미치는지, 그리고 재부팅이 왜 필수적인지에 대해 더 깊이 공부하고 싶습니다.
  • Ansible 재부팅 모듈 상세 이해: Ansible의 reboot 모듈이 제공하는 다양한 옵션(타임아웃, 지연 시간 등)과 활용 사례를 더 찾아볼 예정입니다.
  • 시스템 로깅 및 모니터링 강화: syslog, journald 등 시스템 로깅 시스템을 효과적으로 활용하고, Prometheus, Grafana와 같은 모니터링 도구를 사용하여 시스템 상태 변화를 실시간으로 감지하는 방법을 학습하고 싶습니다.

참고 자료

  • dpkg.log: Debian/Ubuntu 기반 시스템의 패키지 설치, 삭제, 업그레이드 기록을 담고 있는 로그 파일.
  • /var/run/reboot-required: 시스템 업데이트 후 재부팅이 필요한 경우 생성되는 파일.
  • Test-NetConnection: Windows PowerShell에서 네트워크 연결 테스트를 수행하는 cmdlet.