Tự động nhập mật khẩu SSH với tập lệnh


193

Tôi cần tạo một tập lệnh tự động nhập mật khẩu cho sshmáy khách OpenSSH .

Giả sử tôi cần SSH vào myname@somehostbằng mật khẩu a1234b.

Tôi đã thử ...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

...dường như không hiệu quả.

Làm thế nào tôi có thể có được chức năng này vào một kịch bản?

Câu trả lời:


278

Đầu tiên bạn cần cài đặt sshpass .

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • Vòm: pacman -S sshpass

Thí dụ:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM

Ví dụ cổng tùy chỉnh:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400

Ghi chú:

  • sshpasscũng có thể đọc mật khẩu từ một tập tin khi -fcờ được thông qua.
    • Việc sử dụng -fngăn chặn mật khẩu hiển thị nếu pslệnh được thực thi.
    • Các tập tin mà mật khẩu được lưu trữ phải có quyền an toàn.

12
Điều này tốt hơn nhiều so với việc sử dụng Expect.
Per Mejdal Rasmussen

5
chỉ cần lưu ý rằng trong khi sshpass chặn mật khẩu của bạn khỏi các lệnh như ps -aux, bạn thường không nên chạy các lệnh bằng cách nhập mật khẩu của mình vì những người dùng khác trên cùng một máy tính có thể thấy mật khẩu bằng cách chạy ps -aux. nếu thực tế, bạn cũng muốn sử dụng xác thực khóa công khai thay thế, như được đề cập trong câu trả lời khác. điều này cho phép bạn tách thông tin xác thực khỏi tập lệnh của mình để bạn có thể chia sẻ tập lệnh của mình với người khác mà không phải lo lắng và sau đó quyết định bật mã hóa trên thư mục ~ / .ssh mà không cần mã hóa tập lệnh của bạn.
Alexander Taylor

2
Thật không may, điều này không làm việc cho tôi trên một máy chủ có cổng ssh tùy chỉnh ... tại sao ssh không thể chỉ cho chúng tôi tùy chọn chèn mật khẩu vào dòng lệnh?
Andy

2
để cổng tùy chỉnh hoạt động, hãy thêm "-p port-number" vào cuối lệnh
Ye Lwin Soe


95

Sau khi tìm kiếm một câu trả lời cho câu hỏi trong nhiều tháng, cuối cùng tôi đã tìm thấy một giải pháp tốt hơn: viết một kịch bản đơn giản.

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "assword:"
send "$password\r";
interact

Đặt nó vào /usr/bin/exp, sau đó bạn có thể sử dụng:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Làm xong!


2
Câu trả lời này sẽ nhận được nhiều phiếu bầu hơn, nó là một trình bao bọc tuyệt vời. Chỉ cần thử một vài thao tác phổ biến như rsyncing với nhiều cờ khác nhau và thực thi lệnh từ xa và nó hoạt động mọi lúc. Đã thêm vào hộp công cụ của tôi các tập lệnh hữu ích, Cảm ơn @damn_c!
dùng2082382

7
Có lẽ nó đã không nhận được nhiều sự ủng hộ hơn bởi vì mọi người không mong đợi nó?
rõ ràng

7
Lý do tại sao đây là IMO không phải là một câu trả lời hay là bởi vì mật khẩu được viết trong kịch bản, cho đến nay là phương pháp kém an toàn nhất ...
PierreE

8
Mật khẩu sẽ được hiển thị bởi bất cứ ai chạy ps trên máy.
Daniel Persson

22
"Assword" thật tuyệt vời :-)
Ciro Santilli 冠状 病 六四

71

Sử dụng xác thực khóa công khai: https://help.ubfox.com/community/SSH/OpenSSH/Keys

Trong máy chủ nguồn chỉ chạy một lần:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost

Đó là tất cả, sau đó bạn sẽ có thể thực hiện ssh mà không cần mật khẩu.


21
Tôi hiểu rồi. Nhưng tôi BẮT BUỘC phải ssh với mật khẩu. Điều này là do, "Tôi" có thể có tập lệnh trên ổ USB và cần chạy nó từ bất kỳ máy tính nào; trong khi không vô hiệu hóa sự cần thiết của mật khẩu.
user1467855

3
@ user1467855, tôi nghĩ bạn cần giải thích rõ hơn về yêu cầu của mình. Không ai đề xuất rằng bạn có một mạng không an toàn. Theo cách tiếp cận khóa công khai, người dùng vẫn có thể đăng nhập bằng mật khẩu. Nhưng bạn sẽ sao chép khóa riêng vào ổ ngón tay cái của mình, điều đó có nghĩa là ổ ngón tay cái sẽ là thứ duy nhất có thể đăng nhập mà không cần mật khẩu.
Aaron McDaid

5
Thật không may, tôi đang ở trong tình huống OP, vì sysadmin không cho phép xác thực bằng các khóa rsa / dsa và yêu cầu các mật khẩu. Bạn sẽ làm gì
Karel Bílek

26
Bị từ chối vì điều này thậm chí không cố gắng trả lời câu hỏi thực tế.
Bắn Parthian

2
Điều này vẫn nhắc cho lần đăng nhập đầu tiên và không thể được sử dụng trong tập lệnh!
Mehrdad Mirreza

29

Bạn có thể sử dụng một kịch bản mong đợi. Tôi đã không viết một cái trong một thời gian khá lâu nhưng nó sẽ trông như dưới đây. Bạn sẽ cần phải đứng đầu kịch bản với#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact

Tôi đã làm như bạn đề xuất nhưng nhận được các lỗi sau:/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
user1467855

Cảm ơn Aaron đã sửa đổi câu trả lời của tôi là chính xác. Bạn có thể cần chạy lệnh dưới đây để tìm đường dẫn chính xác để đặt kỳ vọng. which expect
Lipongo

1
Bạn cũng có thể sử dụng dòng shebang này:#!/usr/bin/env expect
glenn jackman

1
Tôi đã thêm vào interactcuối để phiên ssh thực sự tương tác
Karel Bílek

-1 cho rủi ro bảo mật rất lớn khi giữ mật khẩu văn bản đơn giản trong tập lệnh.
Aaron Digulla

21

Biến thể tôi

sshpass -p PASSWORD ssh USER@SERVER

Biến thể II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact

Các -plá cờ là để xác định một số cổng.
Kookerus

4
Số sshpass không phải là ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZ OfferAlex

Để chạy sshpass trong Linux CentOS, bạn phải yum -y install epel-releasevà sau đóyum -y install sshpass
Junior Mayhé

Trong bối cảnh của dữ liệu này có thể được bỏ qua
RemiZ OfferAlex

Mặc dù tôi biết đây là một bài viết cũ nhưng đáng chú ý là phương pháp Biến thể II sẽ để lại mật khẩu được cung cấp cho phiên dễ bị tổn thương trong lịch sử bash, khiến nó rất khó coi.
Kirkland

10

sshpass + tự động

Một phần thưởng tuyệt vời của những điều đã được đề cập sshpasslà bạn có thể sử dụng nó autossh, loại bỏ thậm chí nhiều hơn sự kém hiệu quả tương tác.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

Điều này sẽ cho phép tự động kết nối nếu, ví dụ như wifi của bạn bị gián đoạn bằng cách đóng máy tính xách tay của bạn.


2
Lưu ý rằng bạn không thể thêm tùy chọn -fvào autossh trong kết hợp này, bởi vì when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt cũng superuser.com/questions/1278583/
allenyllee

9

sshpass với bảo mật tốt hơn

Tôi đã vấp phải chủ đề này trong khi tìm cách để ssh vào một máy chủ bị sa lầy - phải mất một phút để xử lý nỗ lực kết nối SSH và hết thời gian trước khi tôi có thể nhập mật khẩu. Trong trường hợp này, tôi muốn có thể cung cấp mật khẩu của mình ngay lập tức khi có lời nhắc.

(Và nếu nó không rõ ràng một cách đau đớn: với một máy chủ ở trạng thái này, đã quá muộn để thiết lập đăng nhập khóa công khai.)

sshpassđể giải cứu. Tuy nhiên, có nhiều cách tốt hơn để đi về điều này hơn sshpass -p.

Việc triển khai của tôi bỏ qua trực tiếp đến lời nhắc mật khẩu tương tác (không lãng phí thời gian xem liệu trao đổi khóa công khai có thể xảy ra không) và không bao giờ tiết lộ mật khẩu dưới dạng văn bản thuần túy.

#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"

# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS 
export SSHPASS

# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"

# clear the exported variable containing the password
unset SSHPASS

1
lưu ý đến bản thân: cập nhật tập lệnh để sử dụng trapđể ngăn ctrl-C rò rỉ SSHPASSbiến
Ian

1
Tôi thấy rằng PreferredAuthentications=keyboard-interactivenó không hoạt động, nhưng thay thế nó bằng PreferredAuthentications=passwordlàm việc.
Mike Partridge

7

Đây là cách tôi đăng nhập vào máy chủ của mình.

ssp <server_ip>
  • bí danh ssp = '/ home / myuser / Documents / ssh_script.sh'
  • mèo /home/myuser/Document/ssh_script.sh

#! / bin / bash

sshpass -p mypassword ssh root @ $ 1

Và do đó...

ssp server_ip

5
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1

# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22

tham khảo: https://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card


3
Tôi nghĩ rằng bài viết này chỉ là châm biếm!
Yan Foto

5

Tôi không nghĩ rằng tôi đã thấy ai đề xuất điều này và OP chỉ nói "kịch bản" nên ...

Tôi cần phải giải quyết vấn đề tương tự và ngôn ngữ thoải mái nhất của tôi là Python.

Tôi đã sử dụng thư viện paramiko. Hơn nữa, tôi cũng cần phải ban hành các lệnh mà tôi sẽ cần các quyền được tăng cường bằng cách sử dụng sudo. Hóa ra sudo có thể chấp nhận mật khẩu của mình thông qua stdin thông qua cờ "-S"! Xem bên dưới:

import paramiko

ssh_client = paramiko.SSHClient()

# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)

# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"

ssh_client.connect(hostname="my.host.name.com",
                       username="username",
                       # Uncomment one of the following...
                       # password=password
                       # pkey=pkey
                       )

# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)

# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)

exit_status = chan.recv_exit_status()

if exit_status != 0:
    stderr = chan.recv_stderr(5000)

# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.

    logger.error("Uh oh")
    logger.error(stderr)
else:
    logger.info("Successful!")

Hy vọng điều này sẽ giúp được ai đó. Trường hợp sử dụng của tôi là tạo thư mục, gửi và giải nén các tệp và khởi động chương trình trên ~ 300 máy chủ. Như vậy, tự động hóa là tối quan trọng. Tôi đã thử sshpass, expectvà sau đó đã đưa ra điều này.


2

Tôi đã làm việc này như sau

.ssh / config đã được sửa đổi để loại bỏ dấu nhắc có / không - Tôi đứng sau tường lửa nên tôi không lo lắng về các khóa ssh giả mạo

host *
     StrictHostKeyChecking no

Tạo một tệp phản hồi cho mong đợi tức là answer.Exect

set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart

expect  "*?assword {
      send "password\r"   <- your password here.

interact

Tạo tập lệnh bash của bạn và chỉ cần gọi mong đợi trong tệp

#!/bin/bash
i=1
while [$i -lt 129]    # a few nodes here

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Gets 128 dữ liệu hadoop được làm mới với cấu hình mới - giả sử bạn đang sử dụng ngàm NFS cho các tệp hadoop / conf

Hy vọng điều này sẽ giúp được ai đó - Tôi là một người lập dị Windows và điều này khiến tôi mất khoảng 5 giờ để tìm ra!


"Tôi đứng sau một tường lửa nên tôi không lo lắng về các khóa ssh giả mạo". Một tường lửa không làm gì chính xác trong trường hợp này. HostKeyCheck là để bạn có thể xác minh máy chủ ở đầu bên kia không phải là trojan Host. Tức là một người chỉ giả vờ là nơi bạn muốn kết nối. Nếu bạn kết nối với một máy chủ không xác định và làm điều gì đó nhạy cảm, như viết một tệp có thông tin xác thực hoặc mã thông báo hoặc nhập mật khẩu, thông tin đó giờ đây là kiến ​​thức công khai hiệu quả. Bạn đứng sau một bức tường lửa là không liên quan.
JCGB

2

Nếu bạn đang làm điều này trên một hệ thống Windows, bạn có thể sử dụng Plink (một phần của PuTTY).

plink your_username@yourhost -pw your_password



1

Tôi quản lý để làm cho nó hoạt động với điều đó:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername

0

Trong ví dụ dưới đây tôi sẽ viết giải pháp mà tôi đã sử dụng:

Kịch bản: Tôi muốn sao chép tệp từ máy chủ bằng cách sử dụng tập lệnh sh:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"

-2

Sử dụng tập lệnh này tossh trong tập lệnh, Đối số đầu tiên là tên máy chủ và thứ hai sẽ là mật khẩu.

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"

Điều này thể hiện gì trên đầu các câu trả lời hiện có? Đặc biệt là những người của damn_c, Lipongo hoặc RemiZ OfferAlex và những người khác ...
Martin Prikryl

thực thi tập lệnh cùng với ssh #! / usr / bin / wish set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh mong đợi "* assword:" gửi "$ pass \ n"; tương tác "
Shivam Mehrotra

-3

Để kết nối máy từ xa thông qua các tập lệnh shell, sử dụng lệnh dưới đây:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

trong đó IPADDRESS, USERNAMEPASSWORDlà các giá trị đầu vào cần cung cấp trong tập lệnh hoặc nếu chúng tôi muốn cung cấp trong thời gian chạy, hãy sử dụng lệnh "đọc".


5
Câu trả lời này cho thấy gì trên đầu câu trả lời hiện có? + Không bao giờ đề nghị bất cứ ai sử dụng StrictHostKeyChecking=nomà không giải thích hậu quả.
Martin Prikryl

-5
sudo ssh username@server_ip_address -p port_number

nhấn phím enter và sau đó nhập mật khẩu hệ thống của bạn và cuối cùng nhập mật khẩu máy chủ của bạn

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.