2P by GN⁺ 24시간전 | ★ favorite | 댓글 1개
  • SSH 세션에서 단일 키 입력 시 수백 개의 패킷이 전송되는 현상이 발견되어 원인을 추적한 사례
  • tcpdump 분석 결과, 대부분의 패킷이 36바이트 크기의 반복 메시지로 구성되어 있었으며, 약 20ms 간격으로 발생
  • 원인은 2023년 SSH에 추가된 ‘키 입력 타이밍 난독화(keystroke timing obfuscation)’ 기능으로, 사용자의 입력 타이밍을 숨기기 위해 다수의 ‘chaff’ 패킷(SSH2_MSG_PING) 을 전송함
  • 이 기능을 비활성화하거나 서버가 [email protected] 확장을 광고하지 않도록 수정하면 CPU 사용률과 대역폭이 절반 이하로 감소
  • SSH의 보안 기능이 실시간 성능이 중요한 애플리케이션(예: 게임) 에서는 큰 부하로 작용할 수 있음을 보여주는 사례

문제 발견

  • SSH를 통해 실행되는 고성능 게임의 TUI를 테스트하던 중, 단일 키 입력에도 270개의 패킷이 발생하는 현상 확인
    • tcpdump 결과, 66%가 36바이트 메시지, 33%가 TCP ACK, 나머지는 소량의 기타 데이터
    • 평균 90패킷/초, 약 11ms 간격으로 데이터 전송
  • 테스트 중 서버가 “your screen is too small” 메시지만 보내도록 잘못 설정되었는데, 이때 CPU와 대역폭 사용량이 절반으로 감소
    • 게임 데이터가 전송되지 않아야 CPU 사용이 0%에 가까워야 하지만, 여전히 50% 수준 유지
    • 이로 인해 SSH 자체의 통신 오버헤드 가능성 제기

조사 과정

  • tcpdump를 이용해 정상 동작과 오류 상태의 SSH 트래픽을 비교
    • 오류 상태에서도 36바이트 패킷이 20ms 간격으로 지속 발생
    • MacOS 기본 SSH 클라이언트에서도 동일한 패턴 확인
  • Claude Code를 이용해 pcap 파일을 분석한 결과
    • 전체 413,703개 패킷 중 66%가 36바이트, 34%가 0바이트 ACK
    • SSH 클라이언트가 주도적으로 패킷을 생성하고 있었음

근본 원인

  • SSH 디버그 로그(ssh -vvv)에서 다음 메시지 확인
    obfuscate_keystroke_timing: starting: interval ~20ms
    obfuscate_keystroke_timing: stopping: chaff time expired (101 chaff packets sent)
    
    • 20ms 간격수십~백여 개의 chaff 패킷이 실제 관찰된 패턴과 일치
  • 2023년 SSH에 추가된 키 입력 타이밍 난독화 기능이 원인
    • 사용자의 타이핑 속도 패턴이 노출되는 것을 막기 위해 무작위 ‘chaff’ 패킷을 전송
    • 보안에는 유용하지만, 지연(latency) 이 중요한 환경에서는 과도한 부하 발생

해결 방법

  • 클라이언트 측에서 ObscureKeystrokeTiming=no 옵션으로 기능 비활성화 가능
    • 적용 후 CPU 사용률과 대역폭이 크게 감소, 데이터 전송 정상 유지
  • 서버 측 대응을 위해 Go의 SSH 라이브러리에서 [email protected] 확장 광고를 제거
    • 관련 커밋을 되돌린 후 테스트한 결과
      • CPU 사용률 29.9% → 11.6% ,
        시스템 호출 3.10s → 0.66s,
        암호화 연산 1.6s → 0.11s,
        대역폭 6.5Mbit/s → 3Mbit/s
    • 성능이 50% 이상 향상

LLM을 활용한 디버깅 경험

  • Claude Code를 이용해 tcpdump, tshark 분석을 자동화하며 문제 원인을 빠르게 좁힘
    • 명령 실행 과정을 실시간으로 관찰하며 정신적 모델 유지 가능
  • ChatGPT는 SSH의 동작을 “정상”이라 잘못 판단하는 등 모델 간 차이도 경험
  • LLM이 문제 해결의 전 과정을 대체하지는 않지만, 보조 분석 도구로서 높은 효율성을 보임
  • 인간의 추론과 LLM의 분석을 결합해 복잡한 네트워크 성능 문제를 해결한 사례
Hacker News 의견들
  • go의 crypto 라이브러리를 포크하는 건 좀 무섭게 느껴짐
    내 작은 패치를 안전하게 유지할 방법을 고민 중임
    사실 이런 기능은 ssh 라이브러리의 옵션으로 upstream되는 게 맞다고 생각함
    신뢰되지 않은 환경에서는 chaff(잡음) 패킷을 보내는 게 기본값으로 좋지만, 대역폭을 아끼고 싶은 경우도 많음

    • 기능을 광고하지 않는 방식으로 제어하는 건 너무 불안정한 접근법
      서버가 클라이언트에 “필요 없다”는 신호를 보낼 수 있는 옵션을 추가하고, 클라이언트는 이를 수락하거나 경고하도록 하는 게 올바른 해결책임
    • 사실 이미 비슷한 동작이 있음
      TTY 세션에서만 적용되고, 클라이언트가 비활성화할 수 있음
      다만 이번 케이스는 서버가 미리 중요하지 않은 연결임을 알고 있어서 생긴 예외적인 상황임
      대부분의 경우 클라이언트는 ObscureKeystrokeTiming 설정이 지켜지길 기대함
    • 그래도 이 변경은 거절될 가능성이 높다고 봄
      crypto 라이브러리는 매우 의견이 강한 코드베이스라, TLS cipher suite 순서조차 바꿀 수 없게 되어 있음
    • 신뢰된 환경에서도 위협은 존재함
      이건 SSH의 매우 특수한 사용 사례로 보임
      너무 넓게 노출되면 “설정하고 잊는” 상황이 생겨 오히려 보안이 약화될 수 있음
    • 예전엔 1KB RAM의 ZX80을 쓰던 시절이 있었음
      1200bps 모뎀으로 통신하던 때도 있었고, 56K 모뎀은 사실상 과장이었음
      1994년쯤엔 영국 군사대학에서 일하며 WWW를 처음 접했는데, 그땐 “좀 별로네”라고 생각했음
      지금 생각하면 참 시대의 변화가 놀라움
  • obfuscation 기능은 처음 들어봤는데 흥미로웠음
    ssh의 동작을 디버깅할 때 “None” cipher를 패치해서 패킷 내용을 직접 보는 것도 좋은 방법임
    보안이 중요하지 않고 성능이 중요한 터미널 게임이라면 그냥 telnet을 쓰는 것도 고려할 만함

  • SSH가 이런 걸 한다는 걸 몰랐음
    기본값으로 켜져 있는 게 이해는 되지만, 내 환경에서는 끄는 게 맞을 듯함

    1. SSH로 비밀을 직접 타이핑할 일이 거의 없음
    2. 국가 수준의 공격자가 내 키 입력을 sniffing할 이유도 없음
    3. 대륙 간 연결이라 대역폭 절약이 중요함
      그래서 ObscureKeystrokeTiming=no로 설정하려 함. 혹시 이걸 하면 안 되는 이유가 있을까?
    • 낙관적인 보안 태도는 위험함
      (1) 사람이 언제 비밀을 입력하는지 항상 구분하기 어렵고, 활동 전체가 패턴 분석될 수 있음
      (2) 이건 대학 연구실 수준에서도 가능한 공격임 — USENIX 논문연구 사례 참고
      (3) 비디오 트래픽이 지배적인 인터넷에서 키 입력 몇 바이트 절약하려고 보안을 포기하는 건 의미 없음
    • tty SSH 연결에서 자주 입력하는 비밀은 sudo 비밀번호
      공격자가 키 입력 타이밍을 분석하면 명령어와 암호화된 비밀번호 패턴을 추정할 수도 있음
      물론 세션 키가 매번 달라서 복호화는 어렵겠지만, 가능성은 있음
      나도 대부분의 비밀번호는 패스워드 매니저에서 복사해서 붙여넣음
    • 어떤 평문이 유출돼도 공격자에게 쓸모가 없을 거라 확신할 수 없음
      대부분의 사람은 SSH의 보안 기능을 끄고도 아무 문제 없다고 느끼지만, 그건 단지 운이 좋았을 뿐임
      진짜 성능이 필요하면 Telnet, 진짜 보안이 필요하면 ContainerSSH + OAuth2 조합을 쓰는 게 좋음
  • 2004년에 SSH 세션의 키 입력 간 지연 분석으로 명령어를 추정하는 연구를 했었음
    당시 분석 자료 참고
    2023년 패치가 드디어 그 문제를 해결한 셈임

    • HAL2001 해킹 컨퍼런스에서 Dug SongSolar Designer가 SSH 타이밍 분석을 발표하던 게 기억남
      발표 자료
      세월이 정말 빠름
  • Claude가 디버깅에 실제로 도움이 된 건 잘 모르겠음
    작성자가 이미 방향을 알고 있었고, Claude는 그냥 맞장구친 느낌이었음
    Claude가 “Holy Cow!” 같은 말을 하는 건 좀 거슬림

    • 그래도 Rubber Duck Debugging처럼 생각을 정리하는 데 도움을 줬다면 가치가 있음
      나도 Claude로 시스템 동작을 디버깅할 때, 직접적인 답은 없어도 이해를 정리하고 동기 유지에 도움이 됨
      Rubber Duck Debugging 위키
    • Claude는 pcap 필드 추출이나 awk 처리 속도가 나보다 훨씬 빠름
    • AI는 텍스트에서 성격을 감지하는 데 뛰어남
      작성자가 “holy cow” 반응을 좋아해서 블로그에 넣은 걸 보면, Claude가 분위기를 잘 읽은 듯함
    • 개발 도구에 인격을 부여하는 건 좋은 생각이 아니었을지도 모름
  • TCP_CORK을 사용하면 지연 없이 패킷 수를 줄일 수 있음
    TCP_NODELAY를 끄는 것도 방법이지만, 그건 지연 증가라는 대가가 있음

    • TCP_CORK를 처음 들어봤는데 흥미로움
      소켓을 cork하면 커널이 데이터를 버퍼링하다가 uncork하거나 MSS에 도달하면 전송함
      즉, 패킷을 묶어서 전송하는 방식임
      참고 자료
    • TCP_CORK를 몰랐는데 정말 유용해 보임
      ping은 그대로 받겠지만, pong 전송 횟수를 줄일 수 있을 듯함
      TCP_NODELAY는 이미 써봤는데, 지연이 커져서 내 게임엔 맞지 않았음
      이전 HN 글
    • 다만 chaff 패킷이 20ms 간격으로 전송되므로, TCP_CORK가 그걸 묶을 수 있을지는 의문임
      obfuscation 목적상 지연 합치기(coalescing) 는 불가능할 듯함
  • “The smoking gun!” 표현이 웃겼음
    영어 원어민이 아닌데 Claude가 자주 써서 처음 배웠음
    이제는 진짜 유행어처럼 퍼지고 있음

  • LLM 의존이 아쉬움
    이건 그냥 Wireshark로 패킷 캡처를 보면 더 빨리 해결됐을 듯함
    SSH dissector가 꽤 성숙함

    • 나도 LLM을 좋아하진 않지만, Wireshark로 SSH 패킷을 보면 대부분 암호화된 패킷뿐이라 유용한 정보가 없음
      tcpdump로 한 키 입력만 캡처해도 수백 개의 암호화된 패킷이 나옴
      결국 LLM 덕분에 작성자가 흥미로운 걸 배우고 공유했으니 의미 있었음
    • SSH dissector는 완벽하지 않음
      NEWKEYS 메시지 이후엔 파싱이 안 되고, none 암호화로 패치해도 흐름을 완전히 해석하진 못함
      개선 여지는 있음
    • “Wireshark만 보면 됐지”라는 태도는 게이트키핑처럼 들림
      도구를 활용해서 배우는 것도 충분히 가치 있음
    • SSH는 이름부터 보안 프로토콜
      단순 패킷 캡처로는 유의미한 정보를 얻기 어려움
    • 저자는 SSH 패킷 분석기를 몰랐고, 대신 일반 도구(LLM) 를 활용했을 뿐임
      그게 왜 불행한 일인지 모르겠음
  • 2023년에 SSH가 키 입력 타이밍 난독화 기능을 추가했음
    키 입력 속도로 문자를 추정할 수 있어서, SSH가 chaff 패킷을 섞어 공격자가 구분 못 하게 함
    하지만 이건 잘못된 접근 같음
    정말 원한다면 모든 키 입력을 50ms 간격으로 전송하면 됨

    • 50ms 지연은 입력 체감이 매우 불쾌할 것 같음
    • 50ms 간격으로 보낸다는 게 20ms 대신 50ms로 바꾸자는 건지, 아니면 지속적인 일정 간격 전송인지 애매함
      현재 구현은 20ms 단위로 묶되, 일정 시간 입력이 없으면 chaff 전송을 멈추는 방식임
  • SSH의 핵심은 보안이지만, 보안이 필요 없다면 왜 SSH를 쓰는지 의문임
    예를 들어 netcat(nc) 은 대부분의 플랫폼에 기본 설치되어 있음

    • “보안이 1순위”라고 해서 그게 전부는 아님
      SSH에는 성능, 편의성 등 다른 고려사항도 있음
      작성자는 단지 키 입력 난독화(privacy) 기능이 불필요하다고 한 것뿐임
      여전히 암호화나 무결성 보장은 유지하고 싶을 수 있음
      즉, SSH의 보안 기능 대부분은 그대로 두되 일부만 끄는 선택임
    • Windows에도 이제 SSH가 포함되어 있어서, “모든 플랫폼에 nc가 있다”는 말은 정확하지 않음