원격 접속이 막힌 서버 복구하기

홍혁준·2023년 11월 12일
1

프로젝트를 진행하는 중 갑작스럽게 kerdy서버를 복구해야할 일이 있었었다.
해결과정 탐색과 어떻게 해결했는지 기록해보려고 한다.

단, 급박하게 prod 서버를 복구해야 했기에 몇몇 부분은 시도하지 못한 채 빠르게 넘어간 부분이 있다 가장 안정적이고, 확실한 방법을 시도해보려 했다.

배경

별 문제 없이 kerdy의 서버를 운영하고 있었는데, aws가 위험 IP를 감지해주었다.

guardDuty가 위험한 IP에서 서버에 요청을 보냈음을 이를 감지하고 slack에 메시지를 보내줬다.

nginx의 accessLog를 보니,

무작위 IP에 /?XDEBUG_SESSION_START=phpstorm 로 공격을 하기 위한 사전 정보 수집을 하고 있다.
조사 결과 php 서버면 디버그 모드로 변경할 수 있는 공격이라고 한다.

우리의 prod 서버는 aws 환경이었기에 NACL 로 한번에 제한하면 어떻겠나?라고 생각을 했지만, NACL 변경 권한이 우리에게 없어서, 일단은 자체적으로 막아야 했다.

그 때 떠오른 방법은 우분투 내장 방화벽인 ufw를 설치하여 방화벽 룰을 만드는 것이었다.

sudo apt-get install ufw
sudo ufw enable
sudo ufw deny from (malicious IP) to any

위와 같이 방화벽 세팅을 했다.
(그런 짓은 하지 말아야 했는데...)

방화벽 설정 후 ssh 연결을 끊고 나서 문제를 인지했다.

방화벽은 기본적으로 any any deny룰이 깔려 있다.

sudo ufw status
ufw deny from (malicious IP) to any
(ufw deny from any to any) -> 얘가 숨어 있음

이런 형태였던 것이다.
정보보호병으로서 방화벽 룰을 그렇게 많이 만졌었는데, 이걸 잊어버리다니... 아무튼

위오 같은 형태였기에, 서버로 향하는 모든 요청이 다 ufw에서 거부된 것이다,

해결 방안

현재 해당 서버를 실제 서비스로 운영중이기에 빠르게 복구를 해야하는 상황이었다.
하지만 ssh로는 ec2 인스턴스에 대한 접속을 못하는 상황이다,

문제 상황을 인지하고 나서 가장 먼저 시도한건 ssh를 제외한 다른 접속 방법이 있는지 확인하는 것이다.

aws 직렬 콘솔 접속

가장 먼저 시도한 건 aws 직렬 콘솔 접속이었다.
aws 직렬 콘솔 접속을 하고, ufw를 해제해야지!! 라는 생각을 했었다.

aws 직렬 콘솔은 어떤? 이유인지는 모르겠지만 방화벽에 걸리지 않고 잘 된다. 이 방식에 대해서는 한 번 공부해봐야겠다.
네트워크가 아닌 다른 방식으로 연결하고 있다는게 추측이다.

현재 우리 계정의 권한으론 aws 직렬 콘솔 접속을 할 수 없어서 코치님들에게 요청해 ufw를 풀려고 했다.

하지만 안 된다...
aws 인스턴스에 접속을 하고 root 계정의 비밀번호를 설정하지 않으면, 직렬 콘솔 접속이 안 된다.(이번에 배웠다.)

우리 팀은 pem키로만 서버에 접속했기에 root 비밀번호를 설정할 일이 없었다. root 권한이 필요하면 sudo를 쓰면 됐으니까

ssh 접속 -> 방화벽에 막힘
직렬 콘솔 접속 -> 비밀번호 미설정으로 접속 불가

다방면으로 접속을 시도해본 결과 기존 ec2를 접속하여 복구하는 것은 불가능하다.는 결론을 얻었다.

새로운 ec2 생성

결국 새로운 ec2를 만들고 해당 서버로 prod 서버를 대체해야 했다.

이를 인지하고 나서 (너무나도 부정하고 싶었지만)
바로 prod 서버를 구축했을 때의 문서를 확인해서 체크리스트를 만들었는데

  • CD를 위한 self hosted runner 교체
  • docker 설치
    • docker hub 로그인
  • 무중단 배포 스크립트 작성
  • nginx 설치
    • nginx 설정파일 작성
    • nginx 무중단 배포 설정 파일 작성
  • 새 ec2 s3 권한 부여
  • 로그 파일 복구
  • 새로운 IP 기존 도메인에 할당
  • etc...

그냥 설치만 하는 것들은 문제가 없는데 설정파일을 별도로 백업해두질 않았어서 문제가 생겼다.
(+ 추가적으로 지금 서비스 상에 문제가 있어서 warn.log 와 error.log들을 분석해야할 필요성을 느꼈다.)

초반엔 아예 문서만을 통해서, 서버를 복구해보려 했으나 조사 중 ec2의 볼륨을 ebs라는 형태로 제공해주고 있다는 것을 알았다.

그러면 어떤 걸 시도해볼 수 있을까?

ebs를 기반으로 새로운 ec2 만들기

snapshot(ebs)으로 복구하기

ebs를 snapshot을 찍어 ec2를 만드는 것을 가장 먼저 시도해봤다.
그러면 서버가 사실 교체가 되는거니까.

문제가 없을 거라고 생각 해봤지만, 복구 시 ufw 룰까지 적용되어 복구될 것 같아서 배제했다.
파일의 경로가 똑같았기에 아마 ufw도 그대로 복구가 될 것이라 생각했다.

새로운 ec2에 기존 ebs를 루트 볼륨으로 교체

새로운 ec2를 만들고 해당 ec2에서 ebs를 root 볼륨으로 갈아끼운 후, ufw 설정을 바로 꺼보면 어떨까?라는 생각을 하고 이를 시도해봤다.

하지만, 동작하는 서버의 root 볼륨을 바꾸는 작업은 다방면으로 시도해봤지만 실패했다.
시간이 있었다면 다양하게 시도해봤을텐데, 일단 복구가 우선이었기에 막힌 부분은 빠르게 넘겼다.

새로운 ec2에 추가 파일시스템으로 기존 ebs 할당

마지막으로 ec2에 파일 시스템을 만들고 해당 파일 시스템에 ebs를 할당하는 방법을 생각해봤다.

aws 공식문서 ebs 볼륨을 linux에서 추가하기
라는 공식문서를 보고, 해당 방식의 가능성을 느끼고 시도해봤다.

해당 문서를 보고 많은 시도를 하다가, 나중에 꺠달음을 얻었다.

문서에 있는 내용 다 필요 없고, ebs 볼륨을 aws 콘솔에서 ec2에 추가한 후 mount만 하면 연결이 가능하다. (문서가 날 속였어!)

초기에 ebs 볼륨을 콘솔에서 ec2에 추가하면 아래와 같은 파일시스템 구조를 띈다.

ubuntu@ip-192-168-1-148:~$ lsblk 
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS 
loop0 7:0 0 21.3M 1 loop /snap/amazon-ssm-agent/7529 
loop1 7:1 0 49.1M 1 loop /snap/core18/2794 
loop2 7:2 0 59.3M 1 loop /snap/core20/2019 
loop3 7:3 0 109.6M 1 loop /snap/lxd/24326 
loop4 7:4 0 35.5M 1 loop /snap/snapd/20102 
nvme0n1 259:0 0 20G 0 disk 
├─nvme0n1p1 259:2 0 19.9G 0 part / 
└─nvme0n1p15 259:3 0 99M 0 part /boot/efi
nvme1n1 259:1 0 20G 0 disk 
├─nvme1n1p1 259:4 0 19.9G 0 part 
└─nvme1n1p15 259:5 0 99M 0 part 

여기서 중요한건 nvme0n1nvme1n1이다.
nvme0n1은 새로운 ec2의 볼륨이고, nvme1n1은 prod 서버의 볼륨이다.
나는 nvme1n1p1을 마운트하여, 해당 디스크의 정보를 옮기는 것이 목표였다.

여기서 배경지식이 없었기에 많은 삽질을 했었는데,
단순하게 sudo mount /dev/nveme1n1p1 /back 만 호출해주면 됐다.
공식문서에 있는 내용대로 할 필요가 없었다.

옮기고 나서, 아예 /back 경로에 있는 파일들을 /경로로 덮어씌우려고 했다.
이를 테면 sudo cp -v /back/* / 으로 말이다.
이러면 기존 서버의 볼륨을 루트 볼륨을 교체한 것 과 같은 효과를 낼 수 있을 거라고 생각했다.

우분투에선 모든 설정들이 파일로 관리되고 있었기에 위처럼 하면 빠르게 해결될 거라 생각했다.

그치만 이 작업이 너무 느리기도 하고 확신이 없어서 중간에 멈췄다.
중간에 우분투의 동작을 담당하는 파일과 같은 중요 내용들이 덮어씌워질 때 우분투가 정상적으로 유지 될 거라는 확신이 없었다.
(추후에 시도해보려고 한다.)

그래서, 서버에서 실제로 작성한 파일들인
/home/ubuntu의 파일들과
/etc/nginx의 파일들만 복사하고, 나머지를 세팅해줬다.
(docker 설치, 도메인 ip 변경 등등)

복사한 후에는 5분만에 서버를 정상적을 배포했다.

후기

이 서버 복구과정을 거치면서, 정말 힘들긴 했지만 많은 걸 배울 수 있었다.

  • 서버를 spof로 구성하면 안 되는 이유
  • os에서 직접 관리하는 방화벽에 대한 위험성
  • ebs, 파일 시스템, 볼륨에 대한 내용
  • 문제가 발생했을 때 해결하기 위한 탐색 과정 등

서버는 짧은 시간동안 내려갔지만, 그 동안 너무 많은 일들이 있었다.
이번 일은 절대 잊혀지지 않을 것 같다.

profile
끊임없이 의심하고 반증하기

0개의 댓글