سؤال كيف يمكن الحفاظ على نفق SSH مفتوح؟


أنا استخدم نفق SSH من العمل لتذهب حول جدران الحماية المثالية المختلفة (لا بأس مع مديري :)). المشكلة ، بعد فترة توقف اتصال ssh عادة ، والنفق مكسورة.

إذا تمكنت على الأقل من مراقبة النفق تلقائيًا ، يمكنني إعادة تشغيل النفق عند تعليقه ، لكنني لم أفهم حتى طريقة للقيام بذلك.

نقاط المكافأة للشخص الذي يمكن أن يخبرني عن كيفية منع اتصال ssh الخاص بي من الشنق ، بالطبع!


207
2017-09-08 13:04


الأصل


هل نفقك ميت بسبب عدم النشاط؟ لقد واجهت هذه المشكلة عند نفق المنافذ من هاتفي ، لذلك انتهى بي الأمر في نهاية الأمر إلى وضع الوعاء الدموي على الاتصال لجعله "على قيد الحياة" باستخدام watch الأمر مثل: watch -n1 60 echo "wiiiii". لن يموت النفق ما لم تتعطل الشبكة أو لا تستخدمها. - erm3nda
ذات صلة: unix.stackexchange.com/q/200239 - sampablokuper


الأجوبة:


يبدو وكأنك بحاجة autossh. سيقوم هذا بمراقبة نفق ssh وإعادة تشغيله حسب الحاجة. لقد استخدمناها لبضع سنوات ويبدو أنها تعمل بشكل جيد.

autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C

مزيد من التفاصيل حول المعلمة -M هنا


247
2017-09-08 13:43



+1 من أجل autossh ، فإنه يفعل ما يقول على القصدير. أعتقد أن جزءًا من وظيفتها أيضًا هو إرسال حزم الحافظات المستمرة لمنع أي نوع من المهلة. - akent
هل يمكن أن تستخدم مثال النفق باستخدام autossh في الجواب؟ - Ehtesh Choudhury
autossh -f -nNT -i ~/keypair.pem -R 2000:localhost:22 username@myoutsidebox.com   قد تلاحظ أنني قمت بإعداد هذا باستخدام -nNT الذي لا يقوم بإنشاء محطة طرفية بعيدة حتى أتمكن من وضع autossh في الخلفية ، والخيار -i لـ SSH لاستخدام ملف .pem. إذا كنت ستحافظ على اتصال مفتوح طوال الوقت ، فأنا بالتأكيد أنصح باستخدام الإعداد الإضافي. - juckele
بالنسبة لما يستحق ، يبدو أنه من الأفضل عادة حذفه -M معامل: bugs.debian.org/cgi-bin/bugreport.cgi؟bug=351162 - rinogo
كيف يعمل هذا إذا كان لديّ عبارة مرور؟ هل ستخزن عبارة المرور هذه في سلسلة المفاتيح (على سبيل المثال ، على جهاز Mac)؟ - Yannick Y


جميع جدران الحماية الرسمية تنسي اتصالاً بعد عدم رؤية حزمة لهذا الاتصال لبعض الوقت (لمنع جداول الحالة من أن تصبح مليئة بالاتصالات حيث توفي كلا الطرفين دون إغلاق الاتصال). ترسل معظم تطبيقات TCP حزمة keepalive بعد فترة طويلة دون الاستماع من الجانب الآخر (ساعتان قيمة شائعة). ومع ذلك ، إذا كان هناك جدار حماية رسمي ينسى الاتصال قبل إرسال حزم keepalive ، سيموت اتصال طويل العمر لكن بعيد.

إذا كان هذا هو الحال ، فإن الحل هو منع الاتصال من أن يصبح خاملاً. OpenSSH لديه خيار يسمى ServerAliveInterval التي يمكن استخدامها لمنع الاتصال من الخمول لفترة طويلة (كمكافأة ، فإنه سيتم الكشف عن عندما يموت الأقران عاجلاً حتى إذا كان الاتصال خاملاً).


35
2017-09-28 13:47



الفاصل الزمني المحدد في ثوان ، حتى تتمكن من توفير بعض الضبط الدقيق. إذا كان للجدار الناري الخاص بالولادة مهلة خمول دامت 5 دقائق ، فإن 60 أو 120 ثانية كافية للحفاظ على الاتصال مفتوحًا. إنها إحدى الطرق التي أبقي بها جلسات ssh الخاصة بي من خلال جهاز التوجيه المنزلي الخاص بي مفتوحًا. - Darren Hall
شكرا ، ساعد هذا. لكن لاحظ (من إجابة أقل مرتبة هنا ، superuser.com/a/146641/115515) أنه إذا قمت بتحديد ServerAliveInterval وليس ServerAliveCountMax ، قد تجد ssh قطع الاتصال عمداً مما تريد. - metamatt
metamatt ، تلك الإجابة ذات المرتبة الأقل التي أشرت إليها هي أقل تصنيفًا لسبب وجيه: إنها خاطئة. - Lambart


على جهاز ماك أو جهاز لينكس الخاص بك تكوين ssh الخاص بك إبقاء خادم ssh على قيد الحياة كل 3 دقائق. افتح جهاز طرفي وانتقل إلى ملف ssh غير مرئي في منزلك:

cd ~/.ssh/ 

ثم قم بإنشاء ملف تهيئة سطر واحد مع:

echo "ServerAliveInterval 180" >> config

يجب عليك أيضا إضافة:

ServerAliveCountMax xxxx (high number)

الافتراضي هو 3 بحيث سيتم إيقاف ServerAliveInterval 180 الإرسال بعد 9 دقائق (3 من الفاصل الزمني 3 دقائق المحدد بواسطة ServerAliveInterval).


23
2018-05-29 13:45



لاحظ أن الأمر غير مستحسن إذا كان لديك ملف تهيئة بالفعل. باستخدام >> لإعادة التوجيه سيكون أفضل بكثير! - Peltier
لماذا ServerAliveInterval 180 امنحنا 6 دقائق؟ الحدس يجعلني أحاول هذا: 180/60 == 3. لذلك ، هل ServerAliveInterval العمل في مضاعفات 30 ثانية؟ - nemesisfixx
mcnemesis: ServerAliveInterval 180 يعني 3 دقائق. ServerAliveCountMax الافتراضي من 3 يعني 3 من تلك الفواصل الزمنية ، لذلك 9 دقائق. - metamatt
أنا التصويت هذه الإجابة حتى لأن شكرا لذكر ServerAliveCountMax ، وماذا يحدث إذا قمت بتحديد ServerAliveInterval دون ServerAliveCountMax. ولكن مثل التعليقات السابقة ، ألاحظ أن الحساب على "سيتوقف عن الإرسال بعد" هو خطأ ، وأعتقد أن هذه الإجابة ستخدم بشكل أفضل إذا قدمت المعلومات حول هذه الخيارات فقط ، ولم تخبرنا كيف نطبقها باستخدام أوامر cd و echo . - metamatt
Downvoting لأنه لا معنى لضبط ServerAliveCountMax إلى "عدد كبير". تعيّن ServerAliveCountMax عدد المرات التي سيحاول فيها إرسال رسالة "keepalive" قبل الاستسلام. الافتراضي هو 3 ، لذلك مع ServerAliveInterval 180 ، فإنه سيتوقف عن الإرسال فقط إذا لم يستجب الملقم بعد 9 دقائق ، وفي هذه الحالة قد يكون الاتصال الخاص بك على ما يرام وموت حقا. - Lambart


لقد استخدمت البرنامج النصي Bash التالي للحفاظ على إنشاء نفق ssh جديد عند وفاة السابقة. يعد استخدام برنامج نصي مفيدًا عندما لا تريد أو لا تستطيع تثبيت حزم إضافية أو استخدام برنامج التحويل البرمجي.

while true
do
  ssh <ssh_options> [user@]hostname
  sleep 15
done

لاحظ أن هذا يتطلب وجود ملف key لتأسيس الاتصال تلقائيًا ، لكن هذا هو الحال مع autossh أيضًا.


20
2017-09-22 14:58



يجب عليك إضافة أي أسباب لاستخدام هذا البرنامج النصي على autossh ، أو أنه من السهل أن هذا الطريق؟ - kyrias
هذا لن يساعد إذا جمدت نفسها ssh ، أليس كذلك؟ - nafg
يساعد إذا كنت لا تستطيع تثبيت الأشياء في الخادم. autossh لا تأتي مثبتة مسبقا و bureucracy في بعض الأحيان منفرجة للغاية. - quarkex
نعم ، يفضل عدم تثبيت الأشياء. لقد كنت أفعل ذلك بهذه الطريقة لمدة عام كطريقتي الوحيدة للحفاظ على جهاز بعيد يمكن الوصول إليه (حتى وضع crontab لتشغيله عند إعادة التشغيل). لم يفشل أبدا ، والأهم من ذلك ، أعرف لماذا لن تفشل أبدا. - sudo


Systemd مناسبة بشكل مثالي لهذا الغرض.

قم بإنشاء ملف خدمة /etc/systemd/system/sshtunnel.service تحتوي:

[Unit]
Description=SSH Tunnel
After=network.target

[Service]
Restart=always
RestartSec=20
User=sshtunnel
ExecStart=/bin/ssh -NT -o ServerAliveInterval=60 -L 5900:localhost:5900 user@otherserver

[Install]
WantedBy=multi-user.target

(تعديل القيادة ssh لتناسب)

  • سيتم تشغيل هذا كمستخدم sshtunnel لذا تأكد من وجود المستخدم أولاً
  • القضية systemctl enable sshtunnel لتعيينه لبدء في وقت التمهيد
  • القضية systemctl start sshtunnel للبدء على الفور

تحديث يناير 2018: قد تستخدم بعض التوزيعات (على سبيل المثال Fedora 27) سياسة SELinux لمنع استخدام SSH من systemd init ، وفي هذه الحالة ستحتاج إلى إنشاء سياسة مخصصة لتوفير الإعفاءات اللازمة.


11
2017-07-28 06:10



يبدو هذا مشابهًا تمامًا لجريتي: gist.github.com/guettli/... ردود الفعل هو موضع ترحيب! - guettli
ممتاز ل systemd النظام. إذا كان أحد يستخدم Restart=on-failure ومن ثم فإن قتل عميل SSH يدويًا لن ينتج عنه إعادة تشغيل systemd كعميل SSH مع مخرج بالنجاح. - David Tonhofer
إذا كنت تريد بدء ssh من برنامج نصي (bash) المعطى كوسيطة لـ ExecStart على سبيل المثال لبناء ssh قائمة الحجة ، والقيام ببعض الفحوص الأساسية وما إلى ذلك ، ثم نسميها من البرنامج النصي مثل ذلك exec /bin/ssh -N .... هذه هي أمري: exec /bin/ssh -N -oExitOnForwardFailure=Yes -oTCPKeepAlive=no -oServerAliveInterval=5 -oServerAliveCountMax=6 -i "${LOCAL_PRIVATE_KEY}" -L "${TUNNEL_INLET}:${TUNNEL_OUTLET}" "${REMOTE_USER}@${REMOTE_MACHINE}" أين TUNNEL_INLET="127.0.0.1:3307" و TUNNEL_OUTLET="127.0.0.1:3306" - David Tonhofer


يبدو من المؤكد لي أنك جميع misinterpreting ServerAliveCountMax. كما أفهم المستندات ، إنه عدد رسائل الخادم التي لا يمكن الإجابة عليها دون أن يتم إنهاء الاتصال. لذلك في الحالات التي نناقشها هنا ، فإن تحديدها إلى قيمة عالية سيضمن فقط عدم الكشف عن اتصال معلقة وإنهائه!

الإعداد ببساطة ServerAliveInterval يجب أن يكون كافياً لحل المشكلة بجدار ناري نسيان الاتصال ، وسيترك ترك ServerAliveCountMax low النهاية الأصلية لملاحظة الفشل وإنهاء إذا فشل الاتصال على أية حال.

ما تريده هو ، 1) لكي يبقى الاتصال مفتوحًا بشكل دائم في ظل الظروف العادية ، 2) لفشل كشف الاتصال والجانب الأصلي للخروج عند الفشل ، و 3) لأمر ssh ليتم إعادة إصداره في كل مرة مخارج (كيف تفعل ذلك يعتمد بشكل كبير على النظام الأساسي ، البرنامج النصي "صحيح" الذي اقترحه جاوا هو أحد الطرق ، على نظام التشغيل OS XI الذي قام بالفعل بإعداد عنصر launchd).


9
2017-11-28 01:04





دائما يستخدم ServerAliveInterval خيار SSH في حالة حدوث مشكلات النفق بواسطة جلسات NAT منتهية الصلاحية.

استخدم دائمًا طريقة respawning في حالة انقطاع الاتصال تمامًا ، فلديك ثلاثة خيارات على الأقل هنا:

  • برنامج autossh
  • سكريبت باشwhile true do ssh ...; sleep 5; done) لا تزيل أمر النوم ، ssh قد تفشل بسرعة وستفقد العديد من العمليات
  • /etc/inittab، للوصول إلى مربع يتم شحنه وتثبيته في بلد آخر ، خلف NAT ، بدون إعادة توجيه المنفذ إلى المربع ، يمكنك تكوينه لإنشاء نفق ssh مرة أخرى:

    tun1:2345:respawn:/usr/bin/ssh -i /path/to/rsaKey -f -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip 'sleep 365d'
    
  • النصيحة المبتدئة على أوبونتو ، أين /etc/inittab غير متاح:

    start on net-device-up IFACE=eth0
    stop on runlevel [01S6]
    respawn
    respawn limit 180 900
    exec ssh -i /path/to/rsaKey -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip
    post-stop script
        sleep 5
    end script
    

أو دائما استخدام كلتا الطريقتين.


9
2018-03-08 21:30



إجراء 1+ للخيار المضمن في حالة عدم رغبتك في جميع اتصالات SSH الخاصة بك - user1146334
تكتب "في حالة انقطاع الاتصال تماما". الآن لا أفهم ، ما هي المشاكل التي يصنعها autossh نفسه ، وماذا لا؟ اعتقدت ، بطبيعة الحال ، أنها سوف تأخذ الرعاية من أي اتصال مكسورة ، مثل فصل الكابل لمدة بضع ساعات ، ولكن ربما لا؟ - Mads Skjern


لقد حلت هذه المشكلة مع هذا:

تصحيح

~/.ssh/config

و أضف

ServerAliveInterval 15
ServerAliveCountMax 4

بالنسبة الى صفحة رجل لـ ssh_config:

ServerAliveCountMax
         Sets the number of server alive messages (see below) which may be
         sent without ssh(1) receiving any messages back from the server.
         If this threshold is reached while server alive messages are
         being sent, ssh will disconnect from the server, terminating the
         session.  It is important to note that the use of server alive
         messages is very different from TCPKeepAlive (below).  The server
         alive messages are sent through the encrypted channel and there‐
         fore will not be spoofable.  The TCP keepalive option enabled by
         TCPKeepAlive is spoofable.  The server alive mechanism is valu‐
         able when the client or server depend on knowing when a connec‐
         tion has become inactive.

         The default value is 3.  If, for example, ServerAliveInterval
         (see below) is set to 15 and ServerAliveCountMax is left at the
         default, if the server becomes unresponsive, ssh will disconnect
         after approximately 45 seconds.  This option applies to protocol
         version 2 only.

 ServerAliveInterval
         Sets a timeout interval in seconds after which if no data has
         been received from the server, ssh(1) will send a message through
         the encrypted channel to request a response from the server.  The
         default is 0, indicating that these messages will not be sent to
         the server.  This option applies to protocol version 2 only.

6
2018-05-30 13:32



كل 15 ثانية يبدو في كثير من الأحيان إلى ping الملقم. - Lambart
@ Lambart ، ولكن إذا كان الاتصال غير مستقر بالفعل ويسقط الاتصالات في كثير من الأحيان ، فإنه على الأقل بالكشف عن اتصال ميت ويعطي الفرصة لإعادة المحاولة في وقت سابق. - binki