จะสร้าง bash script เพื่อตรวจสอบการเชื่อมต่อ SSH ได้อย่างไร?


90

ฉันกำลังสร้างสคริปต์ทุบตีที่จะล็อกเข้าสู่เครื่องระยะไกลและสร้างคีย์ส่วนตัวและคีย์สาธารณะ

ปัญหาของฉันคือเครื่องระยะไกลไม่น่าเชื่อถือมากนักและไม่ได้ทำงานตลอดเวลา ฉันต้องการสคริปต์ทุบตีที่จะตรวจสอบว่าการเชื่อมต่อ SSH ทำงานอยู่หรือไม่ ก่อนที่จะสร้างคีย์เพื่อใช้งานจริงในอนาคต.


2
โดยทั่วไปssh-keygenแล้วssh-copy-idจะมีการเรียกใช้คีย์คู่ในเครื่องท้องถิ่นจากนั้นคัดลอกคีย์สาธารณะไปยังเครื่องระยะไกล ดูเหมือนว่าคุณกำลังทำสิ่งที่แตกต่างออกไป ทำไมเป้าหมายของคุณคืออะไร?
ephemient

1
เนื่องจากคุณกำลังเปลี่ยนแปลงอย่างเห็นได้ชัดว่าเครื่องจากระยะไกลสร้างการเชื่อมต่อให้พิจารณาปรับใช้ร็อก mosh.mit.eduมีวัตถุประสงค์เพื่อเสริม SSH ในการเชื่อมต่อที่ไม่เสถียร ฉันมีประสบการณ์ที่ดีกับมันมาก
Aeyoun

@ephemient ฉันรู้ว่ามันช้าไปหน่อย แต่ก็ค่อนข้างตรงไปตรงมาว่าคีย์นั้นไม่ใช่สำหรับเครื่องโลคัลหรือไม่ใช่สำหรับผู้ใช้ภายใน
รถเข็นที่ถูกทิ้ง

คำตอบ:


176

คุณสามารถตรวจสอบสิ่งนี้ด้วยค่าส่งคืน ssh ให้คุณ:

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

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

แก้ไข: อีกวิธีหนึ่งคือการใช้ nmap (คุณไม่จำเป็นต้องมีคีย์หรือสิ่งที่เข้าสู่ระบบ):

$ 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)

แต่คุณจะต้อง grep ข้อความ (nmap ไม่ใช้ return-value เพื่อแสดงว่าพอร์ตถูกกรองปิดหรือเปิด)

แก้ไข 2:

หากคุณสนใจสถานะที่แท้จริงของ ssh-port คุณสามารถแทนที่grep openด้วยegrep 'open|closed|filtered':

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

เพียงเพื่อให้สมบูรณ์


1
เพื่อให้สมบูรณ์คุณสามารถระบุได้ว่ารหัสส่งคืนใดหมายถึงความสำเร็จและข้อใดหมายถึงความล้มเหลวของ SSH
Henley Chiu

สงสัยว่าถ้าความพยายาม SSH ค้างอยู่ที่นั่นหรือไม่?
Sibbs Gambling

2
ตอบโจทย์มาก! อย่างไรก็ตามคุณไม่ได้พูดถึงว่าการพยายามsshลงโฮสต์จะล้มเหลวหลังจากหมดเวลาเช่น 60 วินาทีซึ่งอาจเป็นข้อห้ามสำหรับการใช้งานบางอย่าง นอกจากนี้ถ้าชื่อโฮสต์ถ้ากำหนดไว้ใน~/.ssh/configครั้งแรกsshวิธีการทำงานในขณะที่สองวิธีที่ล้มเหลวด้วยnmap Failed to resolve "<hostname>"
ssc

2
ไม่มีคำอธิบายใด ๆ เกี่ยวกับคำสั่ง ... หรือสิ่งที่คุณกำลังทำอยู่ .. คือ$?อะไร? ฯลฯ
ทศกัณฐ์

รูปแบบที่กระชับยิ่งขึ้นของ # 1: ssh -q user@downhost exit | echo $? ท่อผลลัพธ์การเชื่อมต่อเป็นเสียงสะท้อน
philn5d

23

คุณสามารถใช้สิ่งนี้ได้

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

สิ่งนี้จะแสดงผล "ok" หากการเชื่อมต่อ ssh ใช้ได้


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
เอาต์พุตบรรทัดเดียว: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" user@host.com "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | หาง -n1
Xdg

15

การเติมเต็มการตอบสนองของ@Adrià Cidreคุณสามารถทำได้:

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

ลอง:

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

1
ปัญหาของแนวทางนี้คือไม่รู้จักโฮสต์ที่กำหนดใน ssh_config (เช่น / etc / ssh / config หรือ ~ / .ssh / config)
Ding-Yi Chen

1

sshคำสั่งด้านล่างควรมีรหัสออก0ในการเชื่อมต่อที่สำเร็จและค่าที่ไม่ใช่ศูนย์เป็นอย่างอื่น

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

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

เยี่ยมมาก! ฉันขอแสดงความคิดเห็นเพิ่ม -o ConnectTimeout = 5 เพื่อให้ออกได้เร็วขึ้นในกรณีที่พอร์ตปลายทางถูกกรอง
Daniel

0

ในกรณีที่มีคนต้องการตรวจสอบว่าพอร์ต 22 เปิดอยู่บนเครื่องระยะไกลหรือไม่คำสั่ง netcat ง่ายๆนี้มีประโยชน์ ฉันใช้มันเพราะ nmap และ telnet ไม่พร้อมใช้งานสำหรับฉัน ยิ่งไปกว่านั้นการกำหนดค่า ssh ของฉันใช้การตรวจสอบรหัสผ่านแป้นพิมพ์

เป็นรูปแบบหนึ่งของโซลูชันที่เสนอโดย GUESSWHOz

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

0

หากคุณต้องการตรวจสอบโฟลเดอร์ระยะไกลที่มีอยู่หรือการทดสอบไฟล์อื่น ๆ :

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

อย่าลืมคำพูดใน"$(ssh ...)".


สิ่งนี้ไม่ตอบคำถาม OP ต้องการตรวจสอบว่าสามารถสร้างการเชื่อมต่อ SSH ได้หรือไม่โดยไม่ตรวจสอบไฟล์ในตำแหน่ง ssh ระยะไกล
Rakib Fiha

0

เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ที่มีอินเตอร์เฟสหลายตัว

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

0

ตัวอย่างการใช้ BASH 4+ script:

# -- 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

ลิงค์ด้านบนคือการสร้างสคริปต์ Python สำหรับตรวจสอบการเชื่อมต่อ คุณสามารถใช้วิธีการที่คล้ายกันและใช้:

ping -w 1 -c 1 "IP Address" 

คำสั่งสร้าง bash script


2
สิ่งนี้จะส่ง Ping ไปยัง IP ระยะไกลเท่านั้น ไม่รับประกันว่าการเชื่อมต่อ ssh เป็นไปได้หรือไม่
RJ

ขอขอบคุณที่แจ้งว่านี่คือรหัสสำหรับ 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 is Accessible"
Dheeraj Kumar

-7

ฉันรู้สึกว่าคุณกำลังพยายามแก้ปัญหาที่ไม่ถูกต้องที่นี่ คุณควรพยายามทำให้ ssh daemons มีเสถียรภาพมากขึ้นไม่ใช่หรือ? ลองเรียกใช้บางอย่างเช่นmonitซึ่งจะตรวจสอบว่า daemon กำลังทำงานอยู่หรือไม่และรีสตาร์ทหากไม่เป็นเช่นนั้น (ให้เวลาคุณค้นหาปัญหารากที่อยู่เบื้องหลังการปิด sshd กับคุณ) หรือบริการเครือข่ายเป็นปัญหาหรือไม่? ลองดูที่man ifup. สิ่งที่สาปแช่งทั้งหมดต้องการปิดตัวคุณหรือไม่? นั่นเป็นปัญหาที่ใหญ่กว่า ... ลองดูบันทึกของคุณ (เริ่มต้นด้วย syslog) เพื่อค้นหาความล้มเหลวของฮาร์ดแวร์หรือบริการที่ปิดกล่องของคุณ (อาจเป็นตัวตรวจสอบอุณหภูมิ?)

การทำให้สคริปต์ของคุณยอมรับข้อผิดพลาดนั้นดีมาก แต่คุณอาจต้องยอมรับข้อผิดพลาดในกล่องของคุณด้วย


4
Sam: มีกรณีการใช้งานที่ถูกต้องเพื่อให้สคริปต์ตรวจสอบ เช่น (เช่นฉัน): ฉันมีงาน cron ที่ทำงานบนเครื่องของฉันเพื่อสำรองข้อมูลผ่าน rsync ไปยังบ้านของฉัน ตอนนี้ฉันอยู่นอกหรือแม้กระทั่งตัดการเชื่อมต่อค่อนข้างบ่อยและจำเป็นต้องกำหนดเวลาใหม่หากการเชื่อมต่อไม่พร้อมใช้งาน กล่องของฉันทำงานได้ดี แต่อย่างที่บอกไป: มันเป็นสายเคเบิลเสมอ (aka network)
stwissel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.