ทำไมบางครั้งคอนโซลก็หยุดอยู่ตลอดกาลเมื่อการเชื่อมต่อของ SSH แตก


89

ฉันเห็นสิ่งนี้ด้วยคอนโซลมากมาย (บน Linux, Mac, ... ) และมีเครื่องที่แตกต่างกันมากมายในเครือข่ายที่แตกต่างกัน ฉันไม่สามารถระบุเหตุผลที่แน่ชัดได้ว่าทำไมสิ่งนี้จึงเกิดขึ้น: สิ่งที่คุณต้องทำคือล็อกอินเข้าสู่เครื่องผ่าน SSH หากการเชื่อมต่อหยุดลงด้วยเหตุผลบางประการ (เพื่อความง่ายสมมติว่าสายเคเบิลเครือข่ายถูกดึงออก) จากนั้นบางครั้งคอนโซลก็ค้างตลอดไป - ในบางครั้งมันก็ออกมาดีกับพาเรนต์เชลล์

มันน่ารำคาญมากเมื่อเกิดเหตุการณ์นี้ขึ้น (เช่นคุณสูญเสียประวัติคำสั่ง) อาจมีแป้นพิมพ์ลัดลับๆที่สามารถบังคับให้ออก (Ctrl-C หรือ Ctrl-D ไม่ทำงาน)? และอะไรคือสาเหตุของ "บั๊ก" แบบสุ่มนี้ในการติดตั้งใช้งานทั้งหมด


เธรดนี้ดูเหมือนว่าเหมาะสมที่จะพูดถึงMosh (Mobile Shell) ซึ่งจัดการได้ดีกับความล้มเหลวในการเชื่อมต่อรวมถึงการโรมมิ่ง (เปลี่ยน IP) และอื่น ๆ
Ciprian Tomoiagă

คำตอบ:


137

มีแป้นพิมพ์ลัด "ลับ" เพื่อบังคับให้ออก: ~) จากเซสชันที่ตรึงให้กดปุ่มเหล่านี้ตามลำดับ: Enter~.เครื่องหมายตัวหนอน (เฉพาะหลังจากขึ้นบรรทัดใหม่) ได้รับการยอมรับว่าเป็นลำดับการหลบหนีโดยไคลเอนต์ ssh และระยะเวลาบอก ลูกค้ายกเลิกธุรกิจโดยไม่ต้องกังวลใจ

พฤติกรรมที่ค้างยาวในเรื่องการสื่อสารไม่ใช่ข้อผิดพลาดเซสชัน SSH กำลังอยู่ใน Hangout โดยหวังว่าอีกฝ่ายจะกลับมา หากเครือข่ายหยุดทำงานบางครั้งแม้กระทั่งหลายวันต่อมาคุณจะได้รับเซสชัน SSH กลับมาได้ แน่นอนคุณสามารถบอกได้ว่าจะยอมแพ้และตายไปตามลำดับข้างต้น นอกจากนี้ยังมีสิ่งต่าง ๆ ที่คุณสามารถทำได้เช่นการตั้งค่าไทม์เอาต์แบบ keep-alive ในไคลเอนต์ของคุณเพื่อที่ว่าถ้ามันไม่มีลิงค์ที่ใช้งานในช่วงระยะเวลาหนึ่งมันจะปิดตัวเอง แต่พฤติกรรมเริ่มต้นคือ เชื่อมต่อที่สุด!

แก้ไข:แอปพลิเคชันอื่นที่มีประโยชน์ของคีย์ขัดจังหวะนี้คือการรับความสนใจของไคลเอ็นต์ ssh ในพื้นที่และพื้นหลังเพื่อกลับไปที่โลคัลเชลล์ของคุณเป็นเวลาหนึ่งนาที - กล่าวได้ว่าจะได้รับบางสิ่งจากประวัติของคุณ - จากนั้น Enter~ Ctrl+ Zเพื่อส่งไคลเอ็นต์ ssh ไปยังคิวงานพื้นหลังของเชลล์โลคัลของคุณจากนั้นfgเป็นเรื่องปกติที่จะเรียกคืน

แก้ไข:เมื่อจัดการกับเซสชัน SSH ที่ซ้อนกันคุณสามารถเพิ่มอักขระ tilde หลายตัวเพื่อแยกเซสชั่น SSH หนึ่งในห่วงโซ่เท่านั้น แต่เก็บไว้อื่น ๆ ตัวอย่างเช่นหากคุณซ้อนกันใน 3 ระดับ (เช่นคุณ ssh จาก local-> Machine1-> Machine2-> Machine3) คุณEnter~.จะได้รับการกลับสู่เซสชั่นท้องถิ่นของคุณจะทำให้คุณอยู่ใน Machine1 Enter~~.และEnter~~~.จะทำให้คุณอยู่ใน Machine2 . วิธีนี้ใช้ได้กับลำดับ escape อื่นเช่นกันเช่นการย้ายเซสชัน ssh ไปที่พื้นหลังเป็นการชั่วคราว ด้านบนใช้ได้กับทุกระดับของการทำรังเพียงแค่เพิ่มเครื่องหมายตัวหนอนมากขึ้น

สุดท้ายคุณสามารถใช้Enter~?เพื่อพิมพ์เมนูช่วยเหลือของคำสั่ง escape ที่มีอยู่

TL; DR - คำสั่ง escape ที่สนับสนุนคือ escape sequences ที่สนับสนุน:

 ~.   - terminate connection (and any multiplexed sessions)
 ~B   - send a BREAK to the remote system
 ~C   - open a command line
 ~R   - request rekey
 ~V/v - decrease/increase verbosity (LogLevel)
 ~^Z  - suspend ssh
 ~#   - list forwarded connections
 ~&   - background ssh (when waiting for connections to terminate)
 ~?   - this message
 ~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

11
+1 สำหรับการรู้รหัสผ่าน dodecatouple-secret-probation สำหรับการถ่ายภาพ sshd ที่หัว คุณรู้เกี่ยวกับมันในแบบเดียวกับที่ฉันทำ (พิมพ์ผิด~/.somethingorotherหลังจากกดปุ่ม Enter)?
voretaq7

2
@ voretaq7: ไม่ฉันไม่ได้ฉลาดขนาดนั้น แต่เมื่อมีคนแย้มฉันในตัวฉันฉันก็ไปว่า "จริงเหรอ? นั่นเป็นสิ่งที่เกิดขึ้นตลอดเวลาที่เปลือกของฉันเพิ่งไปถึงกรุงเทพ! . มันไม่ใช่ลำดับทั่วไปยกเว้นในแบบที่คุณเอ่ยถึง แต่มันอาจเกิดขึ้นได้
คาเลบ

14
เพราะ "ความลับ" เขาหมายถึง "ในหน้าคน"
larsks

4
ในขณะที่หลายคนไม่ทราบเกี่ยวกับเรื่องนี้มันเป็นความลับในมุมมองธรรมดา man sshครอบคลุมสิ่งนี้ภายใต้ESCAPE CHARACTERSส่วน ~.(ตัดการเชื่อมต่อ) และ~^Z(background ssh) นั้นมีประโยชน์มาก
Stefan Lasiewski

9
แน่นอนมันอยู่ใน man page :) ฉันใช้คำว่า secret เพราะ OP ทำและฉันใช้ลิ้นเป็นแก้ม ปัญหาของฟีเจอร์นี้คือผู้คนไม่รู้ว่าจะมองหาที่ไหนพวกเขาคาดหวังว่าตัวละครควบคุมและสัญญาณดังกล่าวจะเป็นส่วนหนึ่งของเชลล์หรือเช่นนั้น เมื่อคุณรู้ว่าจะต้องดูหรือถามว่ามันอยู่ตรงไหน
Caleb

12

SSH ให้ความสะดวกสบาย เพิ่มสิ่งต่อไปนี้ในพื้นที่ของคุณ~/.ssh/config(สร้างหากไม่มี):

ServerAliveInterval 15
ServerAliveCount 3

การตั้งค่านี้จะสร้างสัญญาณแบบ keep-alive ที่ส่งทุกๆ 15 วินาทีผ่านอุโมงค์ที่ปลอดภัย หลังจากสามความล้มเหลวติดต่อกันไคลเอนต์ SSH จะออกจาก

โปรดทราบว่าในบางระบบ (รวมถึง macOS 10.14) แทนที่จะต้องมี:

ServerAliveInterval 15
ServerAliveCountMax 3

นำมาจากคำตอบนี้เมื่อ ask.ubuntu: https://askubuntu.com/a/29967/30266


9

ความจริงที่ว่ามันแฮงค์เป็นหน้าที่ของ TCP ไม่ใช่ SSH แอปพลิเคชันไม่มีทางรู้ได้ว่าเซสชัน / การเชื่อมต่อ TCP ถูกตัดออกเว้นแต่ว่า TCP แจ้งแอปพลิเคชันโดยใช้การเชื่อมต่อที่ไม่มีการเชื่อมต่ออีกต่อไป จากมุมมองของแต่ละโฮสต์เซสชัน TCP ยังคงอยู่ในสถานะที่ยอมรับและไม่มีอะไรจะพูดได้ว่าเซสชันที่ไม่มีการใช้งานนาน (ไม่มีการไหลของข้อมูล) ไม่ถูกต้องนอกเหนือจาก RST หรือขาดการตอบสนองต่อแพ็คเก็ต TCP keepalive ไม่ได้นำไปใช้ในระดับสากล) นั่นไม่ได้เป็นข้อบกพร่องใน SSH สำหรับฉันฉันคาดหวังว่าพฤติกรรม


5

หากการเชื่อมต่อถูกพักสายอย่างถูกต้องการกดแป้นวิเศษใด ๆ จะไม่ผ่านเนื่องจากการเชื่อมต่อหยุดทำงานก่อนที่คุณจะกดปุ่ม คุณสามารถบอกให้ไคลเอ็นต์ยกเลิก แต่จะไม่ส่งผลกระทบต่อประวัติที่เก็บ (หรือไม่) ที่ส่วนท้ายของเซิร์ฟเวอร์

ขณะนี้ไม่ได้ตอบคำถามมันอาจช่วยลดผลกระทบของการเชื่อมต่อแฮงค์: เมื่อฉันทำงานจากระยะไกล (และมักจะเมื่อฉันไม่) ฉันทำงานผ่านscreen(มีหรือไม่มีbyobuเสื้อคลุมขึ้นอยู่กับความพร้อม) ดังนั้นหากมีการเชื่อมต่อใด ๆ ที่ทำให้เซสชันของฉันกับประวัติทั้งหมดถูกเก็บรักษาไว้และพร้อมใช้งานในสถานะที่ฉันทิ้งไว้เมื่อฉันเชื่อมต่อใหม่


6
ข้อเสนอแนะของคุณเกี่ยวกับหน้าจอนั้นใช้ได้ แต่บิตแรกไม่สามารถใช้ได้กับปัญหา คุณไม่จำเป็นต้องได้รับกุญแจผ่านไปยังด้านระยะไกลคุณเพียงแค่ต้องส่งกุญแจเหล่านั้นไปยังไคลเอนต์ LOCAL! OP ต้องการของเปลือกท้องถิ่นของเขากลับมารวมถึงประวัติ SSH รับช่วงต่อไปและไม่ตอบสนองต่อการหยุดพักตามปกติเช่น CTRL-C เพราะผ่านไปแล้ว มีวิธีการผ่านและยกเลิกลูกค้าท้องถิ่นดูคำตอบของฉัน โดยทั่วไปแล้วจะมีการเก็บประวัติท้ายเครื่องไว้หากคุณเข้าสู่ระบบอีกครั้งทั้งนี้ขึ้นอยู่กับการกำหนดค่าของเชลล์
คาเลบ

2
@Caleb: คำถามที่กล่าวถึงการสูญเสียประวัติโดยเฉพาะและประวัติคำสั่งจะถูกเก็บไว้ฝั่งเซิร์ฟเวอร์ ในการบอกเซิร์ฟเวอร์ให้ทำสิ่งที่แตกต่างกับประวัติคุณต้องได้รับข้อความไปยังเซิร์ฟเวอร์เพื่อบอกให้เซิร์ฟเวอร์ทำสิ่งที่แตกต่างกับประวัติ แน่นอนมีวิธีการทำทุบตี (และบางหอยอื่น ๆ ) สายประวัติศาสตร์บันทึกทันทีแทนที่จะเก็บพวกเขาในแรมจนกว่าผู้ใช้จะต้องมีอยู่ในเปลือกหอยที่มีexit/ ซึ่งจะช่วยแก้ปัญหาประวัติศาสตร์โดยไม่ต้องใช้logout screen
David Spillett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.