AWS EC2 SSH 접속 시 Host Key Verification Failed 해결 및 원리

라우드 인프라를 운영하다 보면 인스턴스 재생성이나 IP 재할당 과정에서 REMOTE HOST IDENTIFICATION HAS CHANGED라는 붉은색 경고 메시지를 마주하게 됩니다. 이는 AWS EC2와 같은 동적 환경에서 매우 빈번하게 발생하는 현상입니다. 초급 엔지니어는 이를 해킹 시도로 오인하거나 당황하여 .ssh 디렉터리를 통째로 삭제하는 실수를 범하기도 합니다. 하지만 이 경고는 SSH 프로토콜의 핵심 보안 메커니즘이 정상적으로 작동하고 있음을 나타내는 신호입니다.


@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!      @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
...
Host key verification failed.

이 글에서는 해당 오류가 발생하는 기술적 원인(Root Cause)을 SSH 핸드셰이크 과정과 연계하여 분석하고, 단일 클라이언트 해결책부터 CI/CD 파이프라인을 위한 자동화 설정까지 단계별 해결 방안을 제시합니다.

1. 오류 발생 원인과 SSH 신뢰 모델

SSH(Secure Shell)는 클라이언트와 서버 간의 암호화된 통신을 보장하기 위해 TOFU(Trust On First Use) 모델을 사용합니다. 클라이언트가 서버에 처음 접속할 때, 서버는 자신의 공개키 지문(Fingerprint)을 제공하고 클라이언트는 이를 ~/.ssh/known_hosts 파일에 저장하여 신뢰 관계를 형성합니다.

이후 동일한 IP나 도메인으로 접속을 시도할 때, SSH 클라이언트는 로컬에 저장된 지문과 현재 서버가 제시하는 지문을 대조합니다. 만약 두 지문이 일치하지 않는다면 SSH는 이를 잠재적인 중간자 공격(MITM, Man-in-the-Middle Attack)으로 간주하여 연결을 즉시 차단합니다.

AWS 환경에서의 특수성: AWS EC2에서는 탄력적 IP(Elastic IP)를 다른 인스턴스로 재연결하거나, 인스턴스를 종료하고 동일한 IP를 가진 새 인스턴스를 생성하는 경우가 많습니다. 이때 IP는 같지만 서버의 호스트 키(Host Key)가 변경되므로 SSH 클라이언트는 이를 보안 위협으로 탐지합니다.

2. 단계별 해결 전략 (Troubleshooting)

가장 일반적인 해결 방법은 신뢰할 수 없는(변경된) 구형 키 정보를 로컬 known_hosts 파일에서 제거하는 것입니다. 상황에 따라 다음 세 가지 방법을 적용할 수 있습니다.

2-1. ssh-keygen을 이용한 특정 호스트 키 제거 (Recommended)

가장 안전하고 정확한 방법은 ssh-keygen 유틸리티를 사용하여 문제가 되는 특정 IP의 키만 제거하는 것입니다. 수동으로 파일을 편집할 때 발생할 수 있는 휴먼 에러를 방지할 수 있습니다.


# 문법: ssh-keygen -R <IP_ADDRESS_OR_DOMAIN>

# 예시: 54.180.123.45 IP에 대한 키 제거
$ ssh-keygen -R 54.180.123.45

# 실행 결과 예시
# Host 54.180.123.45 found: line 10
# /Users/user/.ssh/known_hosts updated.
# Original contents retained as /Users/user/.ssh/known_hosts.old

이 명령어를 실행하면 기존 known_hosts 파일은 known_hosts.old로 백업되며, 해당 IP에 대한 라인만 삭제되어 즉시 재접속이 가능해집니다.

2-2. sed 명령어를 이용한 라인 삭제

에러 메시지에는 보통 문제가 되는 라인 번호가 명시됩니다. 이를 확인 후 sed 명령어로 해당 라인만 삭제할 수도 있습니다. 대량의 서버를 관리하는 스크립트에서 유용하게 사용됩니다.


# 에러 메시지 예시:
# Offending ECDSA key in /Users/user/.ssh/known_hosts:15

# 15번째 라인 삭제
$ sed -i '15d' ~/.ssh/known_hosts
Caution: macOS의 기본 sed와 Linux(GNU)의 sed-i 옵션 처리 방식이 다릅니다. macOS에서는 백업 확장자를 명시해야 하므로 sed -i '' '15d' ... 형태를 사용해야 합니다.

3. 자동화 및 CI/CD 환경 대응 (Advanced)

Auto Scaling Group이나 일회성 테스트 환경처럼 인스턴스가 빈번하게 생성되고 삭제되는 환경에서는 매번 호스트 키를 수동으로 갱신할 수 없습니다. 이러한 경우 SSH 클라이언트 설정을 조정하여 검증 과정을 우회할 수 있습니다.

3-1. StrictHostKeyChecking 옵션 활용

StrictHostKeyChecking 옵션을 no로 설정하면, 알려지지 않은 호스트 키를 자동으로 known_hosts에 추가하고 경고 없이 접속을 진행합니다. 이와 함께 UserKnownHostsFile/dev/null로 설정하면 호스트 키를 아예 저장하지 않아 디스크 I/O와 키 누적을 방지할 수 있습니다.


# 일회성 접속 시 옵션 추가
$ ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i my-key.pem ubuntu@<IP_ADDRESS>

3-2. SSH Config 파일 설정

특정 IP 대역(예: 사내 프라이빗 서브넷)에 대해 영구적으로 설정을 적용하려면 ~/.ssh/config 파일을 수정합니다. 이는 앤서블(Ansible)이나 젠킨스(Jenkins)와 같은 자동화 도구에서 서버에 접근할 때 필수적인 설정입니다.


# ~/.ssh/config 예시

# 10.0.x.x 대역의 서버에 대해서는 호스트 키 검증 무시
Host 10.0.*.*
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null
    LogLevel ERROR
옵션 (Option) 설명 (Description) 보안 영향 (Impact)
ask (Default) 키 변경 시 접속 거부, 새 키는 사용자에게 물어봄 High
yes 키 변경 시 접속 거부, 새 키 자동 추가 안 함 Very High
no 키 변경 시 경고 후 접속 허용, 새 키 자동 추가 Low (주의 필요)
Security Warning: StrictHostKeyChecking no 옵션은 MITM 공격에 대한 방어막을 제거하는 것과 같습니다. 따라서 신뢰할 수 있는 VPC 내부망이나 VPN 환경에서만 제한적으로 사용해야 하며, 퍼블릭 네트워크를 통한 접속 시에는 기본 설정을 유지하는 것을 권장합니다.

프로덕션 환경에서는 보안과 편의성 사이의 트레이드오프를 명확히 이해하고 설정을 적용해야 합니다. 단순한 경고 메시지 제거가 목적이 아니라, 인프라의 아키텍처에 맞는 올바른 접속 정책을 수립하는 것이 엔지니어의 역할입니다.

요약 및 제언

REMOTE HOST IDENTIFICATION HAS CHANGED 오류는 시스템의 결함이 아니라 보안 기능의 정상적인 작동입니다. 개발 및 테스트 단계에서는 ssh-keygen -R 명령어로 빠르게 대응하고, 자동화된 배포 파이프라인에서는 StrictHostKeyChecking 옵션을 상황에 맞게 조절하여 운영 효율성을 높이십시오. 무조건적인 보안 해제보다는 네트워크 격리 수준에 따른 차등 적용이 핵심입니다.

Post a Comment