क्या कोई नाम आधारित वर्चुअल होस्ट SSH रिवर्स प्रॉक्सी है?


36

मैं अपने विकास के माहौल में HTTP रिवर्स प्रॉक्सी के काफी शौकीन हो गया हूं और पाया गया कि DNS आधारित वर्चुअल होस्ट रिवर्स प्रॉक्सी काफी उपयोगी है। फ़ायरवॉल पर केवल एक पोर्ट (और मानक एक) खुला होने से प्रबंधन के लिए यह बहुत आसान हो जाता है।

मैं SSH कनेक्शन करने के लिए कुछ इसी तरह की खोज करना चाहता हूं, लेकिन बहुत किस्मत नहीं है। मैं केवल एसएसएच टनलिंग का उपयोग नहीं करना चाहता हूं क्योंकि मानक के अलावा अन्य पोर्ट खोलने की आवश्यकता होती है। क्या ऐसा कुछ है जो ऐसा कर सकता है?

क्या HAProxy ऐसा कर सकता है?


अपने इच्छित अनुप्रयोग फ़ाइल स्थानांतरण, या मेजबान के लिए वास्तविक SSH पहुँच है?
काइल हॉजसन

मेजबान के लिए सीधे एसएसएच पहुंच लक्ष्य है। यह ज़रूरत एक मर्क्यूरियल सर्वर को घर में चलाने की इच्छा से आती है लेकिन हमारा सर्वर फ़ायरवॉल के पीछे है। अभी मैं बस एक HTTP संस्करण की स्थापना पर काम कर रहा हूँ, लेकिन मैं चाहता था कि HTTP के बजाय SSH का उपयोग किया जाए। यदि संभव हो तो अन्य सर्वरों तक सीधे एसएसएच पहुंच एक बोनस होगा।
अहानसन

यह एक ऐसी कष्टप्रद समस्या है।
पक्षपात

मेरी समझ यह है कि HAProxy अब SNI के माध्यम से इसका समर्थन करता है। हालांकि मैं अभी तक इसे प्राप्त करने में सक्षम नहीं हूं।
Carel

जवाबों:


24

मुझे विश्वास नहीं है कि नाम-आधारित SSH कुछ ऐसा है जो संभव होगा कि प्रोटोकॉल कैसे काम करता है।

यहाँ कुछ विकल्प दिए गए हैं।

  • आप मेजबान को सेटअप कर सकते हैं जो कि गेटवे के रूप में कार्य करने के लिए पोर्ट 22 का उत्तर देता है। तब आप ssh सर्वर को कुंजी के आधार पर फॉरवर्ड रिक्वेस्ट को कॉन्फ़िगर कर सकते हैं। कुंजी के साथ SSH गेटवे उदाहरण

  • आप उस होस्ट को प्रॉक्सी के रूप में उपयोग करने के लिए अपने क्लाइंट को समायोजित कर सकते हैं। यही है, यह गेटवे होस्ट के लिए ssh होगा, और फिर आंतरिक होस्ट से संबंध बनाने के लिए उस होस्ट का उपयोग करें। ग्राहक विन्यास के साथ SSH प्रॉक्सी ।

  • आप किनारे पर एक साधारण http प्रॉक्सी भी सेट कर सकते हैं। फिर आने वाले कनेक्शन को अनुमति देने के लिए इसका उपयोग करें। के माध्यम से SSH HTTP प्रॉक्सी

स्पष्ट रूप से उपरोक्त सभी के साथ, सुनिश्चित करें कि आपने ठीक से कॉन्फ़िगर किया है और गेटवे को लॉक करना बहुत महत्वपूर्ण है।


18

मैं पिछले 16 महीनों से इस समस्या का समाधान खोज रहा हूं। लेकिन हर बार जब मैं देखता हूं, तो एसएसएच प्रोटोकॉल के साथ ऐसा करना असंभव लगता है जैसा कि प्रासंगिक आरएफसी में निर्दिष्ट है और प्रमुख कार्यान्वयन द्वारा कार्यान्वित किया जाता है।

हालाँकि यदि आप थोड़ा संशोधित SSH क्लाइंट का उपयोग करने के लिए तैयार हैं और आप प्रोटोकॉल का उपयोग करने के लिए तैयार हैं, जो कि जब वे डिज़ाइन किए गए थे, तब इसका कोई इरादा नहीं था, तो इसे प्राप्त करना संभव है। इस पर अधिक नीचे।

यह क्यों संभव नहीं है

क्लाइंट होस्टनाम को SSH प्रोटोकॉल के हिस्से के रूप में नहीं भेजता है।

यह होस्टनाम को DNS लुकअप के हिस्से के रूप में भेज सकता है, लेकिन इसे कैश किया जा सकता है, और क्लाइंट से रिसॉल्वर के माध्यम से आधिकारिक सर्वर तक प्रॉक्सी को पार नहीं कर सकता है, और भले ही यह विशिष्ट DNS लुकअप के साथ जुड़ने का कोई मजबूत तरीका नहीं है। विशिष्ट SSH ग्राहक।

कुछ भी फैंसी नहीं है जो आप स्वयं एसएसएच प्रोटोकॉल के साथ कर सकते हैं। आपको क्लाइंट से SSH संस्करण का बैनर देखे बिना भी एक सर्वर चुनना होगा। आपको क्लाइंट को एक बैनर भेजना होगा, इससे पहले कि वह प्रॉक्सी को कुछ भी भेजे। सर्वर से बैनर अलग हो सकते हैं, और आपके पास अनुमान लगाने का कोई मौका नहीं है, जो कि उपयोग करने के लिए सही है।

भले ही यह बैनर अनएन्क्रिप्टेड भेजा गया है, आप इसे संशोधित नहीं कर सकते। उस बैनर के प्रत्येक बिट को कनेक्शन सेटअप के दौरान सत्यापित किया जाएगा, जिससे आप लाइन में थोड़ा सा कनेक्शन विफलता का कारण बनेंगे।

मेरे लिए यह निष्कर्ष बहुत स्पष्ट है, इस कनेक्टिविटी कार्य को करने के लिए ग्राहक पक्ष में कुछ बदलना होगा।

अधिकांश वर्कअराउंड्स SSH ट्रैफ़िक को एक अलग प्रोटोकॉल के अंदर एन्क्रिप्ट कर रहे हैं। स्वयं SSH प्रोटोकॉल के अतिरिक्त जोड़ की कल्पना भी कर सकता है, जिसमें क्लाइंट द्वारा भेजे गए संस्करण बैनर में होस्टनाम शामिल है। यह मौजूदा सीवरों के साथ संगत रह सकता है, क्योंकि बैनर का हिस्सा वर्तमान में एक निशुल्क फॉर्म पहचान क्षेत्र के रूप में निर्दिष्ट किया गया है, और हालांकि ग्राहक आमतौर पर सर्वर से अपने स्वयं के भेजने से पहले संस्करण बैनर का इंतजार करते हैं, प्रोटोकॉल क्लाइंट को अपना बैनर भेजने की अनुमति देता है प्रथम। Ssh क्लाइंट के कुछ हालिया संस्करण (उदाहरण के लिए Ubuntu 14.04 पर एक) सर्वर बैनर की प्रतीक्षा किए बिना बैनर भेजता है।

मुझे किसी भी क्लाइंट का पता नहीं है, जिसने इस बैनर में सर्वर के होस्टनाम को शामिल करने के लिए कदम उठाए हैं। मैंने ऐसी सुविधा जोड़ने के लिए OpenSSH मेलिंग सूची में एक पैच भेजा है । लेकिन यह SSH ट्रैफ़िक पर स्नूपिंग करने वाले किसी को भी होस्टनाम प्रकट नहीं करने की इच्छा के आधार पर अस्वीकार कर दिया गया था। चूंकि एक गुप्त होस्टनाम नाम आधारित प्रॉक्सी के संचालन के साथ मौलिक रूप से असंगत है, इसलिए एसएसएच प्रोटोकॉल के लिए आधिकारिक एसएनआई एक्सटेंशन को जल्द ही देखने की उम्मीद न करें।

एक वास्तविक समाधान

मेरे लिए सबसे अच्छा काम करने वाला समाधान वास्तव में IPv6 का उपयोग करना था।

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

एक वर्कअराउंड

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

ssh -o ProxyCommand='ssh -W %h:%p user1@bastion' user2@target

यह काम करने के लिए हैक करने के लिए एक गंदा अगर असली समाधान (IPv6) आपकी पहुंच से बाहर है

जिस हैक के बारे में मैं बताने जा रहा हूं, उसका उपयोग केवल बिल्कुल अंतिम उपाय के रूप में किया जाना चाहिए। इससे पहले कि आप इस हैक का उपयोग करने के बारे में सोचें, मैं दृढ़ता से प्रत्येक सर्वर के लिए एक IPv6 पता प्राप्त करने की सलाह देता हूं, जिसे आप SSH के माध्यम से बाह्य रूप से उपलब्ध होना चाहते हैं। अपने SSH सर्वर तक पहुँचने के लिए अपने प्राथमिक विधि के रूप में IPv6 का उपयोग करें और केवल इस हैक का उपयोग करें जब आपको एक IPH4-only नेटवर्क से SSH क्लाइंट चलाने की आवश्यकता होती है जहाँ आपके पास IPv6 को तैनात करने पर कोई प्रभाव नहीं पड़ता है।

विचार यह है कि क्लाइंट और सर्वर के बीच ट्रैफ़िक को पूरी तरह से वैध एसएसएच ट्रैफ़िक होना चाहिए। लेकिन प्रॉक्सी को केवल होस्टनाम की पहचान करने के लिए पैकेट की धारा के बारे में पर्याप्त समझने की आवश्यकता है। चूंकि SSH होस्टनाम भेजने का एक तरीका परिभाषित नहीं करता है, आप इसके बजाय अन्य प्रोटोकॉल पर विचार कर सकते हैं जो इस तरह की संभावना प्रदान करते हैं।

HTTP और HTTPS दोनों क्लाइंट को सर्वर भेजने से पहले होस्टनाम भेजने की अनुमति देते हैं। अब सवाल यह है कि क्या बाइट्स की एक धारा का निर्माण संभव है जो एसएसएच ट्रैफिक के साथ-साथ HTTP और HTTPS के रूप में मान्य है। HTTP यह बहुत अधिक गैर-स्टार्टर है, लेकिन HTTP संभव है (HTTP की पर्याप्त उदार परिभाषाओं के लिए)।

SSH-2.0-OpenSSH_6.6.1 / HTTP/1.1
$: 
Host: example.com

क्या यह आपको SSH या HTTP जैसा लगता है? यह SSH है और पूरी तरह से RFC के अनुरूप है (कुछ द्विआधारी वर्णों को छोड़कर, SF रेंडरिंग द्वारा थोड़ा सा उलझ गया है)।

SSH संस्करण स्ट्रिंग में एक टिप्पणी क्षेत्र शामिल है, जिसमें ऊपर का मान है / HTTP/1.1। Newline के बाद SSH के पास कुछ बाइनरी पैकेट डेटा है। पहला पैकेट MSG_SSH_IGNOREक्लाइंट द्वारा भेजा गया एक संदेश है और सर्वर द्वारा अनदेखा किया जाता है। पेलोड को नजरअंदाज किया जाता है:

: 
Host: example.com

यदि एक HTTP प्रॉक्सी पर्याप्त रूप से उदार है जो इसे स्वीकार करता है, तो बाइट्स के उसी क्रम की व्याख्या एक HTTP विधि के रूप में की जाएगी SSH-2.0-OpenSSH_6.6.1और इग्निशन संदेश के प्रारंभ में बाइनरी डेटा को HTTP हेडर नाम के रूप में व्याख्या किया जाएगा।

प्रॉक्सी न तो HTTP विधि या पहले हेडर को समझेगा। लेकिन यह Hostहेडर को समझ सकता है , जो बैकएंड को खोजने के लिए इसकी आवश्यकता है।

इसके लिए प्रॉक्सी को काम करने के लिए इस सिद्धांत पर डिज़ाइन करना होगा कि बैकएंड खोजने के लिए केवल पर्याप्त HTTP को समझना होगा, और बैकएंड मिल जाने के बाद प्रॉक्सी को केवल कच्ची बाइट स्ट्रीम पास करनी होगी और वास्तविक समाप्ति को छोड़ना होगा HTTP कनेक्शन का बैकएंड द्वारा किया जाना है।

यह HTTP प्रॉक्सी के बारे में बहुत सारी धारणाएं बनाने के लिए थोड़ा खिंचाव की तरह लग सकता है। लेकिन अगर आप SSH का समर्थन करने के इरादे से विकसित सॉफ्टवेयर का एक नया टुकड़ा स्थापित करने के लिए तैयार थे, तो HTTP प्रॉक्सी की आवश्यकताएं बहुत खराब नहीं हैं।

मेरे स्वयं के मामले में मुझे यह विधि पहले से ही स्थापित प्रॉक्सी पर काम करने के लिए मिली, जिसमें कोड, कॉन्फ़िगरेशन, या अन्यथा कोई परिवर्तन नहीं था। और यह केवल HTTP और कोई SSH को ध्यान में रखते हुए लिखे गए प्रॉक्सी के लिए था।

अवधारणा क्लाइंट और प्रॉक्सी का प्रमाण । (अस्वीकरण कि प्रॉक्सी मेरे द्वारा संचालित एक सेवा है। इस उपयोग का समर्थन करने के लिए किसी अन्य प्रॉक्सी की पुष्टि होने के बाद लिंक को बदलने के लिए स्वतंत्र महसूस करें।)

इस हैक के Caveats

  • इसका उपयोग न करें। वास्तविक समाधान का उपयोग करना बेहतर है, जो कि आईपीवी 6 है।
  • यदि प्रॉक्सी HTTP ट्रैफ़िक को समझने का प्रयास करता है, तो यह निश्चित रूप से टूटने वाला है।
  • एक संशोधित SSH क्लाइंट पर भरोसा करना अच्छा नहीं है।

क्या आप the gateway can use the destination IP address to find out which server to send the packet toआईपीवी 6 समाधान में आपके द्वारा बताए गए अर्थ को विस्तृत कर सकते हैं?
जैकब फोर्ड

@JacobFord उस वाक्य को समझने की कुंजी यह है कि मैं गेटवे शब्द का उपयोग करता हूं प्रॉक्सी नहीं । IPv6 के साथ आपको प्रत्येक होस्ट को एक असाइन करने के लिए पर्याप्त आईपी पते मिलते हैं और अभी भी अतिरिक्त पते हैं। आपके द्वारा प्रॉक्सी के पीछे लगाई गई सभी मशीनों का अपना आईपी पता होगा जो कि आपके नाम का संकल्प है। तो आपको अब प्रॉक्सी की आवश्यकता नहीं है, ग्राहक अपने ट्रैफ़िक को वांछित होस्ट के आईपी पते पर भेजते हैं, और आप सीधे ट्रैफ़िक को वहां रूट कर सकते हैं।
कैस्परर्ड

वर्कअराउंड भाग के लिए, ssh के लिए अपेक्षाकृत नया कमांड स्विच है -J, जिससे आप उपयोग कर सकते हैं: ssh -J user1 @ front user2 @ target
PMN

3

मुझे विश्वास नहीं है कि यह कुछ ऐसा है जो संभव होगा, कम से कम जिस तरह से आपने वर्णित किया है, हालांकि मैं गलत साबित होना पसंद करूंगा। ऐसा नहीं लगता कि क्लाइंट होस्टनाम भेजता है जिसे वह कनेक्ट करना चाहता है (कम से कम स्पष्ट रूप से)। SSH कनेक्शन का पहला चरण एन्क्रिप्शन सेट करना प्रतीत होता है।

इसके अलावा, आपके पास होस्ट कुंजी सत्यापन के साथ समस्याएँ होंगी। SSH क्लाइंट एक IP पते के साथ-साथ एक होस्टनाम के आधार पर कुंजियों का सत्यापन करेगा। आपके पास अलग-अलग कुंजियों के साथ कई होस्टनाम होंगे, लेकिन आप जिस आईपी से जुड़ रहे हैं, वही आईपी।

एक संभावित समाधान एक 'गढ़' मेजबान होगा, जहां ग्राहक उस मशीन में ssh कर सकते हैं, एक सामान्य (या यदि वांछित हो) शेल को प्रतिबंधित कर सकते हैं, और फिर वहां से आंतरिक मेजबान में ssh कर सकते हैं।


गढ़ अवधारणा वह है जो हमारे पास मौजूद है, लेकिन मेरे संस्करण नियंत्रण (अतिरिक्त प्रयास के बिना) के लिए समस्याग्रस्त है।
अहानसन 19

यह बहुत कष्टप्रद है कि ssh fqdn नहीं भेजता है और क्लाइंट की ओर DNS को संभालता है। मुझे लगता है कि लोगों ने सार्वजनिक आईपी ब्लोट और एनएटी के बारे में चिंता नहीं की जब अधिकांश टीसीपी / आईपी एप्लिकेशन स्तर प्रोटोकॉल बनाए गए थे। क्योंकि, गंभीरता से, आपको FQDN आधारित NAT को iptables (यानी कर्नेल फिल्टर) के साथ करने में सक्षम होना चाहिए
पक्षपात

होस्टेक रिवर्स प्रॉक्सी की कुंजी हो सकता है। यदि आप आंतरिक नेटवर्क और मेजबानों पर नियंत्रण रखते हैं, तो बैकएंड की सुरक्षा पर भरोसा करने पर यह एक लाभ है।
rox0r

@bias आप होस्टनाम के आधार पर NAT नहीं कर सकते, भले ही उच्च स्तर का प्रोटोकॉल होस्टनाम भेज दे। इसका कारण यह नहीं किया जा सकता है कि SYN पैकेट प्राप्त होने पर बैकएंड का चुनाव किया जाना चाहिए, लेकिन SYN संसाधित होने के बाद होस्टनाम केवल तभी भेजा जाता है और SYN-ACK वापस कर दिया गया है। हालाँकि आप प्रोटोकॉल के लिए एक बहुत ही पतली एप्लिकेशन लेयर प्रॉक्सी का उपयोग कर सकते हैं जो होस्टनाम भेजती हैं, जैसे कि http और https।
कास्परड

3

ब्लॉक पर एक नया बच्चा है। SSH piper आपके कनेक्शन को पूर्व-निर्धारित उपयोगकर्ता नाम के आधार पर रूट करेगा, जिसे आंतरिक होस्ट में मैप किया जाना चाहिए। रिवर्स-प्रॉक्सी के संदर्भ में यह सबसे अच्छा समाधान है।

जीथब पर एसएस पिपर

मेरे पहले परीक्षणों की पुष्टि हुई, एसएसएच और एसएफटीपी दोनों काम करते हैं।


यह प्रभावी रूप से MITM- हमला है। मुझे उम्मीद है कि यह MITM- हमलों के खिलाफ संरक्षित हर सेटअप में टूट जाएगा।
कास्परड

1
वास्तव में होस्टिंग पार्टी दोनों, मेजबान और बीच में आदमी है, इस प्रकार केवल वे दोनों शामिल हैं।
किर्ली इस्तवान

@ KirályIstván यह कमाल का प्रोजेक्ट है और इस बात का प्रमाण है कि अन्य उत्तर 100% सही नहीं हैं। मैंने github.com/gliderlabs/sshfront और कुछ bash / python के आधार पर इसी तरह का टूल बनाया (मैं इसे स्रोत नहीं खोल सकता लेकिन यह दिलचस्प नहीं है - bash रन ssh क्लाइंट और python को ऑरलर रेसलर के रूप में उपयोग किया जाता है)। लेकिन मेरे पास मौजूदा समाधान के साथ एक मुद्दा है। यह sftp (scp वर्क्स) का समर्थन नहीं करता है। यह सबसिस्टम को चलाने की कोशिश करता है debug1: Sending subsystem: sftp। यह पता चला है कि शर्ट-फ्रंट सबसिस्टम का समर्थन नहीं करता है। क्या आप एसएस पाइप में हेम का समर्थन करते हैं?
मैकीक सविकी

1
@MaciekSawicki मैं लेखक नहीं हूँ। मैं सिर्फ अपने प्रोजेक्ट में इसका इस्तेमाल करता हूं। ।)
किर्ली इस्तवान

2

मैं सोच रहा था कि क्या हनीट्रैप (कम बातचीत वाला हनीपोट) जिसके पास एक प्रॉक्सी मोड है उसे हासिल करने के लिए संशोधित नहीं किया जा सकता है।

यह हनीपॉट किसी भी प्रोटोकॉल को दूसरे कंप्यूटर पर फॉरवर्ड करने में सक्षम है। एक नाम आधारित vhost प्रणाली (जैसा कि अपाचे द्वारा लागू किया गया है) को जोड़ने से यह किसी भी प्रोटोकॉल के लिए एक सही रिवर्स प्रॉक्सी बना सकता है?

मेरे पास इसे हासिल करने का कौशल नहीं है, लेकिन शायद यह एक बेहतरीन परियोजना हो सकती है।


उत्कृष्ट विचार!
पक्षपात

1
Apache में vhost फीचर क्लाइंट से होस्टनाम भेजने पर निर्भर करता है, क्योंकि सर्वर से कोई डेटा भेजा गया है। SSH प्रोटोकॉल में ऐसा कोई होस्टनाम शामिल नहीं है, इसलिए मैं यह नहीं देखता कि आप ऐसी सुविधा को कैसे लागू करना शुरू करेंगे। लेकिन अगर आप अपने विचारों पर विस्तार से विचार कर सकते हैं, तो मुझे अवधारणा के प्रमाण को लागू करने में खुशी होगी या आपको यह बताना होगा कि यह काम क्यों नहीं करेगा।
कास्परड

1

जैसे ही आप फायरवॉल बढ़ने के पीछे बंदरगाहों / मेजबानों की संख्या बढ़ाना चाहते हैं, वीपीएन की सुविधा बढ़ जाती है।

मुझे वीपीएन पसंद नहीं है, हालांकि।


1

क्योंकि ssh कैसे काम करता है मुझे लगता है कि यह संभव नहीं है। Https के समान ही आपके पास अलग-अलग होस्ट के लिए अलग (बाहरी) आईपी होना चाहिए, क्योंकि गेटवे को नहीं पता है कि आप कहां कनेक्ट करना चाहते हैं क्योंकि ssh में सब कुछ एनक्रिप्टेड है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.