Làm thế nào để tạo một tập lệnh bash để kiểm tra kết nối SSH?


86

Tôi đang trong quá trình tạo tập lệnh bash để đăng nhập vào các máy từ xa và tạo khóa riêng tư và khóa công khai.

Vấn đề của tôi là các máy từ xa không đáng tin cậy lắm và chúng không phải lúc nào cũng hoạt động. Tôi cần một tập lệnh bash sẽ kiểm tra xem kết nối SSH có được thiết lập hay không. Trước khi thực sự tạo các khóa để sử dụng trong tương lai.


2
Thông thường, một người chạy ssh-keygenđể tạo một cặp khóa trên máy cục bộ, sau đó ssh-copy-idsao chép khóa công khai sang các máy từ xa. Có vẻ như bạn đang làm mọi thứ khác đi. Tại sao, mục tiêu của bạn là gì?
ephemient

1
Vì rõ ràng bạn đang thay đổi cách các máy từ xa thiết lập kết nối, hãy xem xét triển khai mosh . mosh.mit.edu Nó nhằm bổ sung SSH trên các kết nối không ổn định. Tôi có kinh nghiệm rất tốt với nó.
Aeyoun

@ephemient Tôi biết là hơi muộn, nhưng có vẻ khá đơn giản là khóa của họ không dành cho máy cục bộ hoặc không cho người dùng cục bộ.
Giỏ hàng bị bỏ rơi

Câu trả lời:


170

Bạn có thể kiểm tra điều này với giá trị trả về ssh cung cấp cho bạn:

$ ssh -q user@downhost exit
$ echo $?
255

$ ssh -q user@uphost exit
$ echo $?
0

CHỈNH SỬA: Một cách tiếp cận khác là sử dụng nmap (bạn sẽ không cần phải có khóa hoặc nội dung đăng nhập):

$ a=`nmap uphost -PN -p ssh | grep open`
$ b=`nmap downhost -PN -p ssh | grep open`

$ echo $a
22/tcp open ssh
$ echo $b
(empty string)

Nhưng bạn sẽ phải ghi lại thông báo (nmap không sử dụng giá trị trả về để hiển thị nếu một cổng được lọc, đóng hay mở).

EDIT2:

Nếu bạn quan tâm đến trạng thái thực tế của cổng ssh, bạn có thể thay thế grep openbằng egrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered'

Chỉ để được hoàn thành.


Để hoàn tất, bạn có thể cho biết mã trả về nào có nghĩa là thành công và mã nào có nghĩa là thất bại đối với SSH?
Henley Chiu

Tự hỏi điều gì sẽ xảy ra nếu nỗ lực SSH chỉ bị treo ở đó?
Sibbs cờ bạc vào

2
Câu trả lời chính xác! Tuy nhiên, bạn không đề cập đến việc cố gắng truy cập sshmáy chủ không thành công chỉ sau khoảng thời gian chờ là 60 giây - điều này có thể bị cấm đối với một số cách sử dụng. Ngoài ra, nếu tên máy chủ nếu được xác định trong ~/.ssh/config, sshcách tiếp cận đầu tiên hoạt động trong khi nmapcách thứ hai không thành công với Failed to resolve "<hostname>".
ssc

1
không có lời giải thích nào về các lệnh ... hoặc những gì bạn đang thực sự làm .. là $?gì? vv
Toskan

Một thậm chí ngắn gọn hơn hình thức # 1: ssh -q user@downhost exit | echo $? ống kết quả kết nối vào tiếng vang
philn5d

22
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK

2
Đầu ra một dòng: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" user@host.com "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | tail -n1
Xdg

21

Bạn có thể sử dụng một cái gì đó như thế này

$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

Điều này sẽ xuất ra "ok" nếu kết nối ssh ổn


14

Bổ sung phản hồi của @Adrià Cidrebạn có thể làm:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

if [[ $status == ok ]] ; then
  echo auth ok, do something
elif [[ $status == "Permission denied"* ]] ; then
  echo no_auth
else
  echo other_error
fi

7

Thử:

echo quit | telnet IP 22 2>/dev/null | grep Connected

1
Một vấn đề của phương pháp này là nó không nhận ra các máy chủ được xác định trong ssh_config (tức là / etc / ssh / config hoặc ~ / .ssh / config)
Ding-Yi Chen

1

sshLệnh dưới đây phải có mã thoát 0khi kết nối thành công và giá trị khác không.

ssh -q -o BatchMode=yes user@remote.com exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi

Tuyệt quá! Tôi cũng khuyến cáo thêm -o ConnectTimeout = 5, để thoát nhanh hơn trong trường hợp cổng đích được lọc.
Daniel

0

Chỉ trong trường hợp ai đó chỉ muốn kiểm tra xem cổng 22 có đang mở trên một máy từ xa hay không, lệnh netcat đơn giản này rất hữu ích. Tôi đã sử dụng nó vì nmap và telnet không có sẵn cho tôi. Hơn nữa, cấu hình ssh của tôi sử dụng xác thực mật khẩu bàn phím.

Nó là một biến thể của giải pháp do GUESSWHOz đề xuất.

nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"

0

Nếu bạn muốn kiểm tra thư mục từ xa có tồn tại hoặc bất kỳ tệp nào khác kiểm tra thực sự:

if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
    # exists
else
    # doesn't exist
fi

Đừng quên các dấu ngoặc kép trong "$(ssh ...)".


Điều này không trả lời câu hỏi. OP muốn kiểm tra xem kết nối SSH có thể được thiết lập hay không khi không kiểm tra tệp ở vị trí ssh từ xa.
Rakib Fiha

0

Để kết nối với một máy chủ có nhiều giao diện

ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.61;[ $? = 1 ] || ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.51

0

Ví dụ sử dụng tập lệnh BASH 4+:

# -- ip/host and res which is result of nmap (note must have nmap installed)
ip="192.168.0.1"
res=$(nmap ${ip} -PN -p ssh | grep open)

# -- if result contains open, we can reach ssh else assume failure) --
if [[ "${res}" =~ "open" ]] ;then
    echo "It's Open! Let's SSH to it.."
else
    echo "The host ${ip} is not accessible!"
fi

0

https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html

Liên kết trên là để tạo tập lệnh Python để kiểm tra kết nối. Bạn có thể sử dụng phương pháp tương tự và sử dụng:

ping -w 1 -c 1 "IP Address" 

Lệnh tạo tập lệnh bash.


2
Điều này sẽ chỉ ping IP từ xa. Không đảm bảo nếu có thể kết nối ssh.
RJ

Cảm ơn bạn đã chỉ ra điều đó, đây là mã cho ssh xlinu.blogspot.com/2019/09/… export user = "username" export pass = "password" export i = "hostname" export SSHPASS = $ pass sshpass -e ssh $ user @ $ i -q "echo $ i có thể truy cập được"
Dheeraj Kumar

-7

Tôi cảm thấy như bạn đang cố giải quyết vấn đề sai ở đây. Bạn không nên cố gắng làm cho các daemon ssh ổn định hơn? Thử chạy cái gì đó như monit , mà sẽ kiểm tra xem nếu daemon đang chạy và khởi động lại nó nếu nó chưa (đem lại cho bạn thời gian để tìm ra vấn đề gốc rễ đằng sau sshd ngừng hoạt động vào bạn). Hay là dịch vụ mạng rắc rối? Hãy thử nhìn vào man ifup. Có phải Toàn bộ Điều chết tiệt chỉ muốn đóng cửa với bạn? Chà, đó là một vấn đề lớn hơn ... hãy thử xem nhật ký của bạn (bắt đầu với nhật ký hệ thống) để tìm lỗi phần cứng hoặc dịch vụ đang tắt hộp của bạn (có thể là màn hình nhiệt độ?).

Làm cho các tập lệnh của bạn có khả năng chịu lỗi là rất tốt, nhưng bạn cũng có thể muốn làm cho khả năng chịu lỗi boxen của mình.


3
Sam: có những trường hợp sử dụng hợp lệ để tập lệnh kiểm tra nó. Ví dụ: (như tôi): Tôi có một công việc cron đang chạy trên máy tính của mình để sao lưu dữ liệu của tôi qua rsync vào nhà của tôi. Bây giờ tôi đang ở bên ngoài hoặc thậm chí bị ngắt kết nối khá thường xuyên và cần phải lên lịch lại nếu kết nối không khả dụng. Boxen của tôi chạy khá tốt, nhưng như người ta nói: nó luôn luôn là cáp (hay còn gọi là mạng)
stwissel
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.