प्रश्न (TL, DR)
दूरस्थ अग्रेषण (उर्फ -Rविकल्प) के लिए गतिशील रूप से बंदरगाहों को असाइन करते समय, दूरस्थ मशीन पर एक स्क्रिप्ट (उदाहरण के लिए खट्टे से .bashrc) कैसे निर्धारित कर सकती है कि ओपनएसएसएच द्वारा किन बंदरगाहों को चुना गया था?
पृष्ठभूमि
मैं अपने केंद्रीय सर्वर से कनेक्ट करने के लिए ओपनएसएसएच (दोनों छोर पर) का उपयोग करता हूं, जिसे मैं कई अन्य उपयोगकर्ताओं के साथ साझा करता हूं। अपने दूरस्थ सत्र के लिए (अभी के लिए) मैं एक्स, कप और पल्सेडियो को आगे करना चाहूंगा।
-Xविकल्प का उपयोग करते हुए सबसे तुच्छ X अग्रेषित कर रहा है। आवंटित एक्स पता पर्यावरण चर में संग्रहीत किया जाता है DISPLAYऔर इससे मैं ज्यादातर मामलों में, वैसे भी टीसीपी पोर्ट को निर्धारित कर सकता हूं। लेकिन मुझे शायद ही कभी ज़रूरत पड़े, क्योंकि ज़लीब सम्मान DISPLAY।
मुझे कप और पल्सीडियो के लिए एक समान तंत्र की आवश्यकता है। दोनों सेवाओं के लिए मूल बातें, पर्यावरण चर के रूप में CUPS_SERVERऔर PULSE_SERVERक्रमशः मौजूद हैं। यहाँ उपयोग उदाहरण हैं:
ssh -X -R12345:localhost:631 -R54321:localhost:4713 datserver
export CUPS_SERVER=localhost:12345
lowriter #and I can print using my local printer
lpr -P default -o Duplex=DuplexNoTumble minutes.pdf #printing through the tunnel
lpr -H localhost:631 -P default -o Duplex=DuplexNoTumble minutes.pdf #printing remotely
mpg123 mp3s/van_halen/jump.mp3 #annoy co-workers
PULSE_SERVER=localhost:54321 mpg123 mp3s/van_halen/jump.mp3 #listen to music through the tunnel
समस्या सेटिंग CUPS_SERVERऔर PULSE_SERVERसही ढंग से है।
हम पोर्ट फ़ॉरवर्डिंग का बहुत अधिक उपयोग करते हैं और इसलिए मुझे डायनेमिक पोर्ट एलोकेशन की आवश्यकता है। स्थैतिक पोर्ट आवंटन एक विकल्प नहीं हैं।
OpenSSH में 0दूरस्थ अग्रेषण ( -Rविकल्प) के लिए बाइंड-पोर्ट के रूप में निर्दिष्ट करके, दूरस्थ सर्वर पर गतिशील पोर्ट आवंटन के लिए एक तंत्र है । निम्न आदेश का उपयोग करके, OpenSSH गतिशील रूप से कप और पल्स अग्रेषण के लिए पोर्ट आवंटित करेगा।
ssh -X -R0:localhost:631 -R0:localhost:4713 datserver
जब मैं उस कमांड का उपयोग करता हूं, sshतो निम्न को प्रिंट करेगा STDERR:
Allocated port 55710 for remote forward to 127.0.0.1:4713
Allocated port 41273 for remote forward to 127.0.0.1:631
वहाँ जानकारी मैं चाहता हूँ! अंततः मैं उत्पन्न करना चाहता हूँ:
export CUPS_SERVER=localhost:41273
export PULSE_SERVER=localhost:55710
हालाँकि "आवंटित पोर्ट ..." संदेश मेरे स्थानीय मशीन पर बनाए जाते हैं और भेजे जाते हैं STDERR, जिन्हें मैं दूरस्थ मशीन पर एक्सेस नहीं कर सकता। अजीब तरह से ओपनएसएसएच के पास पोर्ट फ़ॉरवर्डिंग के बारे में जानकारी प्राप्त करने के साधन नहीं हैं।
मुझे उस जानकारी को कैसे प्राप्त करना है जो इसे शेल स्क्रिप्ट में डालने के लिए पर्याप्त रूप से सेट किया गया है CUPS_SERVERऔर PULSE_SERVERदूरस्थ होस्ट पर?
अंतिम छोर
एकमात्र आसान चीज जो मुझे मिल सकी, sshdजब तक कि लॉग से जानकारी को पढ़ा नहीं जा सकता है , तब तक वर्बोसिटी बढ़ रही थी । यह व्यवहार्य नहीं है क्योंकि यह जानकारी गैर-रूट उपयोगकर्ताओं द्वारा सुलभ बनाने के लिए समझदार होने की तुलना में बहुत अधिक जानकारी का खुलासा करती है।
मैं ओपनएसएसएच को एक अतिरिक्त एस्केप सीक्वेंस का समर्थन करने के बारे में सोच रहा था जो आंतरिक संरचना का एक अच्छा प्रतिनिधित्व करता है permitted_opens, लेकिन यहां तक कि अगर मैं चाहता हूं, तो मैं अभी भी क्लाइंट साइड सीक्वेंस को सर्वर साइड से एक्सेस करने की स्क्रिप्ट नहीं कर सकता।
इसके लिए अवश्य ही एक बेहतर तरीका होना चाहिए
निम्नलिखित दृष्टिकोण बहुत अस्थिर लगता है और प्रति उपयोगकर्ता एक ऐसे SSH सत्र तक सीमित है। हालाँकि, मुझे कम से कम दो समवर्ती ऐसे सत्र और अन्य उपयोगकर्ताओं की आवश्यकता है। लेकिन मैंने कोशिश की ...
जब तारों को ठीक से संरेखित किया जाता है, तो एक चिकन या दो का बलिदान करने के बाद, मैं इस तथ्य का दुरुपयोग कर सकता हूं जो sshdमेरे उपयोगकर्ता के रूप में शुरू नहीं हुआ है, लेकिन ऐसा करने के लिए सफल लॉगिन के बाद विशेषाधिकार छोड़ देता है:
सभी सुनने वाले सॉकेट के लिए पोर्ट नंबरों की एक सूची प्राप्त करें जो मेरे उपयोगकर्ता के हैं
netstat -tlpen | grep ${UID} | sed -e 's/^.*:\([0-9]\+\) .*$/\1/'सभी श्रवण सॉकेट के लिए पोर्ट संख्याओं की एक सूची प्राप्त करें जो मेरे उपयोगकर्ता द्वारा शुरू की गई प्रक्रियाओं से संबंधित हैं
lsof -u ${UID} 2>/dev/null | grep LISTEN | sed -e 's/.*:\([0-9]\+\) (LISTEN).*$/\1/'सभी पोर्ट जो पहले सेट में हैं, लेकिन दूसरे सेट में मेरे फॉरवर्डिंग पोर्ट होने की उच्च संभावना नहीं है, और वास्तव में सेट पैदावार घटाना
41273,55710और6010; कप, पल्स और एक्स, क्रमशः।6010एक्स पोर्ट का उपयोग कर के रूप में पहचाना जाता हैDISPLAY।41273कप पोर्ट है, क्योंकिlpstat -h localhost:41273 -aरिटर्न0।55710पल्स पोर्ट है, क्योंकिpactl -s localhost:55710 statरिटर्न0। (यह मेरे क्लाइंट के होस्टनाम को भी प्रिंट करता है!)
(सेट सबट्रेक्ट I करने के लिए sort -uऔर उपरोक्त कमांड लाइनों से आउटपुट को स्टोर commकरने के लिए और सबस्टेशन को करने के लिए उपयोग करें।)
पल्सीडियो मुझे क्लाइंट को पहचानने की अनुमति देता है और, सभी इरादों और उद्देश्यों के लिए, यह SSH सत्रों को अलग करने के लिए एक लंगर के रूप में काम कर सकता है जिसे अलग करने की आवश्यकता होती है। हालाँकि, मुझे टाई करने का तरीका नहीं मिला है 41273, 55710और 6010उसी sshdप्रक्रिया को। netstatगैर-रूट उपयोगकर्ताओं के लिए उस जानकारी का खुलासा नहीं करेंगे। मुझे केवल -उस PID/Program nameकॉलम में एक जगह मिलती है जहाँ मैं 2339/54(इस विशेष उदाहरण में) पढ़ना चाहूंगा । बहुत करीब ...
netstatआप उन प्रक्रियाओं के लिए PID नहीं दिखाएंगे जो आपके पास नहीं हैं या जो कर्नेल-स्थान हैं। उदाहरण के लिए