SSH हर key input पर 100 packets क्यों भेजता है
(eieio.games)- SSH session में एक single key input पर सैकड़ों packets transmit होने की घटना मिली, और उसके कारण को trace किया गया
tcpdumpanalysis में पाया गया कि ज़्यादातर packets 36-byte size के repeating messages थे, जो लगभग 20ms के interval पर हो रहे थे- कारण 2023 में SSH में जोड़ा गया 'keystroke timing obfuscation' feature था, जो user के input timing को छिपाने के लिए कई 'chaff' packets (SSH2_MSG_PING) भेजता है
- इस feature को disable करने पर, या server को
[email protected]extension advertise न करने के लिए बदलने पर CPU usage और bandwidth आधे से भी कम हो गए - यह एक उदाहरण है कि SSH के security features real-time performance महत्वपूर्ण applications (जैसे gaming) में बड़ा overhead बन सकते हैं
समस्या का पता चलना
- SSH के जरिए चलने वाले high-performance game के TUI को test करते समय पाया गया कि एक single key input पर भी 270 packets बन रहे थे
tcpdumpके अनुसार, 66% packets 36-byte messages थे, 33% TCP ACK थे, और बाकी थोड़ा-बहुत अन्य data था- औसतन 90 packets/second, यानी लगभग 11ms interval पर data transmission हो रहा था
- Test के दौरान server ग़लती से केवल “your screen is too small” message भेजने के लिए सेट था, और इस स्थिति में CPU और bandwidth usage आधा हो गया
- Game data transmit नहीं होना चाहिए था, इसलिए CPU usage लगभग 0% के पास होना चाहिए था, लेकिन फिर भी लगभग 50% बना रहा
- इससे SSH के अपने communication overhead की संभावना सामने आई
जांच की प्रक्रिया
tcpdumpका उपयोग करके normal operation और error state के SSH traffic की तुलना की गई- Error state में भी 36-byte packets 20ms interval पर लगातार आते रहे
- macOS के default SSH client में भी वही pattern मिला
- Claude Code से pcap files का analysis करने पर
- कुल 413,703 packets में 66% 36-byte थे, 34% 0-byte ACK थे
- SSH client खुद सक्रिय रूप से packets बना रहा था
मूल कारण
- SSH debug log (
ssh -vvv) में यह message मिलाobfuscate_keystroke_timing: starting: interval ~20ms obfuscate_keystroke_timing: stopping: chaff time expired (101 chaff packets sent)- 20ms interval और दर्जनों से लेकर 100+ chaff packets का यह pattern, वास्तविक observation से मेल खाता था
- कारण 2023 में SSH में जोड़ा गया keystroke timing obfuscation feature था
- User के typing-speed pattern के उजागर होने से बचाने के लिए random 'chaff' packets भेजे जाते हैं
- Security के लिए उपयोगी होने के बावजूद, latency महत्वपूर्ण environments में यह बहुत ज़्यादा overhead पैदा कर सकता है
समाधान
- Client side पर
ObscureKeystrokeTiming=nooption से this feature को disable किया जा सकता है- इसे लागू करने के बाद CPU usage और bandwidth काफ़ी घट गए, जबकि data transmission सामान्य बना रहा
- Server side पर समाधान के लिए Go की SSH library में
[email protected]extension advertisement हटा दिया गया- संबंधित commit को revert करके test करने पर
- CPU usage 29.9% → 11.6% ,
system calls 3.10s → 0.66s,
cryptographic operations 1.6s → 0.11s,
bandwidth 6.5Mbit/s → 3Mbit/s
- CPU usage 29.9% → 11.6% ,
- Performance में 50% से अधिक सुधार हुआ
- संबंधित commit को revert करके test करने पर
LLM का उपयोग करके debugging का अनुभव
- Claude Code की मदद से
tcpdump,tsharkanalysis को automate करते हुए समस्या के कारण को तेज़ी से narrow down किया गया- Commands के execution process को real time में देखते हुए mental model बनाए रखना संभव हुआ
- ChatGPT ने SSH के behavior को “सामान्य” मान लिया, जिससे models के बीच का अंतर भी सामने आया
- LLM पूरे problem-solving process की जगह नहीं लेता, लेकिन supporting analysis tool के रूप में बहुत प्रभावी साबित हुआ
- यह एक ऐसा उदाहरण है जहाँ मानव reasoning और LLM analysis को जोड़कर जटिल network performance समस्या हल की गई
1 टिप्पणियां
Hacker News की टिप्पणियाँ
go की crypto लाइब्रेरी को fork करना थोड़ा डरावना लगता है
मैं सोच रहा हूँ कि अपने छोटे patch को सुरक्षित तरीके से कैसे बनाए रखूँ
असल में मुझे लगता है कि ऐसी functionality को ssh लाइब्रेरी के option के रूप में upstream होना चाहिए
अविश्वसनीय environments में chaff (noise) packets भेजना default रूप में अच्छा है, लेकिन कई बार bandwidth बचाना भी ज़रूरी होता है
सही समाधान यह होगा कि server client को “ज़रूरत नहीं है” का signal भेज सके, और client उसे accept करे या warning दिखाए
यह सिर्फ TTY sessions पर लागू होता है, और client इसे disable कर सकता है
बस इस case में server को पहले से पता है कि connection महत्वपूर्ण नहीं है, इसलिए यह एक असाधारण स्थिति है
ज़्यादातर मामलों में client उम्मीद करेगा कि ObscureKeystrokeTiming setting लागू रहे
crypto लाइब्रेरी बहुत strong opinions वाला codebase है, जहाँ TLS cipher suite का order तक बदलने नहीं दिया जाता
यह SSH का बहुत विशेष use case लगता है
अगर इसे बहुत व्यापक रूप से expose किया गया, तो “set and forget” जैसी स्थिति बन सकती है और उल्टा security कमजोर हो सकती है
1200bps modem पर communication का दौर भी देखा है, और 56K modem तो practically बढ़ा-चढ़ाकर बताया गया था
1994 के आसपास मैं UK military college में काम करते हुए पहली बार WWW से मिला था, और तब सोचा था, “कुछ खास नहीं”
अब सोचता हूँ तो ज़माने का बदलाव वाकई हैरान करता है
मैंने यह obfuscation feature पहली बार सुना, काफ़ी दिलचस्प लगा
ssh के behavior को debug करते समय “None” cipher को patch करके packet contents सीधे देखना भी अच्छा तरीका है
अगर security महत्वपूर्ण नहीं है और performance महत्वपूर्ण है, जैसे किसी terminal game में, तो सीधे telnet इस्तेमाल करने पर भी विचार किया जा सकता है
मुझे पता ही नहीं था कि SSH ऐसा करता है
default रूप में enabled होना समझ में आता है, लेकिन मेरे environment में इसे बंद करना ठीक लगेगा
इसलिए मैं
ObscureKeystrokeTiming=noset करने की सोच रहा हूँ। क्या ऐसा न करने की कोई वजह है?(1) इंसान हमेशा यह स्पष्ट नहीं पहचान पाता कि वह कब secret टाइप कर रहा है, और पूरी activity का pattern analysis किया जा सकता है
(2) यह university lab स्तर पर भी संभव हमला है — USENIX paper और research example देखें
(3) ऐसे internet में जहाँ video traffic हावी है, keystroke के कुछ bytes बचाने के लिए security छोड़ना मायने नहीं रखता
अगर attacker keystroke timing का analysis करे, तो commands और encrypted password pattern का अनुमान लगा सकता है
बेशक session key हर बार बदलती है, इसलिए decryption मुश्किल होगा, लेकिन संभावना तो है
मैं भी ज़्यादातर passwords password manager से copy करके paste करता हूँ
ज़्यादातर लोगों को लगता है कि SSH के security features बंद करके भी कोई समस्या नहीं होगी, लेकिन वह सिर्फ अच्छी किस्मत हो सकती है
अगर सच में performance चाहिए तो Telnet, और अगर सच में security चाहिए तो ContainerSSH + OAuth2 का संयोजन बेहतर है
2004 में मैंने SSH session के keystroke delay analysis से commands का अनुमान लगाने पर research की थी
उस समय की analysis सामग्री देखें
2023 का patch मानो आख़िरकार उसी समस्या का समाधान है
presentation material
वक़्त सच में बहुत तेज़ी से निकल गया
यह स्पष्ट नहीं कि Claude वास्तव में debugging में कितना मददगार था
लेखक को पहले से दिशा पता थी, और Claude बस हामी भरता हुआ लगा
Claude का “Holy Cow!” जैसी बातें कहना थोड़ा चुभता है
मैं भी जब Claude के साथ system behavior debug करता हूँ, तो भले सीधे जवाब न मिलें, लेकिन समझ व्यवस्थित करने और motivation बनाए रखने में मदद मिलती है
Rubber Duck Debugging wiki
लेखक ने “holy cow” वाली प्रतिक्रिया ब्लॉग में डाली, इससे लगता है Claude ने माहौल ठीक से पढ़ लिया था
TCP_CORK इस्तेमाल करने से latency बढ़ाए बिना packet count घटाया जा सकता है
TCP_NODELAY बंद करना भी एक तरीका है, लेकिन उसकी क़ीमत latency बढ़ना है
socket को cork करने पर kernel data को buffer करता है, फिर uncork होने पर या MSS तक पहुँचने पर भेजता है
यानी यह packets को batch करके भेजने का तरीका है
संदर्भ सामग्री
ping तो वैसे ही मिलता रहेगा, लेकिन शायद pong भेजने की संख्या कम की जा सके
TCP_NODELAY मैं पहले इस्तेमाल कर चुका हूँ, लेकिन latency बढ़ने की वजह से यह मेरे game के लिए ठीक नहीं था
पिछली HN पोस्ट
obfuscation के उद्देश्य से coalescing संभव नहीं लगता
“The smoking gun!” अभिव्यक्ति मज़ेदार लगी
मैं native English speaker नहीं हूँ, लेकिन Claude इसे अक्सर इस्तेमाल करता है, इसलिए वहीं से पहली बार सीखी
अब तो यह सचमुच चलन का जुमला बनता जा रहा है
LLM पर निर्भरता थोड़ी निराशाजनक लगी
यह शायद सिर्फ Wireshark में packet capture देखकर ज़्यादा जल्दी हल हो जाता
SSH dissector काफ़ी mature है
tcpdump से सिर्फ एक keystroke capture करो तब भी सैकड़ों encrypted packets मिलते हैं
आख़िरकार LLM की वजह से लेखक ने कुछ दिलचस्प सीखा और साझा किया, इसलिए बात सार्थक रही
NEWKEYS message के बाद parsing नहीं होती, और
noneencryption के लिए patch करने पर भी flow पूरी तरह interpret नहीं होतासुधार की गुंजाइश है
tools का उपयोग करके सीखना भी पूरी तरह मूल्यवान है
सिर्फ packet capture से अर्थपूर्ण जानकारी निकालना आसान नहीं है
इसमें दुख की बात क्या है, समझ नहीं आता
2023 में SSH ने keystroke timing obfuscation feature जोड़ा
typing speed से characters का अनुमान लगाया जा सकता है, इसलिए SSH chaff packets मिलाकर भेजता है ताकि attacker उन्हें अलग न कर सके
लेकिन यह तरीका ग़लत लगता है
अगर सच में ऐसा करना है, तो हर keystroke को 50ms interval पर भेज देना चाहिए
मौजूदा implementation 20ms units में bundle करता है, और कुछ समय तक input न होने पर chaff भेजना बंद कर देता है
SSH का मूल उद्देश्य security है, लेकिन अगर security की ज़रूरत ही नहीं, तो SSH क्यों इस्तेमाल करना चाहिए, यह सवाल बनता है
उदाहरण के लिए netcat(nc) ज़्यादातर platforms पर default रूप में installed होता है
SSH में performance, convenience जैसी दूसरी बातें भी हैं
लेखक बस यह कह रहा था कि keystroke obfuscation (privacy) feature उसके लिए अनावश्यक है
हो सकता है वह encryption या integrity protection फिर भी बनाए रखना चाहता हो
यानी SSH की ज़्यादातर security features चालू रखें, और सिर्फ एक हिस्सा बंद करें