คำปฏิเสธ
หากการเชื่อมต่อ SSH ของคุณไม่รอดจากปัญหาเครือข่ายขาดหายไปแสดงว่ามีบางสิ่งที่เกิดขึ้นซึ่งไม่ได้แจ้งให้ทราบssh
และ TCP ทำสิ่งปกติ
ดูรายละเอียดด้านล่าง อย่างไรก็ตาม:
โซลูชันที่ไม่มีการพึ่งพาที่รวดเร็วที่สุดและสกปรกที่สุด
สร้างเชลล์สคริปต์เช่นนี้:
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
เพียงแค่นี้ก็จะทำงานห่วงโง่ง่ายๆที่ช่วยให้พยายามที่จะเชื่อมต่อกับและแนบไปกับssh
screen
ผ่านโฮสต์หรืออะไรก็ตามที่คุณมักจะส่งผ่านไปยังssh
การเรียกร้องของคุณเป็นอาร์กิวเมนต์บรรทัดคำสั่ง
การเชื่อมต่อใหม่นั้นขึ้นอยู่กับว่า SSH รายงานข้อผิดพลาดกับการเชื่อมต่อหรือไม่ซึ่งหมายความว่าไม่มีความฉลาดในการตรวจหาข้อผิดพลาดที่ไม่ใช่ SSH เช่น "คุณไม่ได้เปิด WiFI" หรืออะไรก็ตาม แต่นั่นอาจไม่สำคัญสำหรับ คุณ.
ฉันสมมติว่าคุณมีssh-agent
หรือไม่มีคีย์รหัสผ่าน SSH ที่จะช่วยให้การเชื่อมต่อใหม่ทำงานได้โดยไม่ต้องป้อนข้อมูลเพิ่มเติมจากคุณ
จะมีสภาพการแข่งขันขนาดเล็กซึ่งถ้าคุณกด^C
ในช่วงเวลาเพียงเสี้ยววินาทีที่มนุษย์ไม่สามารถมองเห็นได้ในระหว่างการเชื่อมต่ออีกครั้งคุณสามารถฆ่าสคริปต์แทนการส่ง^C
ผ่านไปยังสถานีลูกค้าดังนั้นหากคุณสงสัยว่าการเชื่อมต่อหยุดชะงัก อย่าบด^C
อย่างแรงเกินไป
โซลูชันซอฟต์แวร์เพิ่มเติมที่ง่ายที่สุด
คุณสามารถลองใช้โปรแกรมautosshซึ่งควรมีอยู่ในที่เก็บแพ็คเกจ Ubuntu ของคุณ
หากคุณจำเป็นต้องสร้างจากแหล่งที่มาหรือการตรวจสอบมันเป็นโปรแกรม C เดียวที่รวบรวมโดยไม่ต้องห้องสมุดเพิ่มเติมใด ๆ เป็นการอ้างอิงดูเหมือนว่าจะมีความฉลาดมากขึ้นเกี่ยวกับการตรวจสอบความมีชีวิตชีวาการเชื่อมต่อมากกว่าสับของฉันข้างต้นและมันก็มาพร้อมกับความสะดวกสบายrscreen
คำสั่งสคริปต์ซึ่งอัตโนมัติ -attaches screen
ไป
รายละเอียด
วิธีการssh
กู้คืนปกติ
เพียงเพื่อตรวจสอบเพราะฉันไม่ชอบพูดสิ่งต่าง ๆ โดยไม่ต้องตรวจสอบตัวเองฉันวิ่งทดสอบเล็กน้อยก่อนตอบ:
ฉันได้บนอินเตอร์เน็ตไร้สายของฉันกับอุปกรณ์ลินุกซ์ทำให้การเชื่อมต่อ SSH ไปยังอุปกรณ์อื่นบน LAN ของฉันตรวจสอบผมมีการทำงานssh
เชื่อมต่อกับส่วนอื่น ๆ (อาจเรียกใช้คำสั่ง ฯลฯ ) แล้วที่ลูกค้ายกเลิกการเชื่อมต่อ Wi-Fi (ก่อให้เกิดการอินเตอร์เฟซ ที่จะยกเลิกการกำหนดค่า: ไม่มีที่อยู่ IP เพิ่มเติมพิมพ์ตัวอักษรจำนวนมากลงในเซสชัน ssh (ไม่มีการตอบสนองแน่นอน) จากนั้นเชื่อมต่อกับ WiFi อีกครั้ง - การเชื่อมต่อใหม่ล้มเหลวอย่างน้อยหนึ่งครั้งเนื่องจากสัญญาณไม่ดีและปัจจัยอื่น ๆ จากนั้นในที่สุดการเชื่อมต่ออีกครั้ง: ฉันรอประมาณห้าวินาทีเพื่อให้ssh
เซสชันกู้คืนไม่มีอะไรเกิดขึ้นดังนั้นฉันจึงกดปุ่มอีกหนึ่งปุ่มและssh
เซสชันกลับมามีชีวิตอีกครั้งในทันทีโดยมีปุ่มทั้งหมดที่ฉันพิมพ์ในระหว่างการยกเลิกการเชื่อมต่อ
ดูssh
เพียงเขียน / อ่านลงในซ็อกเก็ตเครือข่าย TCP จนกว่า OS จะบอกว่ามีบางอย่างผิดปกติและ TCP นั้นทนต่อการเชื่อมต่อที่ยืดเยื้อเป็นเวลานาน
ปล่อยให้อุปกรณ์ของตัวเองมีการตั้งค่าเคอร์เนลเริ่มต้นสแต็ค TCP ใน Linux จะยอมรับการเชื่อมต่อที่เงียบสนิทเป็นเวลาหลายนาทีก่อนที่จะประกาศการเชื่อมต่อที่ตายแล้วและรายงานข้อผิดพลาดถึงssh
- ในที่สุดเมื่อเรายอมแพ้ ประมาณ ~ 30 นาทีหรืออย่างน้อยก็นานพอที่จะอยู่ได้นานกว่าการเชื่อมต่อ hiccups นานสองหรือหนึ่งนาที
ภายใต้ฝาครอบ Linux TCP stack จะพยายามส่งข้อความที่มีความล่าช้านานขึ้นเรื่อย ๆ ซึ่งหมายความว่าเมื่อถึงเวลาที่การเชื่อมต่อของคุณกลับมาคุณอาจมองล่าช้าเพิ่มเติมก่อนที่ssh
เซสชันของคุณจะกลับมา "มีชีวิต" อีกครั้ง
ทำไมบางครั้งถึงแตก
บ่อยครั้งสิ่งที่ทำให้การเชื่อมต่อปิดหลังจากที่ไม่มีการใช้งานในช่วงเวลาสั้นลงอย่างมีนัยสำคัญกว่าจำนวนที่สแต็ก TCP จะทนและจากนั้นไม่สามารถรายงานสถานะการเชื่อมต่อนั้นไปยังssh
ไคลเอนต์ของคุณ
ผู้สมัครที่มีแนวโน้มรวมถึง:
ไฟร์วอลล์หรือเราเตอร์ NAT'ing ซึ่งต้องใช้หน่วยความจำเพื่อจดจำการเชื่อมต่อ TCP ที่ใช้งานจริงแต่ละครั้ง - เป็นการเพิ่มประสิทธิภาพและลดการโจมตีของ DOS บางครั้งพวกเขาจะลืมการเชื่อมต่อของคุณและจากนั้นมองข้ามแพ็กเก็ตตามมาอย่างเงียบ ๆกึ่งกลางของการเชื่อมต่อเมื่อคุณจำการเชื่อมต่อที่มีอยู่ดูไม่ถูกต้อง
ไฟร์วอลล์ / เราเตอร์ที่ทำงานได้ดีกว่าจะฉีดแพ็กเก็ต TCP RST ซึ่งโดยทั่วไปจะปรากฏเป็นconnection reset by peer
ข้อความแสดงข้อผิดพลาด แต่แพ็คเก็ตรีเซ็ตนั้นเป็นไฟและลืมดังนั้นหากการเชื่อมต่อกับไคลเอ็นต์ของคุณยังคงมีปัญหาในขณะนั้น รีเซ็ตแพ็คเก็ตด้วยเช่นกันลูกค้าของคุณจะคิดว่าการเชื่อมต่อยังมีชีวิตอยู่
เซิร์ฟเวอร์เองอาจมีนโยบายไฟร์วอลล์เพื่อทิ้งแพ็กเก็ตที่ไม่คาดคิดซึ่งจะทำให้การเชื่อมต่อของลูกค้าพยายามกลับมาทำงานใหม่เมื่อใดก็ตามที่เซิร์ฟเวอร์คิดว่าการเชื่อมต่อถูกปิด แต่ลูกค้าไม่ทำเช่นนั้น: ไคลเอ็นต์ของคุณพยายามเชื่อมต่อต่อไป ไม่ต้องสนใจเนื่องจากไม่มีการเชื่อมต่อแบบสดๆที่แพ็กเก็ตเหล่านี้อยู่ในสถานะไฟร์วอลล์ของเซิร์ฟเวอร์
เนื่องจากคุณใช้งาน Linux ให้ตรวจสอบเซิร์ฟเวอร์ของคุณอย่างระมัดระวังiptables
/ ip6tables
(หรือnft
หากคุณกำลังใช้สิ่งใหม่) สำหรับสิ่งที่คุณอนุญาตและทำหล่น เป็นเรื่องธรรมดามากที่จะอนุญาตให้ใหม่ / ที่สร้างขึ้น / ที่เกี่ยวข้องกับแพ็คเก็ตบนพอร์ต TCP SSH แต่ไม่ใช่ "ไม่ถูกต้อง" - ถ้าคุณทิ้งทุกอย่างที่ไม่ได้รับอนุญาตการตั้งค่าทั่วไปนี้อาจทำให้เกิดการค้างเหล่านี้ .
เซิร์ฟเวอร์ SSH ของคุณอาจได้รับการกำหนดค่าให้ปิดการเชื่อมต่อหลังจากไม่มีการใช้งานเป็นระยะเวลาหนึ่งโดยใช้หนึ่งในตัวเลือก OpenSSH สำหรับ TCP หรือ SSH ไคลเอ็นต์แบบแพ็คเก็ตแบบคงที่ ด้วยตัวเองสิ่งนี้จะไม่ทำให้เกิดการแฮงไม่ จำกัด แต่สามารถทำให้คุณอยู่ในสถานะใดรัฐหนึ่งที่อธิบายไว้ข้างต้น
เป็นไปได้ว่าคุณไม่ได้ให้เวลามากพอที่จะ "ปลดหู" ด้วยตัวเองหลังจากที่คุณเข้าสู่สถานะที่ssh
เซสชันของคุณวางสาย
<Enter>
และพิมพ์~.
เพื่อบอกให้ฝ่ายคุณเลิกการเชื่อมต่อและคุณสามารถทำซ้ำคำสั่ง ssh สุดท้ายเพื่อเชื่อมต่อใหม่ (เช่นลูกศรขึ้นหรือ!!
)