5 min read

개인 vps 장애 회고

개인 vps 장애 회고
Photo by Joshua Hoehne / Unsplash

최근 제 VPS 환경에서 발생한 '서비스 무한 펜딩' 사건을 해결하며 겪은 기록을 공유합니다. VPS 혹은 웹서비스를 운영 중인 분들이라면 한 번쯤 마주할 수 있는 리소스 문제와 보안 취약점에 대한 이야기입니다.


1. 장애의 시작: 모든 서비스의 'Pending'

사건은 Typesense 기반의 Full Text Search 기능을 구현하던 중 발생했습니다. 평소 잘 작동하던 NPM 기반 서비스들과 어드민 패널이 갑자기 응답을 멈췄습니다.

프록시 요청의 병목 현상

외부 클라이언트의 요청이 서버에 도달하지만, 최종 컨테이너까지 전달되지 못하는 과정입니다.

  1. Client Request: GET /api/search (Port 443)
  2. Nginx (NPM) Stage:
    • Accept 단계: 클라이언트의 연결 시도를 받음.
    • Worker Process 할당: 가용한 워커 커넥션 확인.
    • [Issue 발생]: 로그 확인 시 worker_connections are not enough 메시지 발견.
  3. Result: Nginx가 요청을 백엔드로 넘기지 못하고 대기열(Queue)에 쌓아두다가 타임아웃 발생 → 브라우저에서는 Pending 후 Canceled.

2. 1차 대응과 가속화된 늪: 방화벽과 SSH 유실

단순히 커넥션 수의 문제인 줄 알고 worker_connections를 512에서 4096으로 늘렸지만, 이는 근본 해결책이 아니었습니다. 설상가상으로 방화벽(UFW) 설정을 건드리면서 SSH 접근마저 차단되는 최악의 상황을 맞이했습니다.

inbound 트래픽 차단 레이어

방화벽 설정 오류가 발생하면, 데이터는 물리 서버 입구에서 증발합니다.

레이어상태데이터 흐름
External NetworkNormalTCP SYN (Port 22) 요청 전송
VPS Kernel (UFW)DROPRule Match: Deny -> 패킷 즉시 폐기
SSH DaemonIsolated요청 자체를 인지하지 못함 (Connection timed out)

Rescue system과 snapshot recovery마저 설정 파일(잘못된 방화벽 규칙)까지 함께 복구되는 바람에 소용이 없었죠. 다행히 호스팅사 기술 지원을 통해 SSH 접속 권한을 되찾았습니다.

please help me...
그래 임마. 도와줄게.

3. 2차 장애: "Killed" 메시지와 시스템 마비

겨우 접속에 성공했지만, 이번엔 도커가 실행되지 않았습니다. systemctl은 응답이 없고, curl 같은 기본 명령어를 치면 즉시 Killed라는 무시무시한 메시지가 떴습니다.

😰

[Process Lifecycle: 왜 실행되자마자 죽는가?]

이는 커널 수준에서 발생하는 리소스 보호 기제인 OOM(Out Of Memory) Killer의 작동 결과입니다.

  1. Command Execution: 유저가 $ curl ... 입력.
  2. Fork/Exec: 커널이 새로운 프로세스를 위해 메모리 할당 시도.
  3. Memory Check:
    • Available RAM: 0MB
    • Reserved for Kernel: 부족
  4. OOM Killer Action: 시스템 붕괴를 막기 위해 가장 점유율이 높거나 새로 뜨는 프로세스를 즉시 사살.
  5. 터미널에 Killed 출력 후 프로세스 종료.

4. 근본 원인 발견: 크립토재킹 (Cryptojacking)

top 명령어로 확인한 결과, 정체불명의 프로세스(EWsFl, N9qKjtRb)들이 **CPU 점유율 285%**를 기록하고 있었습니다.

이들은 외부 공격자가 제 서버의 권한을 탈취해 가상화폐 채굴 코드를 실행시킨 것이었습니다. 해당 프로세스들을 kill 명령어로 종료하자마자 시스템은 정상으로 돌아왔고, 도커 데몬도 다시 살아났습니다.

너였구나..

5. 마치며: 보안은 선택이 아닌 필수

이번 장애의 근본 원인은 '보안 취약점을 통한 침입'이었습니다. 공격자는 어떻게 들어왔을까요?

  • 추측 1: 공개된 컨테이너 서비스(n8n 등)의 취약점 이용.
  • 추측 2: 취약한 SSH 비밀번호 브루트 포스 공격. (아마도 이 방법으로 침입하지 않았을까...)

[보안 강화 조치 완료]

  • SSH 강화: 비밀번호 접속을 완전히 차단하고, 공개키(Ed25519) 인증 방식으로만 접근 가능하도록 변경.
  • 백업 자동화: 이번 사건을 계기로 Snapshot 외에 별도의 자동 백업 서비스를 가입했습니다.

개발자로서 서비스 구축만큼 중요한 것이 보안과 모니터링이라는 점을 뼈저리게 느낀 하루였습니다. 여러분의 VPS는 안전한가요? 지금 바로 top을 켜서 이름 모를 프로세스가 내 CPU를 갉아먹고 있지는 않은지 확인해 보세요.