엔지니어링

SSH 호스트 키 TOFU와 모바일 클라이언트가 신경 써야 하는 이유

Trust On First Use(TOFU) 호스트 키 검증에 대한 실용 가이드. 대부분의 모바일 SSH 앱이 어디서 잘못하는지 함께 정리.

CC Chen Chen· 창업자·2026년 4월 30일·10분 분량

TOFU가 실제로 의미하는 것

Trust On First Use(첫 사용 시 신뢰)는, 서버와 처음 통신할 때 그 서버의 식별자를 기록해 두는 보안 모델입니다. 그 이후 다른 식별자로 응답해 오는 연결은 모두 의심 대상입니다.

SSH에서 식별자는 서버의 공개 호스트 키——보통 Ed25519 또는 RSA 지문——입니다. prod-server.example.com에 처음 SSH로 접속하면 서버가 공개 키를 제시합니다. 당신은 그것을 신뢰하거나(직접 셋업한 서버니까) 신뢰하지 않습니다(직접 셋업한 서버가 아니라면 누군가 사칭 중일 수 있음). 한 번 신뢰하면 지문이 known_hosts 파일에 저장됩니다. 이후 연결은 같은 키를 제시해야 하며, 그렇지 않으면 OpenSSH는 진행을 거부합니다.

TOFU는 완벽하지 않습니다——첫 연결은 검증되지 않습니다——하지만 실용적입니다. 첫 핸드셰이크 이후에는 적대적 네트워크에서도 능동적 중간자 공격으로부터 보호됩니다.

모바일에서 더 중요한 이유

모바일 기기는 하루에도 여러 번 신뢰할 수 있는 네트워크와 신뢰할 수 없는 네트워크를 오갑니다: 집 Wi-Fi, 회사 Wi-Fi, 셀룰러, 굉장히 수상한 캡티브 포털이 있는 호텔 네트워크, 갑자기 이름이 "Free WiFi Login"이 된 카페 네트워크. 각각 모두 공격자가 경로상에 자리잡고 목표 SSH 서버를 사칭할 수 있는 장소입니다.

SSH 클라이언트가 서버 호스트 키를 올바르게 저장해 두었다면 이 모두는 문제가 되지 않습니다. 공격자의 키는 일치하지 않고, 연결은 안전하게 실패합니다. 클라이언트가 호스트 키를 저장하지 않는다면(또는 매번 서버가 보내는 어떤 키든 받아들인다면) 전혀 보호되지 않습니다. 22번 포트에서 응답하는 누군가에게 자격 증명을 그대로 건네는 셈입니다.

대부분 모바일 클라이언트의 (나쁜) 행동

TermAI 동작을 설계하기 전에 여러 인기 모바일 SSH 앱을 테스트했습니다. 가장 흔한 기본 동작:

  • 첫 접속 시 확인, 이후 재검증 없음. 첫 접속에서 지문 다이얼로그가 뜸. 사용자가 수락을 탭함. 키가 저장됨. 이후 접속은 조용히 일치 확인. 이것은 OpenSSH의 동작이며——제대로 구현되면 문제없음.
  • 첫 접속 시 확인하지만 UI가 혼란스러움. 위와 같지만 다이얼로그가 "서버를 확인할 수 없습니다" 같은 문구와 "수락" / "취소" 두 버튼만 표시. 대부분 사용자는 반사적으로 수락을 탭. 더 나쁜 것은 나중에 키가 바뀌었을 때도 같은 다이얼로그를 보여주고, 사용자가 또 수락한다는 것. 키 변경은 첫 접속과 전혀 다르게 보여야 합니다.
  • 아예 신경 안 씀. 일부 앱은 그냥 접속만, 지문 표시도 없고 변경 시 경고도 없음. 설계 단계에서 망가진 것.

세 번째 부류는 예상보다 흔했고, 유료 제품에도 있었습니다.

OpenSSH는 어떻게 하는가

OpenSSH의 known_hosts 파일이 참조 구현입니다. 동작은 다음과 같습니다:

# 첫 접속
$ ssh prod-server
The authenticity of host 'prod-server' can't be established.
ED25519 key fingerprint is SHA256:abc...xyz.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'prod-server' to the list of known hosts.

# 이후 키가 변경되면
$ ssh prod-server
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Host key verification failed.

첫 프롬프트는 정중함. 불일치는 적대적이며 접속을 거부함. 계속하려면 옛 항목을 수동으로 제거해야 함. 이 비대칭성——첫 사용 시 조용, 변경 시 강경——이 TermAI가 물려받은 설계입니다.

TermAI는 어떻게 하는가

호스트 지문은 기기 내 AES로 암호화된 Hive 박스에 저장합니다. 암호화 키는 iOS Keychain(Android는 Keystore 등가물)에 들어 있어서, 데이터베이스 파일을 기기에서 빼내더라도 시스템 키체인이 잠금 해제되지 않으면 읽을 수 없습니다.

  1. 첫 접속. 서버가 호스트 키를 제시. TermAI가 SHA256 지문을 계산해 SHA256:abc...xyz로 표시. 탭하면 복사 가능. 수락 버튼이 기본값, 취소 버튼도 분명히 표시됨. 수락하면 지문이 저장됨.
  2. 이후 접속. 지문이 저장 값과 일치 → 연결이 조용히 진행. 프롬프트, 경고, 중단 모두 없음.
  3. 이후 접속에서 불일치 발생. 강제 중지. 빨간 다이얼로그. 다이얼로그는 무슨 일이 생겼는지 설명하고 저장된 지문과 새 지문을 모두 보여주며, 의도적으로 원탭 수락 버튼은 없음. 계속하려면 설정 → Known Hosts로 들어가 저장된 지문을 명시적으로 삭제하고, 다시 접속해 다시 신뢰해야 함. 의도적인 2단계 프로세스.

2단계가 핵심입니다. 한 번 탭으로 키 불일치 경고를 무시할 수 있다면, 시간에 쫓기는 사용자는 그대로 통과시켜 버립니다. 그 중단 자체가 보호입니다.

실제 MITM 알아채기

클라이언트가 키 변경을 경고하면, 물어볼 것: 서버 키가 정당한 이유로 정말 바뀐 것인가, 아니면 무언가가 이 연결을 공격하고 있는가.

정당한 이유:

  • 서버에 OS를 재설치함
  • 의도적으로 호스트 키를 교체함
  • DNS로 호스트명을 다른 서버에 연결함
  • 서버가 로드 밸런서 뒤에 있고, 다른 백엔드에 닿음(모든 백엔드에 같은 키를 설정해야 함)

의심스러운 이유:

  • 완전히 신뢰하지 않는 새 Wi-Fi에 있음
  • 방금 예상치 못한 캡티브 포털을 만남
  • 서버 관리자가 키 변경을 알려주지 않음
  • 정상 서버를 직접 확인해도 이 지문이 완전히 처음 봄

의심스러울 때의 정답: 접속하지 말 것. 서버의 웹 콘솔 / 클라우드 제공자의 시리얼 콘솔 / 같은 네트워크상 신뢰할 만한 머신을 열어, 서버에 대해 ssh-keyscan을 실행하고 지문을 비교. 클라이언트가 보는 새 키와 일치하면 안전. 일치하지 않으면 MITM과 통신 중입니다.

정당한 키 변경

호스트 키를 정당하게 교체하는 경우(베스트 프랙티스: 2년에 한 번 정도), 모든 클라이언트를 혼란에 빠뜨리지 않는 깔끔한 방법이 있습니다:

  1. 새 호스트 키를 생성하되 옛 키도 수용 상태로 유지
  2. 전환 기간 동안 sshd가 둘 다 제공하도록 설정
  3. 사용자가 신뢰하는 채널(팀 비밀번호 관리자, 서명된 공지)로 새 지문을 배포
  4. 모두 업데이트한 뒤 옛 키 제거

개인 서버라면 그냥 "화요일에 호스트 키 교체합니다. 새 지문은 XX" 라고 미리 알리는 것으로 충분합니다. 한 마디만 더하면 경고 다이얼로그가 예상된 확인으로 바뀝니다.

핵심 요약

  • TOFU = 첫 사용 시 신뢰: OpenSSH와 동일한 호스트 키 모델
  • 연결마다 키 고정: 변경 시 이전과 새 지문을 함께 보여주는 경고 표시
  • 대역 외 검증: 서버에서 ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub 실행 후 대조하고 수락
  • 중간자 공격 방어: 키 변경은 중간자 공격의 징후 그 자체이므로 자동 수락하지 않음
  • 검증을 끄지 말 것: StrictHostKeyChecking no는 중간자 공격에 대한 유일한 방어를 제거
TermAI 사용해 보기

iOS/Android 무료. 무료 플랜은 AI 5회/일, SSH/SFTP 무제한, Tailscale 내장.

CC
Chen Chen — Founder of TermAI

Writes about mobile DevOps, terminal UX, and the surprising depth of "boring" infrastructure.

Was this useful? ← Back to blog