SSH रिमोट पोर्ट फ़ॉरवर्डिंग विफल रहा


26

फॉलो-अप: ऐसा लगता है कि प्रत्येक सर्वर को चलाने के कुछ महीनों के दौरान होने वाले डिस्कनेक्ट की तीव्र श्रृंखला संभवतः संयोग है और वास्तविक समस्या को प्रकट करने के लिए बस सेवा की जाती है। AliveInterval मान (कैस्परर्ड के उत्तर) के कारण इसे पुन: कनेक्ट करने में विफल होने का कारण लगभग निश्चित रूप से है। ExitOnForwardFailure विकल्प का उपयोग करने से पुन: कनेक्ट होने से पहले टाइमआउट ठीक से होने देना चाहिए, जिससे अधिकांश मामलों में समस्या का समाधान होना चाहिए। मदहैटर का सुझाव (किल स्क्रिप्ट) संभवतः यह सुनिश्चित करने का सबसे अच्छा तरीका है कि सुरंग बाकी सब विफल होने पर भी पुन: कनेक्ट कर सकती है।

मेरे पास फ़ायरवॉल के पीछे एक सर्वर (ए) है जो एक छोटे से DigitalOcean VPS (B) के लिए कई बंदरगाहों पर एक रिवर्स सुरंग की शुरुआत करता है ताकि मैं B के IP पते से A से जुड़ सकूं। सुरंग लगभग 3 महीने से लगातार काम कर रही है, लेकिन पिछले 24 घंटों में अचानक चार बार विफल रही है। एक ही बात एक और VPS प्रदाता पर कुछ समय पहले हुई थी - सही संचालन के महीने, फिर अचानक कई तीव्र विफलताएं।

मेरे पास मशीन ए पर एक स्क्रिप्ट है जो स्वचालित रूप से सुरंग कमांड को निष्पादित करती है ( ssh -R *:X:localhost:X address_of_Bप्रत्येक पोर्ट एक्स के लिए) लेकिन जब यह निष्पादित होता है, तो यह कहता है Warning: remote port forwarding failed for listen port X

/var/log/secureसर्वर पर sshd में जाना इन त्रुटियों को दर्शाता है:

bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X

हल करने के लिए वीपीएस को रिबूट करने की आवश्यकता होती है। तब तक, "रिमोट पोर्ट फ़ॉरवर्डिंग विफल" संदेश देने के लिए पुन: कनेक्ट करने के सभी प्रयास और काम नहीं करेंगे। यह अब उस बिंदु पर है जहां सुरंग केवल रोकने से पहले लगभग 4 घंटे तक चलती है।

VPS पर कुछ भी नहीं बदला है, और यह एक एकल-उपयोग, एकल उपयोगकर्ता मशीन है जो केवल रिवर्स सुरंग समापन बिंदु के रूप में कार्य करता है। यह CentOS 6.5 पर OpenSSH_5.3p1 चल रहा है। ऐसा लगता है कि कनेक्शन खो जाने पर sshd पोर्ट को बंद नहीं कर रहा है। मुझे यह समझाने के लिए नुकसान हो रहा है कि लगभग सही संचालन के महीनों के बाद अब ऐसा क्यों या क्यों होता है।

स्पष्ट करने के लिए, मुझे पहले यह पता लगाने की आवश्यकता है कि सुरंग विफल होने के बाद बंदरगाहों पर सुनने से इनकार क्यों करता है, जो लगता है कि एसडीएस बंदरगाहों को खुला छोड़ने और उन्हें बंद नहीं करने के कारण होता है। यह मुख्य समस्या लगती है। मुझे यकीन नहीं है कि व्यवहार के महीनों के बाद इस तरह से व्यवहार करने का क्या कारण होगा क्योंकि मुझे उम्मीद है (यानी बंदरगाहों को तुरंत बंद कर देना और स्क्रिप्ट को फिर से जोड़ने की अनुमति देना)।


क्या पूछते हैं? पोर्ट बाइंडिंग त्रुटि को कैसे पता करें, या यह पता कैसे करें कि ssh क्यों मर रहा है, या फिर कुछ और?
MadHatter

मुझे यह पता लगाने की आवश्यकता है कि वीपीएस (बाइंड एरर) पर पोर्ट को खोलने के लिए sshd क्यों मना कर रहा है। पोर्ट बाइंडिंग त्रुटि समस्या की जड़ प्रतीत होती है, और अगर मैं इसे हल करने में सक्षम हूं तो सब कुछ काम करना चाहिए।
जस्टिन मृकवा

2
किसी भी देर से दुबकने के लिए, कनेक्शन को खुला रखने के लिए मैन्युअल रूप से स्क्रिप्ट बनाने के बजाय, इसके बजाय बस ऑटोस का उपयोग करें, जो आपके लिए ऐसा करता है। serverfault.com/questions/598210/…
ऑलिगॉफ़ेन

जवाबों:


27

मैं MadHatter से सहमत हूं, कि यह डिफंक्ट ssh कनेक्शन से पोर्ट फॉरवर्डिंग होने की संभावना है। यहां तक ​​कि अगर आपकी वर्तमान समस्या कुछ और है, तो आप जल्द या बाद में इस तरह के डिफेक्ट ssh कनेक्शन में चलने की उम्मीद कर सकते हैं।

ऐसे तीन तरीके हो सकते हैं जैसे कि अशुद्ध कनेक्शन हो सकते हैं:

  • दो एंडपॉइंट में से एक रिबूट हो गया, जबकि कनेक्शन का दूसरा छोर पूरी तरह से निष्क्रिय था।
  • दो समापन बिंदुओं में से एक ने कनेक्शन बंद कर दिया था, लेकिन उस समय जहां कनेक्शन बंद था, कनेक्शन पर एक अस्थायी आउटेज था। कनेक्शन बंद होने के बाद कुछ मिनट तक आउटेज चलता रहा, और इस तरह दूसरे छोर को कभी भी बंद कनेक्शन के बारे में पता नहीं चला।
  • कनेक्शन अभी भी ssh कनेक्शन के दोनों छोरों पर पूरी तरह कार्यात्मक है, लेकिन किसी ने उनके बीच कहीं एक स्टेटफुल डिवाइस लगाई है, जो आलस्य के कारण कनेक्शन को समाप्त कर देता है। यह स्टेटफुल डिवाइस या तो NAT या फायरवॉल होगा, आपके द्वारा पहले से उल्लेखित फ़ायरवॉल एक प्रमुख संदिग्ध है।

यह पता लगाना कि उपरोक्त तीनों में से कौन सा अधिक महत्वपूर्ण है, क्योंकि यह एक विधि है, जो तीनों को संबोधित करेगी। यह रखने वाले संदेशों का उपयोग है।

आप के ClientAliveIntervalलिए sshd_configऔर ServerAliveIntervalअंतराल के लिए खोजशब्द में देखना चाहिए ssh_configया ~/.ssh/config

sshलूप में कमांड चलाना ठीक काम कर सकता है। लूप में एक नींद सम्मिलित करने के लिए यह एक अच्छा विचार है कि आप किसी कारण से कनेक्शन विफल होने पर सर्वर को बाढ़ नहीं देते हैं।

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


मैं सोच रहा हूँ कि यह समस्या हो सकती है। विशेष रूप से, ए पर मेरी स्क्रिप्ट बी को फिर से कनेक्ट करने का प्रयास करेगी यदि ssh प्रक्रिया मर जाती है (निश्चित रूप से चेतावनी संदेश ssh प्रक्रिया को नहीं मारता है जब यह होता है तो यह लटका रहता है, लेकिन यह एक और दिन के लिए एक समस्या है)। लेकिन अगर A बहुत जल्दी B को फिर से जोड़ने की कोशिश करता है, तो B A को फिर से जोड़ने का इंतजार कर सकता है। मुझे शायद यह सुनिश्चित करने की ज़रूरत है कि बी हमेशा ए रिकंस्ट्रक्शंस से पहले बाहर हो। जोड़ने से पहले sshd प्रक्रियाओं को मारने के MadHatter के सुझाव के साथ संयोजन संभवतया 95% संभावित मामलों को कवर करेगा।
जस्टिन मिक्वा

1
और एसएसएच को नहीं मारने वाले चेतावनी संदेश की बात करते हुए, कि मुझे सोच समझ कर मिला ... और मैनपाट को देखना। पता चला है -o ExitOnForwardFailure yesकि वास्तव में मैं क्या जरूरत है। इसलिए मुझे यह पता लगाने की जरूरत है कि एक कम चीज है। सोचने के लिए, मैं उन चेतावनी संदेशों के लिए पार्स करने के लिए एक पायथन स्क्रिप्ट लिखने जा रहा था। यह बहुत सरल है। : डी
जस्टिन म्कवा

ExitOnForwardFailureमेरा उत्तर लिखते समय भूलने के लिए क्षमा करें । मैंने इसे अब जवाब में जोड़ दिया है।
कास्परड

4
कोई समस्या नहीं है, और यह वास्तव में था -o ExitOnForwardFailure=yes(समान चिह्न पर ध्यान दें)। इसलिए अगर कोई भी इस पार आता है, तो मेरी पिछली टिप्पणी से कॉपी और पेस्ट न करें, यह काम नहीं करेगा। : पी
जस्टिन मिक्वा

इसलिए मैं लगभग 10 घंटे के लिए सर्वर की निगरानी कर रहा हूं और ऐसा लग रहा है कि यह ठीक चल रहा है; मैं इस बिंदु पर यह मान रहा हूं कि यह उत्तर सही है (मैंने जो देखा है, उसके आधार पर मैं 99% निश्चित हूं) और यह कि तेजी से डिस्कनेक्ट की श्रृंखला नेटवर्क के मुद्दों से संबंधित संयोग थी जो अभी कुछ महीनों बाद प्रदर्शित हुई प्रत्येक सेवा शुरू करना। मदद के लिए सभी को धन्यवाद। ;)
जस्टिन Mrkva

4

आप उस सर्वर पर पोर्ट को बाइंड करने वाली प्रक्रिया पा सकते हैं

sudo netstat -apn|grep -w X

यह आधे-अधूरे होने की बहुत संभावना है sshd, लेकिन जब आपके पास डेटा हो सकता है तो धारणा क्यों बनाएं? सुरंग को फिर से ऊपर लाने की कोशिश करने से पहले सिग्नल 9 भेजने के लिए एक पीआईडी ​​खोजने के लिए स्क्रिप्ट का एक अच्छा तरीका है।


मुझे याद है कि पिछले VPS प्रदाता की जाँच, और मैंने पुष्टि की कि sshd उन बंदरगाहों को सुनने की प्रक्रिया थी। अगली बार ऐसा होता है कि मैं इसे यहाँ देखूँगा, लेकिन जैसा कि व्यवहार और सेटअप बिल्कुल वैसा ही है, मुझे इसकी कोई उम्मीद नहीं है।
जस्टिन Mrkva

महान, इसलिए आपकी स्क्रिप्ट है जो सुरंग को फिर से खोलती है ऐसा करने की कोशिश करने से पहले पुराने सुरंग को मार दें।
MadHatter

एक बार में एक से अधिक सुरंग स्क्रिप्ट (ए पर) नहीं चल रही है, यदि आप यही कह रहे हैं। दूसरी ओर, अगर आपका मतलब है कि पटकथा को दूरस्थ रूप से आवारा प्रक्रियाओं को मारने के लिए बी पर एक कमांड निष्पादित करना है ... तो यह वास्तव में एक आधा बुरा विचार नहीं है। अगर मैं डिबग करने की कोशिश कर रहा हूं तो एक चिंता बार-बार सभी एसएसएच कनेक्शनों को मार रही है। यदि ए पर स्क्रिप्ट हमेशा एक गड़बड़ के कारण बी को मार रही है, तो मुझे दुष्ट ए स्क्रिप्ट द्वारा लगातार बी से लात नहीं मारी जा सकती है। : P मुझे यह सुनिश्चित करने के लिए परीक्षण करना होगा कि वह ऐसा नहीं करता है। लेकिन जैसा मैंने कहा, एक आधा बुरा विचार नहीं है। ;)
जस्टिन Mrkva

मुझे नहीं लगा था कि वहाँ था। आप कहते हैं कि एक स्क्रिप्ट दूरस्थ सर्वर पर चल रही है, जो एक टनल को लाने की कोशिश करती है और विफल होने के कारण विफल हो जाती है, और मैं इसे केवल तभी चलाता हूं जब आपको इसकी आवश्यकता होती है (यानी, जब मौजूदा टनल अच्छी नहीं है) क्योंकि आपने अन्यथा नहीं कहा है। मैं केवल यह सुझाव दे रहा हूं कि यह उस विशिष्ट प्रक्रिया को मार डाले, जो नई सुरंग को लाने की कोशिश करने से पहले बंदरगाह को खुला रखती है।
MadHatter

Ssh पर चलने वाली स्क्रिप्ट केवल सर्वर A पर है, सर्वर B एक साधारण वेनिला सर्वर है जिसमें कोई अतिरिक्त स्क्रिप्ट नहीं है। सर्वर बी पर डालने के लिए मैं एक किल स्क्रिप्ट लिखूंगा, तो दूरस्थ रूप से ए से कॉल करें यदि यह एक निश्चित संख्या में कई बार कनेक्ट करने में विफल रहता है। इस तरह से अन्य एसएसएच कनेक्शन के साथ हस्तक्षेप करने की संभावना कम है। और मेरे पास शायद हर बार चलने वाली स्क्रिप्ट स्क्रिप्ट होती है और बिना कुछ किए भी बाहर निकल जाती है अगर इसे कई बार बहुत जल्दी कहा जाए। व्यक्तिगत रूप से, यह किसी भी स्क्रिप्ट को दर-सीमित करने जैसा लगता है जो sshd को मारता है वह शायद विवेकपूर्ण है। : पी
जस्टिन मर्का

3

मेरे लिए जब एक sshसुरंग डिस्कनेक्ट होती है, तो कनेक्शन को रीसेट करने में कुछ समय लगता है, इसलिए sshप्रक्रिया मुझे बिना किसी सक्रिय सुरंग के साथ छोड़ना जारी रखती है और मुझे नहीं पता कि क्यों। वर्कअराउंड सॉल्यूशन को sshबैकग्राउंड में डालना -fऔर नए कनेक्शनों को रीसेट करने के लिए पुराने कनेक्शन की प्रतीक्षा किए बिना स्पॉन करना है। -o ExitOnForwardFailure=yesनई प्रक्रियाओं की संख्या limt के लिए इस्तेमाल किया जा सकता है। -o ServerAliveInterval=60अपने मौजूदा कनेक्शन की विश्वसनीयता में सुधार।

आप sshकमांड को बार-बार दोहरा सकते हैं, कह सकते हैं, cronअपनी स्क्रिप्ट में एक लूप में या, उदाहरण के लिए, निम्नलिखित में, हम sshहर 3 मिनट में कमांड चलाते हैं :

while (1)
do
    ssh -f user@hostname -Rport:host:hostport -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=60
    sleep 180
done

एक तरह से अधिक मजबूत समाधान ऑटोस्कोप
मार्को लैवागीनो

-o ExitOnForwardFailure=yesमैं क्या देख रहा था, बहुत बहुत धन्यवाद!
वादीप

1

मेरे अनुभव में ssh को साफ-साफ बाहर न निकलने की थोड़ी चिड़चिड़ी आदत है अगर 'कुछ' अभी भी रिमोट सिस्टम पर चल रहा है। जैसे पृष्ठभूमि में शुरू हुआ। आप इसे पुन: पेश कर सकते हैं:

ssh <server>
while true; do  sleep 60; done&
exit

आपका ssh लॉग आउट हो जाएगा, लेकिन वास्तव में सत्र को बंद नहीं करेगा - जब तक कि दूरस्थ प्रक्रिया बाहर नहीं निकल जाती (जो कि ऐसा नहीं होगा, क्योंकि यह एक 'सही' लूप है)। यह कुछ ऐसा ही हो सकता है - आपके सत्र में एक 'अटकी' प्रक्रिया है जो ssh द्वारा प्रायोजित की जा रही है। पोर्ट उपयोग में रहता है, और इसलिए इसे आपकी स्थानीय प्रक्रिया द्वारा फिर से उपयोग नहीं किया जा सकता है।


पूरी SSH कमांड जो A मशीन पर निष्पादित होती है, ssh -o ConnectTimeout=10 -o BatchMode=yes -gnN -R *:X:localhost:X root@$TUNSRV 1>>tunnel.log 2>&1 &इसलिए SSH द्वारा सुरंग के अलावा कुछ भी निष्पादित नहीं किया जा रहा है, विशेष रूप से -N विकल्प के कारण। जो कुछ भी खुला रखा जा रहा है वह दूरस्थ सर्वर B पर sshd का उपयोग करके किया जा रहा है।
जस्टिन मृकवा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.