Tại sao bàn giao tiếp đôi khi bị treo vĩnh viễn khi kết nối SSH bị hỏng?


89

Tôi đã thấy điều này với rất nhiều máy chơi game (trên Linux, Mac, ...) và với rất nhiều máy khác nhau trong nhiều mạng khác nhau. Tôi không bao giờ có thể xác định chính xác lý do, tại sao điều này xảy ra: Tất cả những gì bạn phải làm là đăng nhập vào máy thông qua SSH. Nếu kết nối bị ngắt vì một số lý do (vì đơn giản, giả sử cáp mạng đã bị kéo), thì đôi khi bảng điều khiển chỉ bị treo vĩnh viễn - vào thời điểm khác, nó chỉ thoát ra khỏi vỏ cha mẹ.

Thật khó chịu khi điều này xảy ra (ví dụ: bạn mất lịch sử lệnh.) Có thể có một phím tắt bí mật có thể buộc thoát ra (Ctrl-C hoặc Ctrl-D không hoạt động)? Và lý do cho "lỗi" ngẫu nhiên này trên tất cả các triển khai là gì?


Chủ đề này có vẻ thích hợp để đề cập đến Mosh (Mobile Shell) xử lý tốt các lỗi kết nối, bao gồm chuyển vùng (thay đổi IP) và các nội dung khác.
Ciprian Tomoiagă

Câu trả lời:


137

Có một phím tắt "bí mật" để buộc thoát: ~) Từ phiên bị đóng băng, nhấn các phím này theo thứ tự: Enter~.Dấu ngã (chỉ sau một dòng mới) được máy khách ssh nhận ra là một chuỗi thoát khách hàng chấm dứt hoạt động kinh doanh mà không cần phải quảng cáo thêm.

Hành vi kéo dài về các vấn đề giao tiếp không phải là một lỗi, phiên SSH đang diễn ra với hy vọng phía bên kia sẽ quay lại. Nếu mạng bị hỏng, đôi khi thậm chí vài ngày sau bạn có thể lấy lại phiên SSH. Tất nhiên bạn có thể đặc biệt bảo nó bỏ cuộc và chết với trình tự trên. Ngoài ra còn có nhiều cách khác nhau bạn có thể làm như đặt thời gian chờ duy trì trong máy khách của mình để nếu nó không có liên kết hoạt động trong một khoảng thời gian nhất định thì nó sẽ tự tắt, nhưng hành vi mặc định là giữ nguyên kết nối càng tốt!

Chỉnh sửa: Một ứng dụng hữu ích khác của khóa ngắt này là thu hút sự chú ý của ứng dụng khách ssh cục bộ và đặt nền tảng đó để quay lại trình bao cục bộ của bạn trong một phút. Enter~ Ctrl+ Zđể gửi ứng dụng khách ssh đến hàng đợi công việc nền của shell cục bộ của bạn, sau đó fgnhư bình thường để lấy lại.

Chỉnh sửa: Khi xử lý các phiên SSH lồng nhau, bạn có thể thêm nhiều ký tự dấu ngã để chỉ thoát ra khỏi một trong các phiên SSH trong chuỗi, nhưng giữ lại các phiên khác. Ví dụ: nếu bạn được lồng trong 3 cấp độ, (ví dụ: bạn ssh từ local-> Machine1-> Machine2-> Machine3), Enter~.sẽ đưa bạn trở lại phiên cục bộ, Enter~~.sẽ đưa bạn vào Machine1 và Enter~~~.sẽ đưa bạn vào Machine2 . Điều này cũng hoạt động cho các chuỗi thoát khác, chẳng hạn như di chuyển phiên ssh sang nền tạm thời. Các công việc trên cho mọi cấp độ lồng nhau, chỉ bằng cách thêm nhiều dấu ngã.

Cuối cùng, bạn có thể sử dụng Enter~?để in menu trợ giúp của các lệnh thoát có sẵn.

TL; DR - các lệnh thoát được hỗ trợ là các chuỗi thoát được hỗ trợ:

 ~.   - 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 để biết mật khẩu quản chế bí mật-dodecatouple để chụp sshd trong đầu. Bạn có phát hiện ra điều đó giống như tôi đã làm ( ~/.somethingorothernhập sai sau khi nhấn enter) không?
voretaq7

2
@ voretaq7: Không, tôi không phải là thông minh, nhưng khi ai đó đã làm đầu mối cho tôi trong tôi đã đi "?!? Thật Vì vậy, đó là những gì đã xảy ra tất cả những lần vỏ của tôi chỉ đi BANG không có lý do khi tôi đã gõ" . Đây không phải là một trình tự phổ biến, ngoại trừ trong những sai lầm của người bạn đề cập, nhưng nó có thể xảy ra.
Caleb

14
Trong đó "bí mật" anh ấy có nghĩa là "trong trang người đàn ông".
larsks

4
Mặc dù nhiều người không biết về điều này, nhưng đây thực sự là một bí mật. man sshbao gồm điều này dưới ESCAPE CHARACTERSphần. ~.(Ngắt kết nối) và ~^Z(ssh nền) rất tiện dụng.
Stefan Lasiewski

9
Tất nhiên đó là trong trang người đàn ông :) Tôi chỉ sử dụng từ bí mật vì OP đã làm, và tôi đã sử dụng lưỡi trong má. Vấn đề với tính năng này là mọi người không biết tìm nó ở đâu, họ mong đợi các ký tự điều khiển và các tín hiệu như vậy là một phần của vỏ hoặc như vậy. Một khi bạn biết nơi để tìm hoặc thậm chí những gì cần hỏi, tất nhiên nó ở đó.
Caleb

12

SSH cung cấp một cơ sở duy trì sự sống. Thêm phần sau vào địa phương của bạn ~/.ssh/config(tạo nếu nó không tồn tại):

ServerAliveInterval 15
ServerAliveCount 3

Cài đặt này sẽ thiết lập tín hiệu duy trì được gửi cứ sau 15 giây thông qua đường hầm an toàn. Sau ba lần thất bại liên tiếp, máy khách SSH sẽ thoát.

Lưu ý rằng trên một số hệ thống (bao gồm macOS 10.14) thay vào đó, nó cần phải là:

ServerAliveInterval 15
ServerAliveCountMax 3

Lấy từ câu trả lời này trên Ask.ubfox: https://askubfox.com/a/29967/30266


9

Thực tế là nó bị treo là một chức năng của TCP, không phải SSH. Ứng dụng không có cách nào để biết rằng phiên / kết nối TCP đã bị cắt đứt trừ khi TCP thông báo cho ứng dụng bằng kết nối rằng kết nối không còn tồn tại. Từ góc nhìn của mỗi máy chủ, phiên TCP vẫn ở trạng thái Đã thiết lập và không có gì để nói rằng phiên nhàn rỗi dài (không có luồng dữ liệu) không hợp lệ ngoài RST hoặc thiếu phản hồi đối với gói giữ TCP (mà không được thực hiện phổ biến). Điều đó dường như không phải là một lỗi trong SSH đối với tôi, tôi mong đợi hành vi đó.


5

Nếu kết nối được treo đúng cách, bất kỳ tổ hợp phím ma thuật nào sẽ không được thông qua vì kết nối đã được treo trước khi bạn nhấn phím. Bạn có thể yêu cầu khách hàng chấm dứt nhưng điều này sẽ không ảnh hưởng đến lịch sử được lưu giữ (hoặc không) ở cuối máy chủ.

Mặc dù điều này không thực sự trả lời câu hỏi nhưng nó có thể giúp giảm tác động của việc treo kết nối: khi tôi làm việc từ xa (và thậm chí thường là khi tôi không) Tôi chạy qua screen(có hoặc không có byobutrình bao bọc tùy thuộc vào tính khả dụng của nó) để nếu có bất kỳ loại kết nối nào làm giảm phiên của tôi, với tất cả lịch sử của nó, sẽ được giữ nguyên và có sẵn ở trạng thái tôi rời khỏi nó khi tôi kết nối lại.


6
Đề xuất của bạn về màn hình là tốt, nhưng bit đầu tiên thực sự không thể áp dụng cho vấn đề này. Bạn không cần phải lấy chìa khóa đến phía xa, bạn chỉ phải đưa chúng đến máy khách ssh ĐỊA PHƯƠNG! OP muốn vỏ của mình trở lại bao gồm cả lịch sử. SSH tiếp nhận nó và không đáp ứng với các chuỗi ngắt thông thường như CTRL-C vì nó vượt qua các chuỗi đó. Có một cách để vượt qua và chấm dứt khách hàng địa phương, xem câu trả lời của tôi. Lịch sử ở đầu cục bộ thường được giữ bằng mọi cách nếu bạn đăng nhập lại, tùy thuộc vào cấu hình shell.
Caleb

2
@Caleb: câu hỏi đề cập cụ thể đến việc mất lịch sử và lịch sử lệnh được lưu trữ phía máy chủ. Để yêu cầu máy chủ làm bất cứ điều gì khác với lịch sử, bạn cần nhận một thông báo đến máy chủ để bảo nó làm điều gì đó khác với lịch sử. Tất nhiên, có nhiều cách để tạo bash (và một số shell khác) ghi lại các dòng lịch sử ngay lập tức thay vì thu thập chúng trong RAM cho đến khi người dùng tồn tại đúng vỏ với exit/ logoutsẽ giải quyết vấn đề lịch sử mà không cần sử dụng screen.
David Spillett
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.