Summary

  • RFC 4251은 호스트 이름과 공개 호스트 키를 클라이언트에 묶어 기록하고, 다음 접속부터 새로 제시된 키를 그 기록과 대조하는 방법을 설명한다.
  • OpenSSH는 그 기록을 known_hosts에 보관한다. 처음 보는 키에는 확인을 요청하고, 알던 서버의 키가 달라지면 접속을 거부할 수 있다. 인증된 서버는 다음에 쓸 키도 미리 알려 줄 수 있다.

SSH 키 교환에서 서버는 호스트 키를 제시한다. 클라이언트가 정말 알아야 하는 것은 그 키가 애초에 찾아가려던 서버의 것인지다. 2006년 1월의 RFC 4251은 두 길을 적었다. 호스트 이름과 키의 관계를 클라이언트가 직접 보관하거나, 신뢰하는 인증 기관의 증명을 받는 길이다. 앞의 방법은 중앙 명부 없이 굴러간다. 대신 첫 번째 줄을 어떻게 믿고 쓸 것인지는 각자의 몫이다.

RFC가 묘사한 실용적인 절차는 이렇다. 첫 접속의 키를 받아 적고, 이후 같은 호스트를 만날 때마다 비교한다. 컴퓨터에 기억력이 생긴다. 하지만 첫 인사를 가로챈 사람이 자기 키를 내밀면 잘못된 얼굴이 기준이 될 수 있다. 문서가 별도 통신 경로로 지문을 확인하는 방법을 언급하는 이유다. 진짜 키를 기억한 뒤에는 다른 키가 같은 이름표를 달고 들어오기가 훨씬 어려워진다.

OpenSSH에서 그 수첩은 ~/.ssh/known_hosts다. OpenBSD의 ssh(1) 설명서는 알려진 호스트의 키를 저장하는 방식과 키가 달라졌을 때의 눈에 띄는 경고를 설명한다. 경고만 보고 범인을 알 수는 없다. 서버를 다시 만들었거나 계획대로 키를 바꿨을 수도 있고, 누군가 흉내 내고 있을 수도 있다. 클라이언트는 어느 이야기가 맞는지 꾸며 내지 않는다. 어제의 기록과 오늘의 제시가 다르다고 말한다.

OpenBSD의 ssh_config(5)는 첫 방문을 대하는 태도를 나눈다. StrictHostKeyChecking=ask는 새 키를 기록하기 전에 사람에게 묻고, 이미 아는 호스트의 변경된 키는 거절한다. accept-new는 새 호스트를 자동으로 받아 적되 변경은 거절한다. yes는 새 키를 미리 직접 넣어 두도록 한다. 첫 인사를 빨리 끝낼지는 고를 수 있다. 두 번째 인사에서 기억을 버릴지는 별개의 문제다.

정상적인 키 교체에는 예고편이 있다. UpdateHostKeys를 쓰면 이미 인증된 서버가 추가 호스트 키를 클라이언트에 전할 수 있다. 옛 키로 신원을 확인할 수 있을 때 새 키를 먼저 수첩에 적고, 나중에 옛 키를 내린다. 처음 보는 사람이 혼자 와서 «저 어제 그 사람입니다»라고 주장하는 장면과는 다르다.

ssh-keyscan은 공개 키를 모아 known_hosts에 넣기 좋은 형태로 내놓는다. 그러나 설명서는 수집만으로 키의 주인을 인증할 수 없다고 분명히 말한다. 네트워크 중간의 공격자도 키를 내밀 수 있다. 수첩을 빨리 채우는 것과 첫 줄을 정확히 쓰는 것은 다른 일이다. 이 방식의 힘은 다음 방문을 첫 기록에 비추어 묻는 기억에 있다.