Màn hình, hoặc tương tự, để tự động nối lại kết nối ssh không ổn định


18

Tôi thường phải kết nối với máy chủ qua ssh trong môi trường wifi không đáng tin cậy. Trên máy chủ, tôi chạy màn hình, vì vậy nếu tôi bị ngắt kết nối, tôi có thể kết nối lại và tiếp tục phiên màn hình, và chọn nơi tôi rời đi, nhưng mất kết nối vẫn là một khoảng thời gian lớn: nếu kết nối bị mất trong khi tôi Trên máy chủ, cửa sổ đầu cuối có xu hướng đóng băng. Tôi phải hủy tab đó, mở một cái mới, ssh lại máy chủ và tiếp tục phiên màn hình. Tôi đã thử điều này với màn hình đang chạy trên máy chủ và màn hình cục bộ. Dù bằng cách nào, nó có xu hướng đóng băng khi kết nối bị mất.

Có cách nào tôi có thể có một cái gì đó tương tự như màn hình, hoặc có thể là màn hình, nó sẽ tự động cố gắng kết nối lại và duy trì phiên chạy, vì vậy tôi không phải tiếp tục kết nối lại bằng tay? Thông thường khi tôi mất kết nối, tôi nghĩ rằng nó chỉ trong một khoảng thời gian rất ngắn - có thể ít hơn một giây.

Tôi đang sử dụng Ubuntu 14.04 LTS, phiên bản MATE. cảm ơn


4
Re "cửa sổ shell có xu hướng đóng băng": Đó là vì ssh cục bộ của bạn không biết kết nối đã chết. Nhấn <Enter>và gõ ~.để yêu cầu phía bạn bỏ kết nối và bạn chỉ cần lặp lại lệnh ssh cuối cùng để kết nối lại (ví dụ: với mũi tên lên hoặc !!).
alexis

@alexis nghe có vẻ như là một cách nhanh hơn để kết nối lại, cảm ơn! Tôi muốn nó tự động xảy ra mặc dù ...
Max Williams

Câu trả lời:


23

Bạn có thể xem bằng cách sử dụng mosh: https://mosh.org/

Bạn có thể thiết lập máy chủ 'nhảy' với kết nối internet đáng tin cậy mà bạn sử dụng moshđể kết nối, sau đó có sshphiên tới từng máy chủ mà bạn quản lý. Lý do tôi khuyên bạn nên sử dụng máy chủ nhảy là bạn có thể không muốn cài đặt moshtrên máy chủ bạn đang quản lý.

Một ưu điểm khác moshlà nó dựa trên UDP chứ không phải TCP và phiên của bạn có thể tồn tại khi thay đổi địa chỉ IP, ví dụ: đi từ WiFi sang kết nối internet di động.

Chỉ cần làm cho nó rõ ràng, moshkhông phải là một thay thế cho screen, mà là ssh. Nó vẫn là một ý tưởng tốt để sử dụng screenvới nó, vì moshbản thân nó không cung cấp cách kết nối lại với phiên của bạn nếu khách hàng chết vì một số lý do.


Cảm ơn, nó chỉ là một máy chủ (hầu hết thời gian) và chúng tôi sở hữu nó vì vậy tôi có thể cài đặt Mosh. Tôi sẽ kiểm tra.
Max Williams

Trên thực tế, nó chỉ ra rằng vì máy chủ của chúng tôi khá cũ (hoặc chạy Ubuntu cũ mà tôi nên nói) nên quá khó để cài đặt. :(
Max Williams

@MaxWilliams bao nhiêu tuổi? Ngay cả LTS 12.4 đã hết hỗ trợ. Và tại sao bạn không thử tự biên dịch nó
phuclv

Khi tôi đọc tài liệu mosh, bạn cần máy chủ mosh trên mỗi máy chủ bạn định quản lý từ xa. Tuy nhiên, chắc chắn thú vị.
tự đại diện

1
Kết nối với thiết bị đầu cuối tmux qua mosh là giải pháp ổn định nhất đối với tôi.
Nemo

3

Tôi đã sử dụng tmuxmột vài năm nay và theo kinh nghiệm của tôi, nó tự động kết nối lại. Ít nhất là khi kết nối chỉ bị lỗi trong một thời gian tương đối ngắn. Lưu ý rằng tôi thực sự sử dụng byobuvới tmux là phụ trợ. Tôi không biết nếu vững mạnh đây là một tính năng của tmuxhoặc byobuhoặc thậm chí của sự kết hợp của cả hai, nhưng tôi đề nghị bạn cung cấp cho cả một thử.

Tôi kết nối từ cài đặt Arch cục bộ của mình với các máy chủ Ubuntu từ xa khác nhau thông qua VPN. Tôi đã kiểm tra nó ngay bây giờ bằng cách rút cáp mạng trong khi tôi được kết nối với điều khiển từ xa. Phiên bị treo, nhưng ngay sau khi cáp của tôi được cắm lại, nó đã hoạt động trở lại một cách liền mạch.

Tuy nhiên, khi tôi kiểm tra bằng cách khởi động lại bộ định tuyến của mình, kết nối không trở lại. Tôi cho rằng nó có liên quan đến thời gian mạng ngừng hoạt động, nhưng dường như nó sẽ kết nối lại nếu chỉ mất vài giây.

Trong trường hợp có liên quan, tôi thực hiện tất cả điều này bằng cách sử dụng terminatortrình giả lập thiết bị đầu cuối của mình.

Cả ba đều có sẵn trong kho Ubuntu:

sudo apt-get install tmux terminator byobu

Tuy nhiên, tôi không chắc chắn rằng một trong hai tmuxhoặc byobutốt hơn trong việc xử lý ngắt kết nối ssh. Tôi chỉ biết rằng theo kinh nghiệm của tôi, họ thường quay lại sau khi mất kết nối ngắn. Điều đó có thể là xuống các khía cạnh khác trong cấu hình của tôi mặc dù.


1
Khi bạn khởi động lại bộ định tuyến của mình, bạn có thể đã được cung cấp một địa chỉ IP công cộng khác, điều này sẽ phá vỡ tcpkết nối. Từ kinh nghiệm của tôi sshcó thể rất kiên cường đến việc bỏ mạng không liên tục, tôi không nghĩ rằng điều này có liên quan đến thực tế bạn đang sử dụng tmuxbên trong sshcửa sổ.
shackleford rỉ sét ngày

3
Tôi cũng sẽ nói như vậy: ngay cả với SSH đơn giản, bạn có thể xử lý một sự ngắt kết nối ngắn, miễn là kết nối TCP không chết. Mà nó có thể, nếu giao diện của bạn được tắt máy, hoặc một số bộ định tuyến quá hăng hái giết nó (router NAT có thể quên tình trạng NAT trên khởi động lại, và phá vỡ các kết nối hiện có), hoặc ClientAlive/ ServerAlivetrigger, hoặc ... Tôi không có ý kiến gì byobukhông, mặc dù .
ilkkachu

Có, nhưng OP dường như bị đóng băng trong bất kỳ lỗi kết nối nào, trong khi tôi thì không. Nhưng vâng, bạn nói đúng, tôi cũng thấy điều này với ssh đơn giản và không có tmux. Tuy nhiên, có lẽ màn hình không thể đối phó với nó?
terdon

2
@MaxWilliams tmuxvề cơ bản là một sự thay thế hiện đại hơn screen, vâng. Khi tôi mới bắt đầu làm việc như bây giờ và cần loại điều này, việc đọc chữ thảo của tôi cho thấy đó tmuxlà sự lựa chọn tốt hơn trong những ngày này. Tôi cũng không chắc chắn 100% rằng nó có khả năng quản lý tốt hơn các kết nối bị mất, tất cả những gì tôi biết là nó sẽ phục hồi sau khi bị mất điện trong thời gian ngắn. Cho dù đó là xuống tmuxhoặc cái gì khác, tôi không biết. Nhưng có vẻ đáng để thử :). Byobu về cơ bản là một lối vào màn hình / tmux, không phải là trình giả lập thiết bị đầu cuối GUI. Nó cực kỳ hữu ích mặc dù: byobu.org
terdon

2
tmux không làm gì về việc ngắt kết nối. Nó hoạt động với thiết bị đầu cuối được cung cấp bởi ssh. Tất cả đứng và rơi với kết nối ssh.
Jonas Schäfer

2

Sử dụng ServerAlivecác tùy chọn của ssh để phát hiện khi kết nối không thành công.

ServerAliveCountMax
Đặt số lượng tin nhắn còn sống của máy chủ (xem bên dưới) có thể được gửi mà không ssh (1) nhận bất kỳ tin nhắn nào từ máy chủ. Nếu đạt đến ngưỡng này trong khi tin nhắn còn sống của máy chủ đang được gửi, ssh sẽ ngắt kết nối với máy chủ, chấm dứt phiên. Điều quan trọng cần lưu ý là việc sử dụng các thông điệp còn sống của máy chủ rất khác so với TCPKeepAlive (bên dưới). Các thông điệp còn sống của máy chủ được gửi qua kênh được mã hóa và do đó sẽ không thể giả mạo được. Tùy chọn giữ lại TCP được kích hoạt bởi TCPKeepAlive là giả mạo. Cơ chế sống của máy chủ có giá trị khi máy khách hoặc máy chủ phụ thuộc vào việc biết khi nào kết nối không hoạt động.

Giá trị mặc định là 3. Ví dụ: ServerAliveInterval (xem bên dưới) được đặt thành 15 và ServerAliveCountMax được đặt ở mặc định, nếu máy chủ không phản hồi, ssh sẽ ngắt kết nối sau khoảng 45 giây.

ServerAliveInterval
Đặt khoảng thời gian chờ tính bằng giây sau đó nếu không nhận được dữ liệu từ máy chủ, ssh (1) sẽ gửi tin nhắn qua kênh được mã hóa để yêu cầu phản hồi từ máy chủ. Mặc định là 0, cho biết những tin nhắn này sẽ không được gửi đến máy chủ.

Vì vậy, nếu bạn đặt ServerAliveIntervalthành 5, sshsẽ tự động ngắt kết nối nếu mạng bị ngắt trong 15 giây.


Để phá vỡ một phiên SSH bằng vũ lực, tôi nhấn ~.(hoặc đầu tiên là Enter, sau đó ~.) bao gồm: ký tự thoát ~và lệnh phá phiên.
imz - Ivan Zakharyaschev

@ imz - IvanZakharyaschev Giả sử bạn có thể nói rằng kết nối bị treo. Sử dụng thủ tục của SSH sẽ tự động phát hiện lỗi.
Barmar

Điều đó nghe có vẻ rất hữu ích, cảm ơn, tôi chắc chắn sẽ thử rằng lần tới khi tôi ở trong "vùng dễ vỡ".
Max Williams

@Barmar Vâng, đúng. Tôi cũng đã nghĩ về vấn đề xác định xem kết nối có thực sự bị treo hay tôi nhấn một cái gì đó có thể vô tình gửi các phím này đến phía xa ... Và tôi không biết một giải pháp tốt.
imz - Ivan Zakharyaschev

2

Trong các điều kiện tương tự, tôi có xu hướng sử dụng eshellvới TRAMP (trên ssh) bên trong Emacs. TRAMP đảm nhiệm việc kết nối lại khi cần thiết mà không gây ra nhiều rắc rối cho tôi khi đưa ra các lệnh mong muốn cho shell từ xa.

Tuy nhiên, eshell không tốt như một thiết bị đầu cuối, tức là, để chạy các lệnh làm điều gì đó đặc biệt với thiết bị đầu cuối hoặc chạy trong một khoảng thời gian đáng kể liên tục (tăng dần) in một cái gì đó ra.

Về cơ bản, khá đơn giản để bắt đầu sử dụng nó trong Emacs với TRAMP:

M-x eshell
cd /user@host:

1

Khước từ

Nếu kết nối SSH của bạn không tồn tại trong thời gian ngừng hoạt động mạng ngắn, thì có một điều khác xảy ra là không cho phép sshvà TCP làm việc bình thường.

Xem bên dưới để biết chi tiết. Dù sao:

Giải pháp không phụ thuộc nhanh nhất và bẩn nhất

Tạo một kịch bản shell như thế này:

#!/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"

Điều này sẽ chỉ chạy một vòng lặp đơn giản ngu ngốc mà cố gắng kết nối sshvà gắn vào screen. Vượt qua máy chủ lưu trữ hoặc bất cứ điều gì khác mà bạn thường chuyển đến sshlời gọi của mình dưới dạng đối số dòng lệnh.

Việc kết nối lại chỉ dựa trên việc SSH có báo lỗi với kết nối hay không, điều đó có nghĩa là nó không có trí thông minh để phát hiện các lỗi không phải SSH như "bạn thực sự không bật WiFI" hay bất cứ điều gì, nhưng điều đó có lẽ không quan trọng bạn.

Tôi giả sử bạn có ssh-agenthoặc một khóa SSH không có cụm mật khẩu sẽ cho phép kết nối lại chỉ hoạt động mà không cần thêm đầu vào từ bạn.

Sẽ có một điều kiện cuộc đua nhỏ mà nếu bạn đánh ^Ctrong một phần không thể nhận ra của con người trong một giây trong khi kết nối lại, bạn có thể sẽ giết chết tập lệnh thay vì chuyển ^Cqua thiết bị đầu cuối của khách hàng, vì vậy nếu bạn nghi ngờ bị treo kết nối Đừng ^Cquá nhiệt tình.

Giải pháp phần mềm bổ sung đơn giản nhất

Bạn có thể thử các chương trình autossh , mà nên có sẵn trong kho gói Ubuntu của bạn.

Nếu bạn cần xây dựng từ nguồn hoặc kiểm toán nó, thì đó là một chương trình C duy nhất biên dịch mà không có bất kỳ thư viện bổ sung nào, dường như có nhiều thông tin hơn về việc kiểm tra sự sống động của kết nối so với hack của tôi ở trên nó cũng có một rscreenlệnh script thuận tiện tự động -cách để screen.

Chi tiết

Làm thế nào sshbình thường phục hồi

Chỉ để xác minh, vì tôi không thích nói những điều mà không tự kiểm tra, tôi đã chạy thử một chút trước khi trả lời:

Tôi đã kết nối WiFi với thiết bị Linux, tạo kết nối SSH với thiết bị khác trong mạng LAN của mình, xác minh rằng tôi có sshkết nối hoạt động với đầu bên kia (có thể chạy các lệnh, v.v.), sau đó trên máy khách ngắt kết nối WiFi (gây ra giao diện để được định cấu hình: không có thêm địa chỉ IP), nhập thêm một loạt ký tự vào phiên ssh (tất nhiên không có phản hồi) và sau đó kết nối lại với WiFi của tôi - kết nối lại thực sự thất bại ít nhất một lần do tín hiệu xấu và các yếu tố khác , sau đó cuối cùng đã kết nối lại: Tôi đợi khoảng năm giây để sshphiên phục hồi, không có gì xảy ra nên tôi nhấn thêm một phím và sshphiên ngay lập tức trở lại, với tất cả các phím mà tôi đã gõ trong khi ngắt kết nối xuất hiện trên dòng lệnh.

Hãy xem, sshchỉ ghi / đọc vào ổ cắm mạng TCP cho đến khi HĐH báo lỗi, và TCP thực sự rất chịu đựng sự sụt giảm kết nối kéo dài.

Còn lại với các thiết bị của riêng nó với cài đặt kernel mặc định, ngăn xếp TCP trong Linux sẽ vui vẻ chấp nhận kết nối hoàn toàn im lặng trong nhiều phút trước khi tuyên bố kết nối bị chết và báo lỗi ssh- đến lúc cuối cùng chúng ta nói chuyện trong sân bóng trong khoảng 30 phút, hoặc ít nhất là chắc chắn đủ lâu để tồn tại lâu hơn các trục trặc kết nối kéo dài một giây hoặc một phút.

Tuy nhiên, bên dưới vỏ bọc, ngăn xếp TCP TCP sẽ dần dần lấy lại các tin nhắn với độ trễ dài hơn và lâu hơn, điều đó có nghĩa là vào thời điểm kết nối của bạn quay trở lại, bạn có thể sẽ xem xét độ trễ bổ sung trước khi sshphiên của bạn dường như "sống lại".

Tại sao điều này đôi khi phá vỡ

Thường thì một cái gì đó đang tích cực khiến kết nối đóng lại sau một khoảng thời gian không hoạt động ngắn hơn đáng kể so với số lượng mà ngăn xếp TCP sẽ chịu đựng, và sau đó không báo cáo trạng thái kết nối đó cho sshkhách hàng của bạn .

Các ứng viên có khả năng bao gồm:

  1. Tường lửa hoặc bộ định tuyến NAT, phải sử dụng bộ nhớ để ghi nhớ từng kết nối TCP trực tiếp - như một tối ưu hóa và giảm thiểu chống lại các cuộc tấn công của DOS, đôi khi chúng sẽ quên kết nối của bạn và sau đó âm thầm bỏ qua các gói tin do đó, vì các gói trong ở giữa một kết nối khi bạn không nhớ kết nối hiện tại trông không hợp lệ.

  2. Tường lửa / bộ định tuyến hoạt động tốt hơn sẽ tiêm gói TCP RST, thường biểu hiện dưới dạng connection reset by peerthông báo lỗi, nhưng gói đặt lại là lỗi và do đó, nếu kết nối đến máy khách của bạn vẫn gặp sự cố tại thời điểm đó và làm mất đặt lại gói quá, khách hàng của bạn sẽ nghĩ rằng kết nối vẫn còn sống.

  3. Bản thân máy chủ có thể có chính sách tường lửa để âm thầm loại bỏ các gói không mong muốn, điều này sẽ phá vỡ các nỗ lực nối lại kết nối của máy khách bất cứ khi nào máy chủ nghĩ rằng kết nối bị đóng nhưng máy khách thì không: máy khách của bạn tiếp tục cố gắng tiếp tục kết nối, nhưng máy chủ chỉ là bỏ qua nó bởi vì không có kết nối trực tiếp mà các gói này thuộc về trạng thái tường lửa của máy chủ.

    Vì bạn đang chạy Linux, hãy kiểm tra cẩn thận máy chủ của bạn iptables/ ip6tables(hoặc nftnếu bạn đang sử dụng công cụ mới) để biết chính xác những gì bạn cho phép so với việc bỏ. Việc cho phép các gói mới / thành lập / liên quan trên cổng TCP SSH, nhưng không phổ biến là rất phổ biến - nếu bạn bỏ âm thầm mọi thứ không được phép, thiết lập chung này có thể gây ra các loại đóng băng này sau các sự cố kết nối ngắn .

  4. Bản thân máy chủ SSH của bạn có thể được cấu hình để đóng kết nối sau một thời gian không hoạt động, sử dụng một trong các tùy chọn OpenSSH cho các gói giữ lại máy khách TCP hoặc SSH. Chính nó, điều này sẽ không gây ra treo cổ vô thời hạn, nhưng nó có thể đưa bạn vào một trong những trạng thái được mô tả ở trên.

  5. Có thể bạn chỉ không dành đủ thời gian để "gỡ rối" sau khi bạn vào trạng thái nơi sshphiên của bạn bị treo.

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.