8 मिनट पढ़ें

SSH कनेक्शन multiplexing: कंट्रोल सॉकेट के जोखिम

SSH connection multiplexing किसी task के खत्म होने के बाद भी authenticated access चालू रख सकता है। जानें कि control sockets को अलग कैसे रखें, sessions कैसे बंद करें और evidence कैसे सुरक्षित रखें।

SSH कनेक्शन multiplexing: कंट्रोल सॉकेट के जोखिम

SSH कनेक्शन multiplexing उस कमांड के लौटने के बाद भी किसी होस्ट तक प्रमाणित रास्ता खुला रख सकता है जिसने उसे शुरू किया था। यह व्यवहार जानबूझकर बनाया गया है। फिर भी जब कोई automated task, agent run या deployment job खुद को पूरा बताता है, तो इसे आसानी से गलत समझा जा सकता है।

मैंने टीमों को एक कथित रूप से बंद maintenance window की जाँच करते देखा है और बाद में पता चला कि स्थानीय ssh master अभी भी सक्रिय transport पकड़े हुए था, सॉकेट नए क्लाइंट स्वीकार कर रहा था और अगली कमांड ने बिना दोबारा interactive authentication के उसी transport का इस्तेमाल किया। कुछ असाधारण नहीं हुआ था। कॉन्फ़िगरेशन ने वही किया था जो OpenSSH के दस्तावेज़ में लिखा है। टीम ने shell command के खत्म होने को access के खत्म होने के बराबर मान लिया था।

काम पूरा करने वाली client command और बंद हो चुके authenticated transport के बीच अंतर समझना ज़रूरी है। Multiplexing इन दोनों घटनाओं को अलग कर देता है। अगर आप SSH पर autonomous काम चलाते हैं, तो cleanup और evidence में इस अंतर को शामिल करें।

कंट्रोल सॉकेट उसे खोलने वाली कमांड से अधिक समय तक जीवित रह सकता है

SSH multiplexing एक लंबे समय तक चलने वाले SSH कनेक्शन, जिसे master कहा जाता है, का इस्तेमाल बाद की SSH client प्रक्रियाओं के काम के लिए करता है। OpenSSH के दस्तावेज़ में इन बाद के क्लाइंट को अक्सर slave कहा जाता है। जब slave स्थानीय control socket के ज़रिए master से सफलतापूर्वक संपर्क करता है, तो वह सामान्य connection setup और user authentication दोबारा नहीं करता।

एक सामान्य कॉन्फ़िगरेशन ऐसा दिख सकता है:

Host build-box
    HostName 192.0.2.44
    User deploy
    ControlMaster auto
    ControlPath ~/.ssh/cm/%C
    ControlPersist 20m

पहली ssh build-box नेटवर्क कनेक्शन बनाती है और ~/.ssh/cm/ के अंदर Unix domain socket बनाती है। बाद की कमांड, जैसे ssh build-box 'uname -a', scp और sftp, उस सॉकेट का इस्तेमाल कर सकती हैं। ControlPersist 20m के साथ, आखिरी सत्र बंद होने के बाद भी master बीस मिनट तक उपलब्ध रहता है।

इसलिए यह क्रम सामान्य है:

  1. कोई टास्क ssh build-box 'apply-change' चलाता है और status zero के साथ खत्म होता है।
  2. ControlPersist के कारण master कनेक्टेड रहता है।
  3. उन्नीस मिनट बाद कोई दूसरी स्थानीय प्रक्रिया ssh build-box 'read-status' चलाती है।
  4. वह प्रक्रिया पहले से प्रमाणित transport के ज़रिए चैनल खोलती है।

बाद की कमांड को आपके स्थानीय operating system और सॉकेट permissions अनुमति दे सकते हैं, लेकिन रिमोट होस्ट को नया SSH authentication दिखाई नहीं देता। जो reviewer केवल शुरुआती login record देखता है, वह आसानी से मान सकता है कि activity इससे बहुत पहले खत्म हो गई थी।

OpenSSH के ssh_config manual में ControlMaster को एक नेटवर्क कनेक्शन पर कई सत्र चलाने की सुविधा के रूप में बताया गया है। ControlPersist master को background में चालू रखता है। दोनों बातों को साथ पढ़ें। ControlPersist केवल performance setting नहीं है। यह उस अवधि को बदलता है जिसमें कोई स्थानीय प्रक्रिया प्रमाणित कनेक्शन पर नए चैनल खोलने का अनुरोध कर सकती है।

एक मशीन पर काम करने वाले व्यक्ति के लिए यह समझौता उचित हो सकता है। लेकिन task-scoped automation में इसके लिए स्पष्ट मालिक और स्पष्ट stop action होना चाहिए।

एक authentication event, एक command event नहीं होता

टीमें अक्सर authentication, connection, channel और command को एक ही चीज़ मान लेती हैं। SSH में ये अलग-अलग चीज़ें हैं और multiplexing इस अंतर को सामने लाता है।

शुरुआती master सर्वर से TCP connection बनाता है, host verification करता है, cryptography negotiate करता है और account को authenticate करता है। authenticate होने के बाद वह SSH channels खोल सकता है। Shell command, interactive shell, SFTP transfer, local port forwarding request और remote port forwarding request, सभी उस transport पर channels या channel-संबंधित requests का इस्तेमाल करते हैं।

जब कोई नई स्थानीय ssh invocation इस्तेमाल करने योग्य control socket खोज लेती है, तो वह उसी socket के ज़रिए request भेजती है। Master तय करता है कि माँगा गया channel खोला जाए या नहीं। उसे private key दोबारा नहीं चाहिए। उसे agent prompt दोबारा नहीं चाहिए। सर्वर को दूसरा login attempt भी नहीं मिलता।

इसका अर्थ यह नहीं है कि OpenSSH सॉकेट में दोबारा इस्तेमाल होने वाला password रखता है। यह गलत और अस्पष्ट वर्णन है। असली चिंता पहले से प्रमाणित transport और उसके स्थानीय interface को लेकर है, जिसके ज़रिए उससे काम करने को कहा जा सकता है। जिस attacker को सॉकेट इस्तेमाल करने की अनुमति मिल जाए, उसे मूल credential की ज़रूरत शायद न पड़े।

इस अंतर से incident investigation के सवाल बदल जाते हैं। «क्या key disk पर बनी रही?» महत्वपूर्ण है, लेकिन इससे यह तय नहीं होता कि access बचा रहा या नहीं। इसके बजाय पूछें:

  • क्या master process रिमोट destination से जुड़ा रहा?
  • क्या कोई दूसरी स्थानीय प्रक्रिया उसके control socket तक पहुँच सकती थी?
  • क्या master ने अतिरिक्त sessions, file transfers या forwarding requests स्वीकार कीं?
  • कौन socket owner के रूप में चल सकता था या socket directory में प्रवेश कर सकता था?
  • master वास्तव में कब बंद हुआ?

Task runner द्वारा दी गई command exit code इनमें से किसी सवाल का उत्तर अपने-आप नहीं देता। यह code केवल उस child process का परिणाम बताता है जिसका उसने इंतज़ार किया।

साझा सॉकेट स्थानीय प्रक्रिया की सीमाओं को access की सीमाओं में बदल देते हैं

Control socket एक स्थानीय Unix domain socket होता है। उसका filesystem location और permissions तय करते हैं कि कौन सी स्थानीय प्रक्रियाएँ master से संपर्क करने की कोशिश कर सकती हैं। इसी कारण broad ControlPath अलग-अलग काम को एक साथ जोड़ सकता है, भले ही remote host aliases व्यवस्थित दिखें।

मान लीजिए CI runner account में यह कॉन्फ़िगरेशन है:

Host *
    ControlMaster auto
    ControlPath /tmp/ssh-%r@%h:%p
    ControlPersist 1h

Job A deploy के रूप में app.internal से जुड़ता है। वह master और /tmp में सॉकेट बनाता है। Job A खत्म हो जाता है। उसी स्थानीय account के तहत चलने वाला Job B उसी target से जुड़ता है। अगर वह उस सॉकेट का नाम जानता है और उसे access कर सकता है, तो वह Job A के authenticated transport का इस्तेमाल कर सकता है।

यह तरीका लोकप्रिय है क्योंकि इससे application में लगभग कोई बदलाव किए बिना दोहराई जाने वाली कमांड तेज़ हो जाती हैं। स्वतंत्र jobs के लिए यह गलत है, क्योंकि reuse की सीमा उस job पर नहीं, बल्कि host, port और user पर आधारित होती है जिसके पास authorization है। साझा runner account इस गलती को नियमित cross-task access में बदल देता है।

Directory उतनी ही महत्वपूर्ण है जितनी socket file। Unix systems पर किसी pathname तक पहुँचने के लिए process को directory search permission चाहिए। private ownership और mode 0700 वाली directory में रखा socket साझा temporary directory की तुलना में कहीं स्पष्ट सीमा देता है। Socket की अपनी permissions भी महत्वपूर्ण हैं, लेकिन नियंत्रण को केवल उन्हीं तक सीमित न समझें।

हर task के लिए बनाई गई और executing account के स्वामित्व वाली directory इस्तेमाल करें। Global SSH configuration पर निर्भर हुए बिना shell wrapper से यह किया जा सकता है:

set -eu
run_id="release-4821"
cm_dir="$HOME/.ssh/task-control/$run_id"
mkdir -p "$cm_dir"
chmod 700 "$cm_dir"

socket="$cm_dir/%C"
ssh -o ControlMaster=auto \
    -o ControlPersist=5m \
    -o ControlPath="$socket" \
    build-box 'id && hostname'

%C token लंबे literal नाम से बचाता है और अलग connection parameter sets के बीच collisions घटाता है। OpenSSH का ssh_config manual इसे connection details पर आधारित hash के रूप में परिभाषित करता है। यह उपयोगी है, लेकिन इसमें आपका deployment ticket, agent session या task ID शामिल नहीं होता। इस उदाहरण में parent directory वह missing boundary देती है।

Literal control socket को repository checkout, broadly writable workspace या /tmp में केवल सुविधा के लिए न रखें। ऐसी सुविधा ही स्थानीय socket को अनजाने shared capability में बदलती है।

ControlPersist retention policy है, cleanup plan नहीं

ControlPersist SSH को client sessions बंद होने के बाद master उपलब्ध रखने के लिए कहता है। इसमें yes दिया जा सकता है, जिससे वह background में अनिश्चित समय तक चलता रहे, या 10m जैसा time value दिया जा सकता है। दोनों retention choices हैं।

Client cleanup से पहले crash हो जाए तो timeout मदद करता है। लेकिन यह प्रमाण नहीं देता कि task और access एक ही समय पर खत्म हुए। Timeout के दौरान socket तक पहुँच रखने वाली प्रक्रिया नया काम माँग सकती है। जब deployment task दो मिनट का हो, तब एक घंटे का timeout खास तौर पर उचित ठहराना कठिन है।

कुछ मामलों में छोटा timeout ठीक है। नियंत्रित automation process लगातार कई commands चला सकता है और warm connection से लाभ पा सकता है। ऐसे में timeout को expected idle gap से छोटा रखें, socket को उसी run तक सीमित करें और success path पर master बंद करें। तब timeout सामान्य closure mechanism नहीं, failure fallback का काम करेगा।

ControlPersist yes के लिए access की लंबी अवधि की वजह रखने वाला मालिक चाहिए। Administrator के interactive workstation में ऐसी वजह हो सकती है। Disposable task में नहीं।

एक और आम गलती यह मानना है कि command failure से master बंद हो जाएगा। Failed remote command के बाद shell जल्दी लौट सकती है, जबकि background master चलता रह सकता है। Task cancellation भी ऐसा कर सकती है। Cleanup success, failure और interruption तीनों के बाद चलना चाहिए और यह record करना चाहिए कि shutdown सफल हुआ या नहीं।

अगर automation में trap इस्तेमाल करते हैं, तो cleanup को सीमित रखें और उसके target की पुष्टि करें। पहले socket pathname को अंधाधुंध न हटाएँ। Path हटाने से master process और connection चलते रहने के बावजूद discovery कठिन हो सकती है।

cleanup() {
    ssh -S "$socket" -O exit build-box >/dev/null 2>&1 || true
    rmdir "$cm_dir" 2>/dev/null || true
}
trap cleanup EXIT HUP INT TERM

यह pattern directory हटाने से पहले master से exit करने को कहता है। अगर ssh -O exit विफल हो, तो directory बचाकर रखें और जाँच करें, evidence मिटाएँ नहीं। Production code में failure, process ID और socket path को task record में लिखें।

exit और stop का operational अर्थ अलग है

हर SSH कार्रवाई दर्ज करें
सिर्फ एजेंट रन की शुरुआत नहीं, बल्कि हर SSH कार्रवाई का Activity जर्नल रखें।

OpenSSH ssh -O के ज़रिए control commands देता है। दोनों नाम cleanup जैसे लगते हैं, इसलिए operators अक्सर गलत command चुन लेते हैं।

ssh -O check host पूछता है कि master चल रहा है या नहीं और master उत्तर दे तो उसका process ID बताता है। ssh -O exit host master से exit करने को कहता है। पूरे हो चुके task के लिए सामान्यतः exit ही चाहिए, क्योंकि यह reusable transport को खत्म करता है।

ssh -O stop host master को नए multiplexed sessions स्वीकार करना बंद करने को कहता है। मौजूदा sessions चलते रहते हैं। जब operator active work को धीरे-धीरे पूरा कराना चाहता हो, तब यह उपयोगी है, लेकिन इससे यह दावा पूरा नहीं होता कि task पूरा होते ही सारा SSH access खत्म हो गया। Active channels वाला master अभी भी live network connection रखता है।

जब diagnosis को user की मौजूदा configuration पर निर्भर नहीं बनाना हो, तो socket path साफ़ तौर पर दें:

ssh -S "$socket" -O check build-box
# Master running (pid=41782)

ssh -S "$socket" -O exit build-box
# Exit request sent.

ssh -S "$socket" -O check build-box
# Control socket connect(...): No such file or directory

शब्द और exact error text platform तथा OpenSSH version के अनुसार बदल सकते हैं। इसलिए केवल एक वाक्य को contract मानकर parse न करें, standard output और standard error दोनों capture करें। Evidence का ढाँचा महत्वपूर्ण है: सफल check सक्रिय master की पहचान करता है, सफल exit termination request भेजता है और बाद में विफल check इस दावे को समर्थन देता है कि किसी control socket ने उत्तर नहीं दिया।

एक कठिन स्थिति भी हो सकती है। Master crash होने के बाद socket बच सकता है और checks के बीच PID गायब हो सकता है। पुराना pathname यह साबित नहीं करता कि access अभी मौजूद है। इसके उलट, जाँच से पहले pathname हटा देने पर unresponsive check भी यह साबित नहीं करता कि remote connection खत्म हो गया। कुछ हटाने से पहले process table और खुले Unix sockets देखें।

macOS पर lsof अक्सर सबसे तेज़ स्थानीय inspection tool है:

lsof -nP -U | grep '/.ssh/task-control/'
ps -p 41782 -o pid=,ppid=,lstart=,etime=,command=

Output को task record के साथ रखें। पहली command Unix socket को process से जोड़ती है। दूसरी parentage, start time, elapsed time और invocation details देती है। grep को interactive aid समझें, audit control नहीं। वास्तविक collector को संबंधित records सीधे query करके store करने चाहिए।

Port forwarding idle master को अधिक महत्वपूर्ण बना देता है

जो master idle दिखता है, वह forwarding state रख सकता है या बाद में forwarding request स्वीकार कर सकता है। इसलिए केवल shell commands गिनने से पूरी तस्वीर नहीं मिलती।

Local forwarding ऐसा local listener खोलता है जो SSH connection के ज़रिए traffic भेजता है। Remote forwarding server से listen करने और connections को client के ज़रिए वापस भेजने को कहता है। Dynamic forwarding SOCKS proxy बनाता है। Session और master कैसे चलाए गए हैं, उसके आधार पर इनमें से कोई भी उस command से अधिक समय तक चल सकता है जिसने उसे बनाया था।

OpenSSH manuals multiplexing सक्रिय होने पर forwarding requests के लिए forward और cancel जैसे control commands दर्ज करते हैं। यह operational रूप से उपयोगी है। इसका मतलब यह भी है कि socket तक पहुँच रखने वाली प्रक्रिया साधारण shell command से आगे के network paths माँग सकती है, server policy और master की state के अधीन।

Automated tasks में forwarding को स्पष्ट exception बनाएँ। Bind address, local या remote port, destination host और port तथा cleanup result दर्ज करें। किसी user की broad Host * configuration से LocalForward, RemoteForward या DynamicForward directives को generic SSH wrapper में चुपचाप inherit न होने दें।

Alias पर भरोसा करने से पहले resolved settings देखें:

ssh -G build-box | grep -E '^(controlmaster|controlpath|controlpersist|localforward|remoteforward|dynamicforward) '

ssh -G host matching और defaults लागू होने के बाद effective configuration दिखाता है। इससे एक आम failure पकड़ा जाता है: task simple host alias इस्तेमाल करता है, लेकिन included configuration file task की अपनी configuration से बहुत दूर multiplexing या forwarding सक्षम कर देती है। अलग versions में command अधिक fields दिखा सकती है। अपेक्षित lines ही नहीं, पूरा ssh -G output रखें।

Remote system एक source connection log कर सकता है, जबकि कई forwarded application connections उसी के ज़रिए गुजरती हैं। Network telemetry, server SSH logs और task logs इस कहानी के अलग-अलग हिस्सों का उत्तर देते हैं। इनमें से कोई भी दूसरे की जगह नहीं ले सकता।

केवल server logs स्थानीय निर्णयों का पूरा रिकॉर्ड नहीं बना सकते

हर संवेदनशील SSH कॉल को नियंत्रित करें
संवेदनशील SSH कुंजी के हर इस्तेमाल के लिए Touch ID या एक-क्लिक मंज़ूरी ज़रूरी बनाएँ।

Remote SSH server transport और logging configuration में दर्ज channels तथा commands को देखता है। वह भरोसेमंद तरीके से यह नहीं बता सकता कि किस स्थानीय process को control socket इस्तेमाल करने की अनुमति मिली, socket directory किस task की थी, या मूल task खत्म होने के बाद किसी दूसरी स्थानीय प्रक्रिया ने उसे reuse किया या नहीं।

यह server logs की आलोचना नहीं है। वे system के अलग बिंदु पर काम करते हैं। sshd authentication और connection events दर्ज कर सकता है। Forced command wrapper या audit subsystem remote commands दर्ज कर सकता है। ये records उपयोगी हैं, लेकिन default रूप से हर local multiplex client की पहचान नहीं बताते, क्योंकि server सभी channels को एक ही पहले से authenticated transport का हिस्सा देख सकता है।

Boundary के दोनों ओर evidence रखें। एक उपयोगी task record में ये चीज़ें शामिल होनी चाहिए:

  • secrets हटाकर पूरी resolved client configuration, ssh -G से;
  • remote hostname, address, account, host fingerprint result और शुरुआती master PID;
  • control socket path, private parent directory तथा create और exit times;
  • हर remote command, transfer या forwarding operation और उसका exit status;
  • cleanup से पहले check result, exit result और cleanup के बाद process तथा socket inspection।

Directory name और log record में task identifier जोड़ें, हर task के लिए साझा global control socket path में नहीं। Identifier स्थानीय events को जोड़ता है, लेकिन अपने-आप security boundary नहीं बन जाता।

Collection के बाद record को hash या sign करने से बाद में editing का पता लगाने में मदद मिलती है, लेकिन missing events वापस नहीं आते। Lifecycle events होते समय collect करें। Incident के बाद shell history से बनाया गया record कमजोर evidence है, खासकर जब background masters और retries शामिल हों।

Agent-driven work में agent के intent और executed SSH action को अलग रखें। «Deploy version X» intent है। ssh build-box 'sudo systemctl restart api' action है। Socket reuse record बताता है कि action ने नया transport लिया या मौजूदा transport का इस्तेमाल किया। ये अलग audit facts हैं।

Task-scoped sockets cleanup को मालिक देते हैं

छोटे automated work के लिए सुरक्षित pattern सीधा है: हर task के लिए अलग control socket directory रखें, reuse को उसी task तक सीमित करें और task completion report करने से पहले स्पष्ट exit request भेजें।

Practical wrapper का lifecycle स्पष्ट होना चाहिए। वह restrictive permissions वाली directory बनाए, पहली connection से पहले record लिखे, हर command में वही explicit ControlPath इस्तेमाल करे, master बंद करे, परिणाम verify करे और तभी खाली directory हटाए। Remote command सफल होने पर भी जिस task में cleanup verify नहीं हो सका, उसे cleanup failure report करना चाहिए।

यह उदाहरण unique directory का अनुमान लगाने के बजाय mktemp इस्तेमाल करता है:

set -eu
base="$HOME/.ssh/task-control"
mkdir -p "$base"
chmod 700 "$base"
cm_dir=$(mktemp -d "$base/run.XXXXXX")
chmod 700 "$cm_dir"
socket="$cm_dir/%C"

finish() {
    status=$?
    ssh -S "$socket" -O exit build-box >>"$cm_dir/cleanup.log" 2>&1 || \
        printf '%s\n' 'master exit request failed' >>"$cm_dir/cleanup.log"
    ssh -S "$socket" -O check build-box >>"$cm_dir/cleanup.log" 2>&1 || true
    exit "$status"
}
trap finish EXIT HUP INT TERM

ssh -o ControlMaster=auto \
    -o ControlPersist=2m \
    -o ControlPath="$socket" \
    build-box 'deployctl apply release-4821'

छोटी ControlPersist setting उस स्थिति को संभालती है जिसमें process trap चलने से पहले बंद हो जाए। इसे किसी दूसरे task को master reuse करने की अनुमति न समझें। Random directory उस reuse को रोकती है, क्योंकि दूसरे task को पहले task का path पता नहीं होता और वह उसे inherit नहीं करता।

इस sample को अपनाने से पहले एक सुधार करें। Sensitive command arguments, environment values या copied private data को cleanup.log में न लिखें। Audit record में यह बताने के लिए पर्याप्त विवरण होना चाहिए कि किसने क्या किया, लेकिन उसे नया secret store नहीं बनना चाहिए। Arguments को wrapper boundary पर redact करें, जहाँ उनका अर्थ अभी स्पष्ट होता है।

Sallyport SSH actions को अपने bundled stateless sp-ssh helper के ज़रिए चलाता है और SSH keys को agent के सामने रखने के बजाय encrypted vault में रखता है। इससे credential handling की एक आम समस्या दूर होती है, लेकिन teams को फिर भी action boundary स्पष्ट करनी चाहिए और यह record रखना चाहिए कि run कब खत्म हुआ।

Global convenience settings task boundaries को नष्ट कर देती हैं

देखें कि कौन सा एजेंट चला
Sessions जर्नल में एजेंट रन दर्ज करें और चल रहे सत्र को सीधे रद्द करें।

Global Host * stanza किसी account के तहत चलने वाले हर human shell, script, repository और automation child process के लिए multiplexing चालू कर सकती है। जब एक ही account अलग approvals या अलग owners वाले tasks चलाता हो, तो यह बहुत व्यापक है।

Setting Include files, configuration management, developer की personal dotfiles या build image से आ सकती है। Command line भी इसे override कर सकती है। किसी एक दिखाई देने वाली config file से active behavior का अनुमान कभी न लगाएँ। उसी exact host alias और user context के साथ ssh -G चलाएँ जिसका task इस्तेमाल करेगा।

अगर automation environment private control path की गारंटी नहीं दे सकता, तो उस action के लिए multiplexing बंद करें:

ssh -o ControlMaster=no \
    -o ControlPath=none \
    build-box 'maintenancectl status'

इससे हर invocation के लिए नया connection और authentication करना पड़ेगा। High-consequence actions, rare break-glass access या task और trust boundaries पार करने वाले काम के लिए यह अच्छा खर्च है। बार-बार होने वाला authentication अधिक साफ़ authorization event देता है और lifecycle reasoning को कम अस्पष्ट बनाता है।

ControlMaster=auto को यह गारंटी न समझें कि कोई process केवल अपना connection reuse करेगा। auto का मतलब है कि client configured path पर master खोजेगा और न मिलने पर नया बनाएगा। वह किसका connection खोज सकता है, यह configured path तय करता है।

कुछ teams कहती हैं कि shared socket ठीक है क्योंकि उनके सभी jobs एक service account के तहत चलते हैं। यह तर्क तभी सही है जब उस Unix identity वाले हर job को उस account के ज़रिए हर target तक पहुँचने का समान अधिकार हो और team यह स्वीकार करे कि एक job दूसरे job का live transport inherit कर सकता है। अधिकांश mature environments वास्तव में ऐसा नहीं चाहते।

साफ़ task ending के लिए transport closure का प्रमाण चाहिए

अंतिम remote command लौटते ही SSH task को complete घोषित न करें। तब complete घोषित करें जब task ने master बंद करके उसका proof record कर लिया हो, या यह report किया हो कि वह ऐसा नहीं कर सका।

Final record investigator को यह बताना चाहिए कि बाद की command के पास connection reuse करने का कोई रास्ता था या नहीं। उसमें task identity, resolved SSH configuration, socket path, master process details, activity records, explicit control command results और cleanup के बाद का observation होना चाहिए। SSH से स्वतंत्र रूप से जारी रहने वाले remote work, जैसे service restart या detached process, के लिए remote evidence भी रखें।

Operators के लिए दबाव में अपनाई जा सकने वाली standard प्रक्रिया बनाएँ: socket अलग रखें, cleanup से पहले उसका निरीक्षण करें, exit request भेजें, verify करें कि कोई master उत्तर नहीं दे रहा और परिणाम सुरक्षित रखें। यह लंबे default timeout से अधिक उपयोगी है, क्योंकि यह access के बारे में अनुमान को जाँचने योग्य तथ्य में बदल देती है।

जब काम इतना संवेदनशील हो कि बचा हुआ authenticated transport स्वीकार्य न हो, तो shared master से उसे optimize न करें। नया connection खोलें, action करें, उसे बंद करें और record रखें। कुछ अतिरिक्त सेकंड उस स्थिति को समझाने की कीमत से कम हैं जिसमें task खत्म हो जाने के बाद भी access path जीवित रहा।

सामान्य प्रश्न

क्या SSH ControlMaster मेरी कमांड खत्म होने के बाद भी प्रमाणित कनेक्शन चालू रख सकता है?

हाँ। ControlMaster कनेक्शन एक बार प्रमाणीकरण करता है, जिसके बाद SSH के दूसरे क्लाइंट स्थानीय master से नए चैनल खोलने का अनुरोध कर सकते हैं। अगर ControlPersist master को चालू रखता है, तो ये चैनल मूल कमांड और उसे शुरू करने वाले टास्क के समाप्त होने के बाद भी खुल सकते हैं।

SSH master और slave कनेक्शन में क्या अंतर है?

Master प्रक्रिया वह मूल SSH कनेक्शन है जिसके पास नेटवर्क ट्रांसपोर्ट और स्थानीय कंट्रोल सॉकेट होता है। Slave प्रक्रिया बाद में चलने वाली ssh कमांड है, जो उस सॉकेट से संपर्क करके master से सत्र, फ़ॉरवर्डिंग या कोई दूसरा चैनल खोलने को कहती है।

मैं साझा SSH कंट्रोल सॉकेट को सुरक्षित तरीके से कैसे बंद करूँ?

जब आपकी कॉन्फ़िगरेशन host alias को सही ControlPath तक पहुँचाती हो, तब ssh -O exit host-alias चलाएँ। अगर सॉकेट का पथ सीधे बताना हो, तो ssh -S /path/to/socket -O exit host इस्तेमाल करें। पहले -O check से जाँच करें, ताकि ऑपरेटर गलती से गलत कनेक्शन बंद न कर दे।

क्या ऑटोमेशन के लिए SSH multiplexing सुरक्षित है?

यह बार-बार होने वाले प्रमाणीकरण को कम करता है और छोटी SSH कमांड को तेज़ बनाता है। लेकिन जब उसके जीवनकाल का कोई स्पष्ट मालिक न हो, कई अलग-अलग जॉब एक ही सॉकेट डायरेक्टरी साझा करें, या मंज़ूरी की सीमा खत्म होने के बाद भी कोई टास्क चैनल खोल सके, तब यह ऑटोमेशन के लिए असुरक्षित है।

क्या SSH सर्वर लॉग multiplexing से भेजी गई हर कमांड दिखाते हैं?

रिमोट SSH सर्वर अक्सर एक ही ट्रांसपोर्ट लॉगिन दर्ज करता है और बाद की स्थानीय कमांड को नए प्रमाणीकरण इवेंट के रूप में नहीं पहचानता। भरोसेमंद रिकॉर्ड के लिए क्लाइंट प्रक्रिया, multiplexing कॉन्फ़िगरेशन, कंट्रोल सॉकेट का जीवनचक्र और टास्क-स्तरीय कमांड लॉग भी रखें।

क्या मुझे SSH cleanup के लिए ControlPersist timeout पर निर्भर रहना चाहिए?

Timeout अधिकतम प्रतीक्षा अवधि है, यह प्रमाण नहीं कि कनेक्शन टास्क खत्म होते ही बंद हो गया। cleanup में ssh -O exit चलाएँ, फिर पुष्टि करें कि सॉकेट गायब है और ssh -O check विफल होता है। crashed क्लाइंट के लिए timeout उपयोगी fallback बना रहता है।

SSH कंट्रोल सॉकेट कहाँ रखने चाहिए?

कंट्रोल सॉकेट को स्थानीय क्रेडेंशियल की तरह समझें। उसे चलाने वाले अकाउंट के स्वामित्व वाली निजी डायरेक्टरी में रखें, हर टास्क के लिए अलग पथ रखें, साझा temporary डायरेक्टरी से बचें और पुराने पथ हटाने से पहले जाँच लें कि कोई master प्रक्रिया अभी भी उन्हें इस्तेमाल कर रही है या नहीं।

SSH ControlPath में %C का क्या मतलब है?

ControlPath Unix सॉकेट का पथ चुनता है। %C कनेक्शन की विशेषताओं से बना hash इस्तेमाल करता है, जिससे पथ की लंबाई और नामों के टकराव की कई समस्याएँ घटती हैं। लेकिन यह अपने-आप अलग टास्क पहचान नहीं बनाता।

क्या SSH master बंद करने से रिमोट मशीन पर शुरू किया गया काम वापस हो जाता है?

नहीं। multiplexed ट्रांसपोर्ट बंद करने से उस क्लाइंट का प्रमाणित कनेक्शन खत्म होता है, लेकिन रिमोट मशीन पर बदली गई फ़ाइलें वापस नहीं होतीं, detached प्रक्रिया बंद नहीं होती और किसी दूसरे सत्र में इस्तेमाल हो सकने वाले क्रेडेंशियल रद्द नहीं होते। रिमोट काम का cleanup अलग से करें।

ऑटोमेटेड SSH टास्क खत्म होने के बाद हमें कौन सा सबूत रखना चाहिए?

एक दोहराए जा सकने वाले रिकॉर्ड से शुरुआत करें: पूरी तरह resolved SSH कॉन्फ़िगरेशन, master का process ID, सॉकेट पथ, रिमोट गंतव्य, शुरू और खत्म होने का समय और स्पष्ट shutdown कमांड का परिणाम। इसे टास्क के कमांड transcript और रिमोट होस्ट के संबंधित लॉग के साथ रखें।

Sallyport

Sallyport आपके AI एजेंट के लिए API कॉल और SSH कमांड चलाता है। कुंजियाँ आपके Mac पर एक लोकल वॉल्ट में रहती हैं; आप हर रन को स्वीकृत करते हैं और हर क्रिया एक सीलबंद जर्नल में दर्ज होती है।

© 2026 Sallyport · Apache-2.0 के तहत ओपन सोर्स · Oleg Sotnikov