네, 원문의 내용을 충실히 살리면서, 초보자도 "아, 이래서 안전하구나!"라고 무릎을 칠 수 있도록 상세하고 친절하게 풀어쓴 버전입니다. 개발 블로그에 그대로 복사해서 붙여넣으셔도 손색없도록 구조화하고 가독성을 높였습니다.
[Deep Dive] SSH 접속의 모든 것: ssh -i key.pem을 쳤을 때 일어나는 9단계 과정
개발자라면 AWS EC2나 리눅스 서버에 접속하기 위해 하루에도 수십 번씩 아래 명령어를 입력합니다.
ssh -i my-key.pem ec2-user@1.2.3.4
엔터를 누르고 프롬프트가 뜨기까지 걸리는 시간은 불과 1초. 하지만 그 짧은 찰나에 내부에서는 고도의 암호화 수학과 엄격한 인증 절차가 숨 가쁘게 돌아갑니다.
이 글은 SSH 접속 시 실제로 무슨 일이 벌어지는지, "인증(로그인)"과 "암호화(통신 보호)"를 명확히 분리하여 아주 상세하게 정리한 글입니다. 이 원리만 알면 SSH 접속 에러나 보안 경고가 떴을 때 당황하지 않고 원인을 찾을 수 있습니다.
0. 가장 먼저 잡아야 할 핵심 개념 2가지
SSH 과정을 이해하기 위해선 딱 하나, "키(Key)가 두 번 등장한다"는 사실을 먼저 기억해야 합니다. 많은 분들이 이 둘을 혼동합니다.
1) 로그인(인증)을 위한 키: "신분증"
- 종류: 클라이언트 사용자 키 (
my-key.pem,id_rsa등) - 목적: "내가 이 서버에 들어갈 권한이 있는 사람인지" 증명하는 용도입니다.
- 특징: 서버에 접속할 때 딱 한 번 신원 확인용으로 쓰입니다.
2) 통신(암호화)을 위한 키: "암호 코드북"
- 종류: 세션 대칭키 (Session Key)
- 목적: "SSH 세션 안의 모든 데이터(명령어, 출력 결과, 파일 전송 등)를 암호화"하는 용도입니다.
- 특징: 접속할 때마다 서버와 클라이언트가 협상해서 새로 만듭니다. (일회용)
💡 핵심 결론:
우리가 명령어에 넣는-i my-key.pem은 통신을 암호화하는 키가 아닙니다. 오직 "로그인 증명"에만 쓰입니다. 통신 암호화는 접속 때마다 새로 만든 대칭키로 수행합니다.
1. AWS EC2 .pem의 정체: 서버에는 무엇이 저장될까?
AWS에서 인스턴스를 만들 때 다운로드한 .pem 파일, 그리고 서버의 관계는 다음과 같습니다.
- 내 컴퓨터 (Client):
my-key.pem(개인키)를 가지고 있습니다. 이것은 절대 남에게 보여주면 안 되는 '도장'과 같습니다. - AWS 서버 (Server): 인스턴스 생성 시, 해당 키 페어의 공개키(Public Key)가 기본 사용자 계정의
authorized_keys파일에 자동 등록됩니다. - 위치 예시:
/home/ec2-user/.ssh/authorized_keys
즉, 서버는 "이 공개키에 딱 맞는 도장(개인키)을 가진 사람만 들여보내줘"라고 설정된 상태입니다. 그래서 우리는 공개키 내용을 외우지 않아도, 내 컴퓨터에 있는 개인키(pem)만으로 접속이 가능한 것입니다.
(참고: 만약 pem 파일에서 공개키 내용을 다시 뽑아보고 싶다면 아래 명령어를 씁니다.)
ssh-keygen -y -f my-key.pem > my-key.pub
2. SSH 접속 전체 단계 (The Full Flow)
이제 ssh -i my-key.pem ec2-user@<IP>를 입력하고 엔터를 탁! 쳤을 때 일어나는 일을 시간 순서대로 뜯어보겠습니다.
[1단계] TCP 연결 (네트워크 레벨)
가장 먼저 클라이언트는 서버의 22번 포트로 TCP 연결을 시도합니다. (노크)
- 여기서 막힌다면?
- AWS Security Group(보안 그룹)에서 22번 포트를 열어주지 않았거나,
- 네트워크 방화벽, 라우팅 문제일 가능성이 99%입니다.
[2단계] 프로토콜 버전 교환
연결이 되면 서로 인사를 나눕니다.
- "안녕? 나는 SSH-2.0 버전을 써."
- "반가워, 나도 SSH-2.0 지원해."
[3단계] 알고리즘 협상 (KEXINIT)
이제 앞으로 어떻게 통신할지 '규칙'을 정하는 회의를 합니다. 서로 지원 가능한 알고리즘 목록을 교환하고 합의합니다.
- 키 교환 방식(KEX): (EC)DHE, Curve25519 등 ("우리 암호키 어떻게 만들까?")
- 대칭 암호(Cipher): AES-GCM, ChaCha20 등 ("데이터는 뭘로 잠글까?")
- 무결성(MAC): ("데이터가 변조됐는지 어떻게 확인할까?")
[4단계] 키 교환 (Key Exchange) → 공유 비밀 생성 (★중요)
이 단계가 보안의 핵심입니다. 세션 대칭키(암호 코드북)를 만들기 위한 재료를 만듭니다. 주로 디피-헬먼(Diffie-Hellman) 방식을 사용합니다.
- 클라이언트: 비밀값
a를 만들고, 이를 가공한 공개값A를 서버에 보냅니다. - 서버: 비밀값
b를 만들고, 이를 가공한 공개값B를 클라이언트에 보냅니다. - 마법:
- 클라이언트는 (내 비밀
a+ 서버 공개값B)를 계산 → 값 S 도출 - 서버는 (내 비밀
b+ 클라이언트 공개값A)를 계산 → 값 S 도출 - 수학적으로 두
S는 동일한 값이 나옵니다!
핵심 포인트:
네트워크 선을 타고A와B가 왔다 갔다 했지만, 이것만 봐서는 해커가 절대 비밀값S를 유추할 수 없습니다. 즉, 진짜 암호키는 전송되지 않고 각자 자리에서 '생성'됩니다. 그래서 스니핑(도청)이 불가능합니다.
[5단계] 세션 대칭키 파생 + 암호화 채널 시작
위에서 만든 공유 비밀 S 하나로 끝이 아닙니다. 이를 바탕으로 여러 개의 키를 파생시킵니다.
- 클라이언트 → 서버 갈 때 쓸 암호키
- 서버 → 클라이언트 올 때 쓸 암호키
- 데이터 무결성 검증 키 등
"자, 이제부터 이 키들로 암호화해서 말하자!"라고 신호를 보낸 뒤, 이 시점 이후의 모든 SSH 패킷은 암호화됩니다.
(아직 로그인 안 했습니다! 로그인 정보를 안전하게 보내기 위해 보안 터널부터 뚫은 것입니다.)
[6단계] 서버 검증 (Host Key Verification)
터널은 뚫렸는데, 저쪽 끝에 있는 게 '진짜 내 서버'가 맞을까요? 해커가 만든 가짜 서버면 어쩌죠?
- 서버는 자신의 서버 호스트키(개인키)로 현재까지의 대화 내용을 서명해서 보냅니다.
- 클라이언트는 서버가 보낸 서버 호스트 공개키로 서명을 검증합니다.
- 그리고 내 컴퓨터의
~/.ssh/known_hosts파일을 봅니다.
- 첫 접속: "어? 이 서버 키는 처음 보는데? 믿을래?" →
Are you sure... (yes/no)?(이걸 TOFU: Trust On First Use라고 합니다.) - 재접속: 저장된 키와 다르면? →
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!경고를 띄웁니다. (중간자 공격 가능성)
요약: 이 단계는 중간자 공격(MITM)을 막는 단계입니다. 해커가 중간에서 가짜 서버 흉내를 내도, 서버의 호스트 키가 없으면 이 검증을 통과 못 합니다.
[7단계] 사용자 인증 시작 (User Authentication)
드디어 안전한 터널 위에서 로그인을 시도합니다.
"나 ec2-user로 로그인할게."
서버는 가능한 인증 방법을 알려줍니다. (EC2는 보통 비밀번호 끄고 publickey 방식만 켜둡니다.)
[8단계] 공개키 인증 (Public Key Authentication) → -i pem이 쓰이는 구간
이제 우리가 가진 my-key.pem이 주인공으로 등장합니다.
- 클라이언트: "나
my-key.pem에 해당하는 공개키 가지고 있어. 이걸로 인증할게." - 서버:
authorized_keys파일을 뒤집니다. "어, 그 공개키 등록되어 있네? 하지만 네가 진짜 그 키 주인인지는 확인해야겠어." - 검증 요청: 서버는 임의의 데이터(난수 등)를 주며 말합니다. "이거 네 개인키로 서명(Sign)해서 보내봐."
- 서명 생성: 클라이언트는
pem파일(개인키)을 이용해 데이터를 암호화 서명(Sig)합니다.
Sig = Sign(private_key, Data)
- 검증: 클라이언트는 서명값
Sig만 서버로 보냅니다. 서버는 가지고 있던 공개키로 이를 풉니다.
Verify(public_key, Data, Sig) == True
- 결과: 풀리면 로그인 성공!
중요:
개인키 파일(.pem) 자체는 절대로 네트워크를 타고 전송되지 않습니다. 가는 건 오직 '서명값'뿐입니다. 서명값은 매번 달라지므로 해커가 이걸 훔쳐봐도 재사용할 수 없습니다.
[9단계] 세션 채널 오픈 → 모든 데이터 암호화 통신
로그인이 성공하면 터널 안에 실제 데이터를 주고받을 '채널(Channel)'이 열립니다.
이제 우리가 치는 ls, cd 같은 명령어와 그 결과, 파일 전송 등 모든 트래픽은 [5단계]에서 만든 세션 대칭키로 암호화되어 흐릅니다.
3. "누가 훔쳐보면 어쩌죠?" 보안 Q&A
Q1. 해커가 네트워크 패킷을 스니핑하면 어떻게 되나요?
A. 아무것도 볼 수 없습니다.
[5단계] 이후의 모든 데이터는 대칭키로 암호화되어 있습니다. 해커 눈에는 a1b2c3d4... 같은 무의미한 난수만 보입니다. 암호화 키는 네트워크로 전송된 적 없이 각자 계산해서 만들었기 때문에 해커가 가질 수 없습니다.
Q2. 그럼 SSH는 무적입니까?
A. 2가지 약점은 조심해야 합니다.
- 무지성
Yes(MITM): 접속할 때 "이 서버 키 바뀌었는데 접속할래?"라는 경고를 무시하고Yes를 누르거나,StrictHostKeyChecking=no옵션을 남발하면, 해커가 만든 가짜 서버에 접속해서 정보를 털릴 수 있습니다. - 개인키(
pem) 유출: 내 컴퓨터에 있는.pem파일이 털리면 끝입니다. 그 파일만 있으면 누구든 나와 똑같이 로그인할 수 있습니다. 그래서 "프라이빗 키는 절대 공유 금지"인 것입니다.
4. 올바른 키 관리: "내 키는 나만, 친구는 친구 키로"
팀원과 서버를 같이 써야 할 때, 절대 내 .pem 파일을 메신저로 보내주지 마세요.
- 나만 접속: 서버
authorized_keys에 내 공개키만 있음. - 친구 추가: 친구에게 "너의 공개키(Public Key)를 줘"라고 한 뒤, 서버
authorized_keys에 한 줄 추가해 줍니다. - 친구 차단: 싸웠다면 친구의 공개키 줄만 지우면 됩니다. (내 키는 안전함)
보너스 팁: AWS Security Group에서 22번 포트는 0.0.0.0/0(전체 허용) 대신 My IP로 내 IP만 허용하세요. 키가 털려도 네트워크 레벨에서 막을 수 있는 최후의 보루입니다.
5. 실제로 눈으로 확인해보기 (실습)
백문이 불여일견, 터미널에서 -vvv 옵션을 붙여 접속해보세요. 위에서 설명한 9단계가 로그로 쏟아집니다.
ssh -vvv -i my-key.pem ec2-user@1.2.3.4
확인해볼 포인트:
debug1: kex: algorithm:: 어떤 키 교환 방식을 썼는지debug1: Authentications that can continue:: 서버가 어떤 인증을 허용하는지debug1: Offering public key:: 내 공개키를 들이미는 과정debug1: Authentication succeeded: 인증 성공!
6. 운영자를 위한 최소 보안 체크리스트
- 비밀번호 로그인 끄기:
/etc/ssh/sshd_config에서PasswordAuthentication no설정 - 개인키 권한 잠그기: 로컬에서
chmod 400 my-key.pem(나만 읽기 가능) - SSH 접속 경고 무시 금지:
known_hosts경고가 뜨면 무조건 확인하기. (IP가 바뀌었는지, 진짜 해킹인지) - IP 제한: 보안 그룹(방화벽)으로 접속 가능한 IP 최소화하기.
요약
SSH 접속은 (1) 키 교환 마법을 통해 둘만의 암호 코드를 '생성'하여 도청을 막고, (2) 질문-답변(서명) 방식을 통해 '키 파일 자체 전송 없이' 소유자를 증명하는 안전한 기술입니다.
'CKA' 카테고리의 다른 글
| Security - 인증서 생성 방법 (0) | 2026.01.01 |
|---|---|
| Security - TLS in Kubernetes (0) | 2026.01.01 |
| Security - 대칭키/비대칭키/CA (0) | 2026.01.01 |
| Security - Authentication 기초 (0) | 2025.12.31 |
| Security - 개요 (0) | 2025.12.31 |