9 điểm bởi GN⁺ 2026-01-23 | 1 bình luận | Chia sẻ qua WhatsApp
  • Một trường hợp lần theo nguyên nhân khi phát hiện hiện tượng truyền hàng trăm gói tin chỉ với một lần nhấn phím trong phiên SSH
  • Kết quả phân tích bằng tcpdump cho thấy phần lớn gói tin là các thông điệp lặp lại có kích thước 36 byte, xuất hiện với khoảng cách khoảng 20ms
  • Nguyên nhân là tính năng “làm rối thời điểm gõ phím” (keystroke timing obfuscation) được thêm vào SSH từ năm 2023, gửi nhiều gói “chaff” (SSH2_MSG_PING) để che giấu thời điểm người dùng nhập liệu
  • Khi tắt tính năng này hoặc sửa để máy chủ không quảng bá phần mở rộng [email protected], mức sử dụng CPU và băng thông giảm xuống còn chưa đến một nửa
  • Đây là ví dụ cho thấy một tính năng bảo mật của SSH có thể trở thành gánh nặng lớn trong các ứng dụng đòi hỏi hiệu năng thời gian thực, chẳng hạn như game

Phát hiện vấn đề

  • Trong lúc thử nghiệm TUI của một trò chơi hiệu năng cao chạy qua SSH, đã xác nhận hiện tượng 270 gói tin phát sinh chỉ với một lần nhấn phím
    • Kết quả tcpdump: 66% là thông điệp 36 byte, 33% là TCP ACK, phần còn lại là một lượng nhỏ dữ liệu khác
    • Trung bình 90 gói/giây, dữ liệu được truyền cách nhau khoảng 11ms
  • Trong quá trình thử nghiệm, máy chủ bị cấu hình sai nên chỉ gửi thông báo “your screen is too small”, và khi đó mức sử dụng CPU và băng thông giảm còn một nửa
    • Dù dữ liệu game lẽ ra không được truyền thì mức dùng CPU phải gần 0%, nhưng vẫn duy trì quanh 50%
    • Từ đó đặt ra khả năng có overhead truyền thông từ chính SSH

Quá trình điều tra

  • Dùng tcpdump để so sánh lưu lượng SSH giữa trạng thái hoạt động bình thường và trạng thái lỗi
    • Ngay cả trong trạng thái lỗi, các gói 36 byte vẫn tiếp tục xuất hiện đều đặn mỗi 20ms
    • Cùng một mẫu cũng được xác nhận trên SSH client mặc định của MacOS
  • Kết quả phân tích file pcap bằng Claude Code cho thấy
    • Trong tổng số 413.703 gói tin, 66% là 36 byte và 34% là ACK 0 byte
    • Chính SSH client là bên chủ động tạo ra các gói tin này

Nguyên nhân gốc rễ

  • Trong log debug của SSH (ssh -vvv) xuất hiện các thông báo sau
    obfuscate_keystroke_timing: starting: interval ~20ms
    obfuscate_keystroke_timing: stopping: chaff time expired (101 chaff packets sent)
    
    • Khoảng cách 20msvài chục đến hơn một trăm gói chaff khớp với mẫu quan sát thực tế
  • Nguyên nhân là tính năng làm rối thời điểm gõ phím được thêm vào SSH từ năm 2023
    • Để ngăn lộ mẫu tốc độ gõ của người dùng, hệ thống gửi các gói “chaff” ngẫu nhiên
    • Hữu ích về mặt bảo mật, nhưng trong môi trường mà độ trễ (latency) là yếu tố quan trọng thì lại gây tải quá lớn

Cách khắc phục

  • Ở phía client, có thể tắt tính năng này bằng tùy chọn ObscureKeystrokeTiming=no
    • Sau khi áp dụng, mức dùng CPU và băng thông giảm mạnh, trong khi việc truyền dữ liệu vẫn diễn ra bình thường
  • Ở phía máy chủ, để xử lý vấn đề, phần quảng bá phần mở rộng [email protected] đã bị loại bỏ khỏi thư viện SSH của Go
    • Kết quả thử nghiệm sau khi hoàn tác commit liên quan:
      • Mức sử dụng CPU 29.9% → 11.6%,
        system call 3.10s → 0.66s,
        tính toán mã hóa 1.6s → 0.11s,
        băng thông 6.5Mbit/s → 3Mbit/s
    • Hiệu năng cải thiện hơn 50%

Trải nghiệm gỡ lỗi với LLM

  • Dùng Claude Code để tự động hóa phân tích tcpdumptshark, giúp nhanh chóng thu hẹp nguyên nhân vấn đề
    • Có thể quan sát quá trình chạy lệnh theo thời gian thực để duy trì mô hình tư duy
  • ChatGPT lại từng đánh giá sai rằng hành vi của SSH là “bình thường”, cho thấy sự khác biệt giữa các mô hình
  • LLM không thay thế toàn bộ quá trình giải quyết vấn đề, nhưng cho thấy hiệu quả cao như một công cụ phân tích hỗ trợ
  • Đây là một trường hợp kết hợp suy luận của con người với phân tích của LLM để giải quyết vấn đề hiệu năng mạng phức tạp

1 bình luận

 
GN⁺ 2026-01-23
Ý kiến Hacker News
  • Việc fork thư viện crypto của Go nghe có phần đáng ngại
    Tôi đang nghĩ cách để giữ cho bản vá nhỏ của mình an toàn
    Thực ra tôi nghĩ kiểu tính năng này nên được đưa upstream thành một tùy chọn của thư viện ssh
    Trong môi trường không đáng tin cậy, việc gửi các gói chaff (gói nhiễu) làm mặc định là hợp lý, nhưng cũng có nhiều trường hợp muốn tiết kiệm băng thông

    • Điều khiển theo cách không công khai quảng bá tính năng là một cách tiếp cận quá mong manh
      Giải pháp đúng là thêm một tùy chọn để máy chủ có thể báo cho máy khách rằng “không cần cái này”, còn máy khách thì có thể chấp nhận hoặc cảnh báo
    • Thực ra đã có hành vi tương tự rồi
      Nó chỉ áp dụng cho phiên TTY, và máy khách có thể tắt đi
      Chỉ là trường hợp lần này khá ngoại lệ vì máy chủ biết trước đây là một kết nối không quan trọng
      Trong đa số trường hợp, máy khách sẽ kỳ vọng thiết lập ObscureKeystrokeTiming được tôn trọng
    • Dù vậy tôi vẫn nghĩ thay đổi này nhiều khả năng sẽ bị từ chối
      Thư viện crypto là một codebase rất thiên về quan điểm, đến mức ngay cả thứ tự TLS cipher suite cũng không cho đổi
    • Ngay cả trong môi trường đáng tin cậy thì vẫn có mối đe dọa
      Đây có vẻ là một trường hợp sử dụng rất đặc thù của SSH
      Nếu phơi ra quá rộng, rất dễ dẫn đến kiểu “cấu hình rồi quên”, khiến bảo mật còn yếu đi
    • Đã có thời tôi dùng ZX80 với 1KB RAM
      Cũng từng truyền thông qua modem 1200bps, còn modem 56K thì thực ra bị thổi phồng khá nhiều
      Khoảng năm 1994 tôi làm ở một học viện quân sự tại Anh và lần đầu tiếp xúc với WWW, lúc đó còn nghĩ “cũng thường thôi”
      Nghĩ lại bây giờ mới thấy thời thế đổi thay thật đáng kinh ngạc
  • Đây là lần đầu tôi nghe về tính năng obfuscation này, khá thú vị
    Khi debug cách ssh hoạt động, vá None cipher để xem trực tiếp nội dung gói tin cũng là một cách hay
    Nếu là một trò chơi terminal mà bảo mật không quan trọng còn hiệu năng mới là ưu tiên, thì dùng telnet cũng đáng cân nhắc

  • Tôi không biết SSH lại làm chuyện này
    Tôi hiểu vì sao nó được bật mặc định, nhưng trong môi trường của tôi có lẽ nên tắt đi

    1. Tôi hầu như không bao giờ trực tiếp gõ bí mật qua SSH
    2. Cũng chẳng có lý do gì để một tác nhân cấp quốc gia đi sniffing phím gõ của tôi
    3. Đây là kết nối xuyên lục địa nên tiết kiệm băng thông là quan trọng
      Vì vậy tôi định đặt ObscureKeystrokeTiming=no. Có lý do gì khiến tôi không nên làm vậy không?
    • Thái độ lạc quan với bảo mật là nguy hiểm
      (1) Không phải lúc nào con người cũng phân biệt được khi nào mình đang nhập bí mật, và toàn bộ hoạt động có thể bị phân tích mẫu
      (2) Đây là kiểu tấn công mà ngay cả mức phòng thí nghiệm đại học cũng làm được — xem bài báo USENIXca nghiên cứu
      (3) Trên một Internet mà traffic video chiếm áp đảo, hy sinh bảo mật chỉ để tiết kiệm vài byte từ phím gõ là không có ý nghĩa gì
    • Bí mật hay được nhập nhất trên kết nối tty SSH là mật khẩu sudo
      Nếu kẻ tấn công phân tích timing phím gõ, họ có thể suy đoán lệnh và mẫu của mật khẩu đã mã hóa
      Tất nhiên khóa phiên thay đổi mỗi lần nên việc giải mã là khó, nhưng khả năng đó vẫn tồn tại
      Tôi cũng dán phần lớn mật khẩu từ trình quản lý mật khẩu
    • Không thể chắc rằng bất kỳ plaintext bị lộ nào cũng sẽ vô dụng với kẻ tấn công
      Đa số mọi người thấy mình tắt các tính năng bảo mật của SSH mà vẫn chẳng có vấn đề gì, nhưng đó chỉ là vì may mắn
      Nếu thực sự cần hiệu năng thì dùng Telnet, còn nếu thực sự cần bảo mật thì nên dùng tổ hợp ContainerSSH + OAuth2
  • Năm 2004 tôi từng nghiên cứu phân tích độ trễ giữa các lần gõ phím trong phiên SSH để suy đoán lệnh
    Xem tài liệu phân tích khi đó
    Bản vá năm 2023 rốt cuộc đã giải quyết vấn đề đó

    • Tôi còn nhớ ở hội nghị hack HAL2001, Dug SongSolar Designer đã trình bày về phân tích timing SSH
      Tài liệu trình bày
      Thời gian trôi thật nhanh
  • Tôi không chắc Claude thực sự có giúp được gì nhiều cho việc debug
    Có vẻ tác giả đã biết sẵn hướng đi rồi, còn Claude chỉ như phụ họa theo
    Việc Claude nói kiểu “Holy Cow!” hơi gây khó chịu

    • Nhưng nếu nó giúp sắp xếp suy nghĩ như Rubber Duck Debugging thì vẫn có giá trị
      Tôi cũng dùng Claude khi debug cách hệ thống hoạt động; dù không có câu trả lời trực tiếp, nó vẫn giúp sắp xếp hiểu biết và giữ động lực
      Rubber Duck Debugging wiki
    • Claude trích xuất trường pcap hay xử lý awk nhanh hơn tôi rất nhiều
    • AI rất giỏi trong việc nhận ra tính cách từ văn bản
      Việc tác giả thích phản ứng kiểu “holy cow” và đưa nó vào blog cho thấy Claude đã bắt đúng không khí
    • Có lẽ gán nhân cách cho công cụ phát triển chưa hẳn là ý hay
  • Dùng TCP_CORK có thể giảm số gói tin mà không làm tăng độ trễ
    Tắt TCP_NODELAY cũng là một cách, nhưng cái giá phải trả là độ trễ tăng lên

    • Tôi mới nghe về TCP_CORK lần đầu, khá thú vị
      Khi cork socket, kernel sẽ buffer dữ liệu rồi chỉ gửi khi uncork hoặc khi đạt MSS
      Tức là nó gom nhiều gói lại để gửi
      Tài liệu tham khảo
    • Trước giờ tôi không biết TCP_CORK, nhưng trông thật sự hữu ích
      Có lẽ vẫn nhận ping bình thường, nhưng có thể giảm số lần gửi pong
      Tôi đã thử TCP_NODELAY rồi, nhưng độ trễ tăng lên nên không hợp với game của tôi
      Bài HN trước đó
    • Nhưng vì các gói chaff được gửi cách nhau 20ms nên tôi không chắc TCP_CORK có gom chúng lại được không
      Vì mục đích obfuscation, chuyện gộp trễ (coalescing) có lẽ là không thể
  • Cụm “The smoking gun!” nghe buồn cười thật
    Tôi không phải người bản ngữ tiếng Anh, mà Claude hay dùng nên tôi mới học được lần đầu
    Giờ nó thật sự lan ra như một câu cửa miệng

  • Sự phụ thuộc vào LLM hơi đáng tiếc
    Chuyện này có lẽ chỉ cần xem packet capture bằng Wireshark là giải quyết nhanh hơn
    SSH dissector của nó khá trưởng thành

    • Tôi cũng không thích LLM lắm, nhưng nhìn gói SSH trong Wireshark thì phần lớn chỉ là gói đã mã hóa, không có nhiều thông tin hữu ích
      Chỉ cần bắt một lần gõ phím bằng tcpdump thôi cũng ra hàng trăm gói mã hóa
      Dù sao thì nhờ LLM mà tác giả học được điều thú vị rồi chia sẻ lại, như vậy cũng đáng giá
    • SSH dissector không hoàn hảo
      Sau thông điệp NEWKEYS thì nó không parse được nữa, và kể cả khi vá sang mã hóa none thì cũng không diễn giải hoàn toàn luồng dữ liệu
      Vẫn còn chỗ để cải thiện
    • Thái độ kiểu “chỉ cần xem Wireshark là xong” nghe như gatekeeping
      Học hỏi bằng cách tận dụng công cụ cũng hoàn toàn có giá trị
    • Ngay từ tên gọi, SSH đã là một giao thức bảo mật
      Chỉ bắt gói đơn thuần thì rất khó thu được thông tin có ý nghĩa
    • Tác giả không biết về trình phân tích gói SSH, nên chỉ dùng công cụ phổ thông (LLM) thay thế
      Tôi không hiểu vì sao đó lại là điều đáng buồn
  • Năm 2023, SSH đã thêm tính năng làm rối timing phím gõ
    Vì có thể suy đoán ký tự từ tốc độ gõ, SSH trộn thêm gói chaff để kẻ tấn công không phân biệt được
    Nhưng tôi thấy đây là cách tiếp cận sai
    Nếu thật sự muốn, chỉ cần gửi mọi lần gõ phím theo khoảng 50ms là được

    • Độ trễ 50ms có vẻ sẽ rất khó chịu khi nhập liệu
    • Không rõ “gửi theo khoảng 50ms” là ý đổi từ 20ms sang 50ms, hay là gửi liên tục theo khoảng cố định
      Cách triển khai hiện tại là gom theo đơn vị 20ms, rồi nếu một lúc không có nhập liệu thì dừng gửi chaff
  • Cốt lõi của SSH là bảo mật, nhưng nếu không cần bảo mật thì tôi thắc mắc vì sao còn dùng SSH
    Ví dụ netcat(nc) được cài sẵn trên hầu hết nền tảng

    • Việc “bảo mật là ưu tiên số một” không có nghĩa đó là tất cả
      SSH còn có những cân nhắc khác như hiệu năng, sự tiện lợi, v.v.
      Tác giả chỉ nói rằng tính năng làm rối phím gõ (privacy) là không cần thiết mà thôi
      Họ vẫn có thể muốn giữ mã hóa hay đảm bảo tính toàn vẹn
      Tức là giữ nguyên phần lớn tính năng bảo mật của SSH và chỉ tắt một phần
    • Giờ Windows cũng đã có SSH đi kèm, nên nói rằng “mọi nền tảng đều có nc” là không chính xác