모든 VPS 또는 클라우드 제공자에서 첫 SSH 연결의 MITM 막기

4 hours ago 2
  • ssh-init-vm은 새 VM의 첫 SSH 접속에서 중간자 공격을 막기 위해 cloud-init으로 임시 SSH 호스트 개인키를 주입하고, 장기 호스트 키를 생성·가져오는 동안만 신뢰하게 함
  • Hetzner Cloud처럼 전용 접속 보호 기능이 없는 VPS나 클라우드에서도 동작하며, 필요한 것은 널리 지원되는 cloud-init뿐임
  • 일반적인 Trust On First Use에서 ssh의 “The authenticity of host [...] can't be established” 질문에 yes를 입력하면, 공격자가 트래픽을 프록시하거나 사용자의 VM처럼 보이는 머신을 제공할 수 있음
  • 장기 SSH 호스트 개인키를 cloud-init userdata에 직접 넣으면 첫 접속 인증에는 도움이 되지만, 메타데이터 서비스·SSRF·클라우드 제공자 시스템·관리자 워크스테이션을 통해 민감한 키 자료가 노출될 수 있음
  • ssh-init-vm은 임시 키를 임시 디렉터리에 두고 ~/.ssh/known_hosts에 넣지 않으며, VM 출력물을 그대로 저장하지 않고 OpenSSH의 호스트 키 순환에 의존해 장기 키를 기록함

cloud-init userdata 노출 문제

  • cloud-init으로 장기 SSH 호스트 개인키를 주입하면 공개키를 ~/.ssh/known_hosts에 넣어 첫 접속을 인증할 수 있지만, 개인키가 여러 경로로 유출될 수 있음
  • VM 내부의 임의 프로세스가 일반적으로 읽을 수 있는 메타데이터 서비스에서 userdata를 얻을 수 있으며, Hetzner VM에서는 http://169.254.169.254/hetzner/v1/userdata로 cloud-init 내용이 보일 수 있음
  • 공격자는 SSRF를 통해 프로세스가 메타데이터를 누설하도록 만들 수 있고, 이런 차단은 전용 보호 기능이 있는 환경에서도 항상 적용되는 것은 아님
  • 클라우드 제공자의 다른 시스템에서도 userdata가 노출될 수 있으며, Hetzner는 서버 생성 API 문서에서 “passwords or other sensitive information”을 저장하지 말라고 명시
  • 관리자 워크스테이션도 cloud-init userdata가 남거나 지나가는 위치가 될 수 있으므로, 장기 개인키를 넣는 방식은 키가 유효한 동안 노출될 위험을 만듦

보안 분석과 위협 모델

  • 전제는 OpenSSH 프로토콜과 구현을 신뢰하며, 관리자가 공격을 탐지하는 능력에는 의존하지 않는다는 것임
  • 네트워크 공격자에 대한 보호

    • 보호 대상은 관리자 워크스테이션의 무결성과 VM임
    • 공격자는 네트워크를 완전히 제어하는 중간자이며, 스크립트가 성공하거나 실패해 종료된 뒤 어느 시점에 cloud-init userdata를 알게 될 수 있음
    • 공격자가 키 자료를 가치가 남아 있는 시점에 알지 못하기 때문에 보호가 성립함
    • 스크립트는 임시 SSH 호스트 키의 우발적 사용을 막기 위해 이를 임시 디렉터리에 보관하며, 임시 SSH 호스트 키를 ~/.ssh/known_hosts에 넣지 않음
  • 관리자 워크스테이션이 침해된 경우

    • 보호 대상은 VM과 VM의 장기 SSH 호스트 개인키에 한정됨
    • 공격자는 네트워크와 관리자 워크스테이션을 완전히 제어하지만, 실제 VM에는 접속하지 않는다고 가정함
    • 장기 SSH 호스트 개인키는 관리자 워크스테이션에 있었던 적이 없고, 공격자가 실제 VM에 접속하지 않기 때문에 VM의 장기 호스트 키를 얻지 못함
    • 공격자가 실제 VM에 접속하면 ssh root@<VM> cat /etc/ssh/ssh_host_* 같은 방식으로 SSH 호스트 키를 알 수 있을 가능성이 큼
  • VM 또는 제공자가 침해된 경우

    • 보호 대상은 관리자 워크스테이션의 무결성에 한정됨
    • 공격자는 네트워크를 완전히 제어하고 VM이나 제공자도 완전히 제어할 수 있음
    • 이 경우에도 OpenSSH가 안전하다는 전제 때문에 관리자 워크스테이션의 무결성을 보호함
    • 추가 방어로 스크립트는 VM 출력물을 그대로 ~/.ssh/known_hosts에 쓰지 않고, OpenSSH 순환에 의존해 장기 SSH 호스트 키를 넣음
    • 이 방식은 침해된 호스트가 known_hosts 파서에 악성 데이터를 먹이는 것을 막고, VM이 실제로 제어하는 키만 ~/.ssh/known_hosts에 기록되게 함
    • HashKnownHosts 같은 OpenSSH 옵션과 향후 관련 옵션도 올바르게 처리할 수 있음

실제 중간자 공격이 성립하는 조건

  • 중간자 공격의 성공 여부는 사용자가 모든 접속이 처음부터 잘못된 머신으로 향하고 있음을 실제로 감지하는지, 비밀번호 입력을 거부하는지, ssh의 agent 또는 X11 전달을 설정하는지에 따라 달라짐
  • ssh-mitm 기준의 단순화된 조건으로는, 공격자가 진짜 대상 호스트가 아니라 공격자 제어 머신에 접근 권한을 제공해 사용자를 속일 수 있으면 성공 가능성이 큼
  • 공격자가 사용자를 속여 진짜 호스트에 로그인할 수 있는 정보를 얻어도 성공함
    • 사용자가 공격자 머신에 비밀번호로 로그인하면 공격자가 성공할 수 있음
    • 사용자가 어떤 인증 방식으로든 로그인한 뒤 프롬프트에서 비밀번호를 입력하면 공격자가 성공할 수 있음
    • 사용자가 어떤 인증 방식으로든 로그인하고 ssh-agent 연결을 전달하면 공격자가 성공할 수 있음
  • 위 조건이 없으면 공격자는 사용자를 속이기 위해 진짜 호스트 접근이 필요하지만, 사용자의 입력만으로는 진짜 호스트에 로그인할 수 없어 실패할 가능성이 큼
  • 사용자가 X11 연결을 전달하면 공격자는 인증 방식과 별개로 관리자 워크스테이션을 공격하는 데 성공할 수도 있음
Read Entire Article