SSH 클라이언트가 서버에 접속(ssh user@host) 할 때의 “표준적인 동작 순서”를 정리함.
- SSH2 기준(RFC로 2006년 표준화)임
- SSH1 (1995년 초 설계된 Protocol Version 1)은 deprecated 상태로 보안상 사용을 하면 안됨.
0. TCP 연결
- 클라이언트 → 서버
TCP connect(host:22): 포트는 서버 설정에 따라 변경될 수 있음. - 아직은 SSH 레벨 암호화 전 (그냥 TCP)
1. 프로토콜 버전 문자열 교환
- 서로 이런 문자열을 주고받음
- 예:
SSH-2.0-OpenSSH_9.x
- 예:
- “우리는 SSH2로 대화한다”를 확인하는 단계
어떤 protocol version으로
대화할지 맞추는 단계.
2. 알고리즘 협상: SSH_MSG_KEXINIT
KEYINT : Key Exchange Initialization - 키 교환을 위한 알고리즘 협상 시작.
- 클라이언트가 “내가 지원하는 목록” 전송
- 서버도 “내가 지원하는 목록” 전송
보통 다음 묶음들을 협상함:
- 키 교환(KEX): (EC)DH 계열
- 서버 호스트키 알고리즘: ed25519 / ecdsa / rsa 등
- 대칭 암호: AES-CTR/GCM, ChaCha20-Poly1305 등
- 무결성(MAC, Message Authentication Code): HMAC 또는 AEAD에 포함 (데이터가 전송중 바뀌지 않았고, 송신자 인증을 같이 수행)
- 압축: none/zlib 등
3. 키 교환(KEX) + 서버 인증(Host Key)
- (EC)DH로 공유 비밀값
K를 “각자 계산” (K자체를 보내진 않음)- 서로 교환하는 건 공개값(
A,B) 같은 것들 - 이를 교환하고 나면 같은 K를 계산할 수 있음.
- 이 시점에서
- K를 통한 대칭키 암호를 통한 안전한 채널 생성이 가능해짐.
- 하지만, 아직 상대방이 신뢰할 수 있는 누구인지 모르는 상태.
- 서로 교환하는 건 공개값(
- 서버는 다음을 전송:
- 자기 호스트 공개키
- 자기 호스트 비밀키로 키교환관련 데이터의 해쉬값에 서명
- 데이터는 클라이언트/서버 버전, KEXINIT, DH 공개값, 공유 비밀
K등 포함 - 이 데이터와 해쉬값의 관계는 키와 fingerprint와의 관계와 유사.
- 데이터는 클라이언트/서버 버전, KEXINIT, DH 공개값, 공유 비밀
- 이 둘을 보내어 내가 진짜 그 서버다”를 증명 요청
- 서명을 서버공개키로 검증하면, 대응하는 비밀키를 가진 대상임이 확인되는 것임.
- 클라이언트는 서버 호스트 공개키를 검증
- 보낸 서버 호스트 공개키로부터 fingerprint 계산하고
- 이를
~/.ssh/known_hosts에 있는 fingerprint 와 비교하여 서버의 신원을 확인.- 바뀌었으면 경고 및 중단(중간자 공격 의심)
- 최초 접속인 경우 사용자에게 해당 호스트키를 신뢰할지 여부를 질의: (TOFU: Trust On First Use).
- 서버 호스트키 신원이 확인된 후, 해당 서버 호스트 공개키를 사용하여 서버가 보낸 서명(signature) 을 검증
- 서버가 보낸 서명이
- 해당 서버 호스트 공개키에 대응하는 비밀키로 생성된 것이며,
- 클라이언트가 키 교환 과정에서 사용된 값들(
A,B,K등) 로부터 독립적으로 계산한 해시값(exchange hashH) 에 대해 생성된 것인지 확인 - 서버와 클라이언트는 공개적으로 교환된 값(
A,B)과 각자의 비밀값으로부터 계산된 공유 비밀 K를 이용해 동일한 해시값H를 독립적으로 계산할 수 있다.
ECDH(Elliptic Curve Diffie–Hellman) 는
타원곡선(Elliptic Curve) 위에서 수행되는 Diffie–Hellman 키 합의 방식 알고리즘.
4. 세션 키 파생 + 암호화 전환
- 양쪽이 공유 비밀
K와 교환 메시지 해시H등으로부터
- 대칭 세션 키, (필요 시) MAC 키, IV 등을 KDF로 파생
NEWKEYS메시지를 주고받고- 이 순간부터 모든 SSH 패킷이 암호화/무결성 보호됨
참고: KDN은 Key Derivation Function의 약어.
5. 사용자 인증 (User Authentication)
- 이제 “사용자”가 누구인지 인증하는 단계 (서버는 이미 3)에서 인증됨)
- 클라이언트가
ssh-userauth서비스 요청 - 서버가 허용 인증 방식 안내(예: publickey, password, keyboard-interactive)
- 클라이언트가
A. 공개키 인증(현재 가장 널리 사용됨)
- 클라이언트가 “이 public key로 시도해도 됨?” 요청
- 서버가
authorized_keys등을 보고 가능 여부 응답 - 가능하면 서버가 서명 검증용 데이터를 주고,
- 클라이언트가 대응하는 private key 로 서명해서 전송
- 서버가 public key로 검증 : 성공/실패 결정
(키에 passphrase 가 걸려 있으면 이때 로컬에서 입력/에이전트 사용)
B. 비밀번호 인증(옵션)
- 암호화된 연결(tansport connection) 안에서 비밀번호를 보냄.
- 보안/정책상 오늘날에는 거의 쓰이지 않음.
6. 연결(세션) 서비스 시작: 채널(Channel) 생성
- 인증 성공 후
ssh-connection단계로 진입 - 하나의 SSH 연결 안에서 channel 을 연다.
여기서 channel은 그 위에서 동작하는 논리적 서비스 단위
대표적인 channel 의 종류는 다음과 같음:
- interactive shell (터미널 접속)
- exec (원격 명령 1회 실행)
- subsystem: sftp (SFTP)
- port forwarding (local/remote/dynamic)
7. 데이터 전송 (암호화된 패킷 흐름)
- 키 입력/출력, 파일, 포워딩 트래픽 등이
- 모두 SSH 패킷 단위로 캡슐화
- 대칭키로 암호화(+무결성/AEAD)
8. 일정시간 지나면 다시 대칭세션키 교환(Re-key) (장시간 연결 시)
- 일정 시간/전송량이 지나면 자동으로 다시 KEX 수행
- 새 세션 키로 교체(보안성 향상)
9. 종료
- 채널 close → 연결 close
- 세션 키는 폐기
전체 과정:
- TCP 연결
- 버전 교환
- 알고리즘 협상
- (EC)DH 키교환 + 서버호스트키검증
- 연결 암호화 ON (연 암호화는 대칭키방식)
- 사용자 인증
- 채널 열기(쉘/SFTP/포워딩)
- 통신
- (필요시) 다시 키교환
- 종료
같이보면 좋은 자료들
2025.08.05 - [utils] - ssh (Secure SHell) 사용 방법
ssh (Secure SHell) 사용 방법
SSH 는 Secure SHell의 약자로 암호화된 보안 연결을 통해 원격 서버에 안전하게 접속하고 명령을 실행할 수 있게 해주는 네트워크 프로토콜을 가리킴. (이를 사용하는 클라이언트 및 앱을 가리키기
ds31x.tistory.com
2023.12.27 - [utils/git and github] - [ssh-keygen] ssh 관련 private key와 public key 생성하기.
[ssh-keygen] ssh 관련 private key와 public key 생성하기.
ssh (secure shell)ssh는 secure shell의 약자로 네트워크 상에서 암호화된 통신을 위한 프로토콜 (및 이를 구현한 프로그램)을 가르킴. 주로 원격지의 장비에 보안이 보장된 접속을 제공하며 이를 위해
ds31x.tistory.com
https://ds31x.github.io/wiki/gpg/gpg_term/
GPG 관련 용어
ds31x.github.io
'CE' 카테고리의 다른 글
| SSH 키 알고리즘 비교 정리 (0) | 2026.01.18 |
|---|---|
| FIPS - Federal Information Processing Standard (1) | 2026.01.18 |
| C Runtime (CRT) 이란 - CRT, POSIX, System call, ABI (0) | 2026.01.16 |
| 특수키의 role과 notation - Special Key (0) | 2026.01.09 |
| Shell (Python Shell 포함) 의 키보드 단축키에 대해 (0) | 2026.01.07 |