จะส่งรหัสผ่านไปยัง su / sudo / ssh โดยไม่แทนที่ TTY ได้อย่างไร?


148

ผมเขียนโปรแกรม C เชลล์ที่จะทำsuหรือหรือsudo sshพวกเขาต้องการรหัสผ่านในอินพุตคอนโซล (TTY) มากกว่า stdin หรือบรรทัดคำสั่ง

ไม่มีใครรู้วิธีการแก้ปัญหา?

การตั้งค่ารหัสผ่านsudoไม่ได้เป็นตัวเลือก

อาจเป็นตัวเลือก แต่ไม่มีในระบบ stripping down ของฉัน



คำตอบ:


215

สำหรับ sudo มีตัวเลือก -S สำหรับรับรหัสผ่านจากอินพุตมาตรฐาน นี่คือรายการคน:

    -S          The -S (stdin) option causes sudo to read the password from
                the standard input instead of the terminal device.

สิ่งนี้จะช่วยให้คุณเรียกใช้คำสั่งเช่น:

echo myPassword | sudo -S ls /tmp

สำหรับ ssh ฉันพยายามหลายครั้งโดยอัตโนมัติ / สคริปต์มันใช้งานไม่ประสบความสำเร็จ ดูเหมือนว่าจะไม่มีการ build-in ใด ๆ ในการส่งรหัสผ่านไปยังคำสั่งโดยไม่แจ้งให้ทราบ ดังที่คนอื่น ๆ ได้กล่าวถึงยูทิลิตี้ " คาดหวัง " ดูเหมือนว่ามันมีจุดประสงค์เพื่อแก้ไขปัญหานี้ แต่ท้ายที่สุดการตั้งค่าการอนุญาตคีย์ส่วนตัวที่ถูกต้องเป็นวิธีที่ถูกต้องในการพยายามทำสิ่งนี้โดยอัตโนมัติ


2
โชคดีที่ Ruby มีไคลเอ็นต์ SSH ในตัวซึ่งอนุญาตให้คุณระบุรหัสผ่าน คุณสามารถลอง ruby ​​-e "require 'net / ssh'; Net :: SSH.start ('example.com', 'test_user',: รหัสผ่าน => 'secret') do | ssh | ใส่ 'เข้าสู่ระบบเรียบร้อยแล้ว'; ในขณะที่ cmd = ได้รับ; ใส่ ssh.exec! (cmd); end end "
1158559

13
ฉันเกลียดที่จะเป็นเซ่อเปอร์ปาร์ตี้ที่นี่ แต่การทำเช่นนี้สามารถทำให้รหัสผ่านของคุณปรากฏในรายการกระบวนการ ฉันพยายามหาวิธีที่ดีกว่าและเจอบทความนี้และรู้สึกประหลาดใจที่ไม่มีใครชี้ให้เห็น ทางออกที่ดี แต่ระวังความเสี่ยง
แมตต์

เกี่ยวกับ ssh คุณลองรหัสผ่านในสตริงการเชื่อมต่อแล้วหรือยัง? ชอบnonroot:yourpassword@hostname.comไหม แน่นอนว่าทุกอย่างง่ายขึ้นถ้าคุณใช้การตรวจสอบคีย์และตัวจัดการคีย์
Killah

12
หลีกเลี่ยงรหัสผ่านที่แสดงในรายการกระบวนการหรือไฟล์บันทึกโดยใส่ไว้ในไฟล์และใช้ cat; และหลังจากนั้น'cat pw | sudo -S <command> rm pw
CAB

อีกวิธีหนึ่งที่จะใช้ netcat และส่งมอบรหัสผ่านมากกว่าซ็อกเก็ต nc -l 12345 | sudo -S <command>- ในด้านการส่ง; echo myPassord | nc <target> 12345. นี่เป็นเพียงการย้ายปัญหาการจัดการรหัสผ่าน แต่สันนิษฐานว่าเป็นคอนโซลหลักที่คุณมีตัวเลือกเพิ่มเติม
CAB

36

ฉันเขียน Applescript ซึ่งให้รหัสผ่านผ่านกล่องโต้ตอบแล้วสร้างคำสั่ง bash แบบกำหนดเองเช่นนี้

echo <password> | sudo -S <command>

ฉันไม่แน่ใจว่าสิ่งนี้จะช่วยได้หรือไม่

มันจะดีถ้า sudo ยอมรับรหัสผ่านที่เข้ารหัสล่วงหน้าดังนั้นฉันจึงสามารถเข้ารหัสได้ภายในสคริปต์ของฉันและไม่ต้องกังวลกับการสะท้อนรหัสผ่านข้อความที่ชัดเจน อย่างไรก็ตามสิ่งนี้ใช้ได้สำหรับฉันและสถานการณ์ของฉัน


27

เพื่อsshคุณสามารถใช้sshpass: sshpass -p yourpassphrase ssh user@host.

คุณต้องดาวน์โหลด sshpass ก่อน :)

$ apt-get install sshpass
$ sshpass -p 'password' ssh username@server

12

ฉันได้รับ:

ssh user@host bash -c "echo mypass | sudo -S mycommand"

ได้ผลสำหรับฉัน


ไม่ได้ผลสำหรับฉัน ssh ยังคงให้รหัสผ่าน
AKS

ยอดเยี่ยมในที่สุดสิ่งที่ฉันสามารถใช้ได้! ขอบคุณ ฉันใช้สิ่งนี้ภายในสคริปต์ทุบตีที่เริ่มเซสชัน ssh และส่งคำสั่ง sudo ไปยังไคลเอนต์ สคริปต์ของฉันมีบรรทัดการแก้ไข: ssh -t ชื่อผู้ใช้ @ hostname bash -c "sudo echo fartjuice"
James T Snell


10

วิธีแก้ปัญหาตามปกติของปัญหานี้คือการกำหนดแอพตัวช่วยที่ทำงานที่ต้องการการเข้าถึง superuser: http://en.wikipedia.org/wiki/Setuid

Sudo ไม่ได้หมายถึงการใช้แบบออฟไลน์

แก้ไขในภายหลัง: SSH สามารถใช้กับการตรวจสอบคีย์ส่วนตัว - สาธารณะ หากคีย์ส่วนตัวไม่มีวลีรหัสผ่านคุณสามารถใช้ ssh ได้โดยไม่ต้องใส่รหัสผ่าน


10

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

ssh-keygen
Enter file in which to save the key (/home/myuser/.ssh/id_rsa): <Hit enter for default>
Overwrite (y/n)? y

จากนั้นป้อนรหัสผ่านเปล่า หลังจากนั้นให้คัดลอกคีย์ ssh ของคุณไปยังโฮสต์เป้าหมายที่คุณจะเชื่อมต่อ

ssh-copy-id <remote_user>@<other_host>
remote_user@other_host's password: <Enter remote user's password here>

หลังจากลงทะเบียนคีย์ ssh คุณจะสามารถดำเนินการเงียบssh remote_user@other_hostจากโฮสต์ท้องถิ่นของคุณ


7

บางทีคุณอาจใช้expectคำสั่ง?:

expect -c 'spawn ssh root@your-domain.com;expect password;send "your-password\n";interact

คำสั่งนั้นให้รหัสผ่านโดยอัตโนมัติ


ดูดี แต่ฉันจะเปิดใช้งานคำสั่ง expect บน maschine โดยไม่มีการอนุญาต root ได้อย่างไร?
Radon8472

1
@ Radon8472 อาจเพิ่มไฟล์ปฏิบัติการลงใน ~ / bin ได้หากคุณไม่มีสิทธิ์ในการติดตั้ง หากระบบของคุณไม่เพิ่ม ~ / bin ไปยัง PATH ของคุณโดยอัตโนมัติคุณสามารถทำได้ด้วยตนเองด้วยการส่งออก PATH = "$ PATH: ~ / bin" หรือเพิ่มคำสั่งนั้นลงในโปรไฟล์ของคุณเพื่อดำเนินการโดยอัตโนมัติ หากคุณไม่ต้องการเปลี่ยน PATH ของคุณคุณสามารถรันคำสั่งโดยใช้พา ธ สัมบูรณ์ของมันแทน: ~ / bin / expect [อาร์กิวเมนต์] อย่าลืมตั้งค่าบิตที่เรียกใช้งานได้: chmod + x ~ / bin / expect
StarCrashr

6

เมื่อไม่มีทางเลือกที่ดีกว่า (ตามที่คนอื่นแนะนำ) ดังนั้นผู้ชายสามารถช่วย:

   (sleep 5; echo PASSWORD; sleep 5; echo ls; sleep 1) |
   socat - EXEC:'ssh -l user server',pty,setsid,ctty

          EXEC’utes an ssh session to server. Uses a pty for communication
          between socat and ssh, makes it ssh’s  controlling  tty  (ctty),
          and makes this pty the owner of a new process group (setsid), so
          ssh accepts the password from socat.

ความซับซ้อนของ pty, setsid, ctty ทั้งหมดและในขณะที่คุณไม่จำเป็นต้องนอนหลับนานคุณจะต้องนอนหลับ ตัวเลือก echo = 0 นั้นมีค่าเช่นกันเช่นเดียวกับการส่งคำสั่งรีโมตบนบรรทัดรับคำสั่งของ ssh


1
สิ่งนี้จะใช้ได้จริงsuเช่นกัน suไม่มีตัวเลือก -S (stdin)
จาก

เป็นไปได้ไหมที่จะหลีกเลี่ยงการนอนหลับและใช้สิ่งที่น่าเชื่อถือมากกว่าแทน
Michael Pankov

6

ดูexpectยูทิลิตี้ linux

อนุญาตให้คุณส่งเอาต์พุตไปยัง stdio ตามการจับคู่รูปแบบแบบง่ายบน stdin


1

ตั้งค่า SSH สำหรับการตรวจสอบคีย์สาธารณะโดยไม่ต้องใส่รหัสผ่านบนคีย์ คำแนะนำมากมายบนอินเทอร์เน็ต คุณไม่ต้องใช้รหัสผ่านในการเข้าสู่ระบบ จากนั้นคุณสามารถ จำกัด การเชื่อมต่อสำหรับคีย์ตามชื่อโฮสต์ของไคลเอ็นต์ ให้ความปลอดภัยที่เหมาะสมและยอดเยี่ยมสำหรับการเข้าสู่ระบบอัตโนมัติ


1
ssh -t -t me@myserver.io << EOF
echo SOMEPASSWORD | sudo -S do something
sudo do something else
exit
EOF

หากคุณสามารถเข้าสู่ระบบในฐานะผู้ใช้ด้วยคีย์ ssh สำหรับการเข้าถึง sudo นั้นใช้ได้: ssh -t user @ host "echo mypassword | sudo -S sudocommand"
แจ็ค

0

ผมมีปัญหาเหมือนกัน. สคริปต์โต้ตอบเพื่อสร้างไดเรกทอรีบนพีซีระยะไกล โต้ตอบกับ ssh เป็นเรื่องง่าย ฉันใช้ sshpass (ติดตั้งไว้ก่อนหน้านี้)

   dialog --inputbox "Enter IP" 8 78 2> /tmp/ip

   IP=$(cat /tmp/ip)


   dialog --inputbox "Please enter username" 8 78 2> /tmp/user

   US=$(cat /tmp/user)


   dialog --passwordbox "enter password for \"$US\" 8 78 2> /tmp/pass

   PASSWORD = $(cat /tmp/pass)


   sshpass -p "$PASSWORD" ssh $US@$IP mkdir -p /home/$US/TARGET-FOLDER


   rm /tmp/ip

   rm /tmp/user

   rm /tmp/pass

คำทักทายจากประเทศเยอรมนี

ติตัส


0

คำตอบของ @ Jahid สร้างขึ้นสำหรับฉันใน macOS 10.13:

ssh <remote_username>@<remote_server> sudo -S <<< <remote_password> cat /etc/sudoers

0

sshpassทางเลือกที่ดีกว่าคือ: passh https://github.com/clarkwang/passh

เข้าสู่ระบบเซิร์ฟเวอร์ระยะไกล

 $ passh -p password ssh user@host

เรียกใช้คำสั่งบนเซิร์ฟเวอร์ระยะไกล

 $ passh -p password ssh user@host date

วิธีการอื่นในการส่งรหัสผ่าน

-p รหัสผ่าน (ค่าเริ่มต้น: `รหัสผ่าน ')

-p env: อ่านรหัสผ่านจาก env var

ไฟล์ -p: อ่านรหัสผ่านจากไฟล์

ที่นี่ฉันอธิบายว่าทำไมมันดีกว่า sshpass และโซลูชันอื่น ๆ


-1
echo <password> | su -c <command> <user> 

นี่มันใช้งานได้ดี


1
นี่เป็นสิ่งเดียวที่ใช้ได้ผลกับฉันใน Fedora ผู้คน downvote ตอบเพียงเพราะพวกเขาไม่ทำงานในสถานการณ์ของพวกเขา?
Hangchen Yu

2
"su: ต้องเรียกใช้จากเทอร์มินัล" (RPi1B, Raspbian)
notme1560

น่าเสียดายที่นี่ไม่ได้อยู่ในเวอร์ชั่นล่าสุดsuซึ่งอ่านรหัสผ่านจากstdioแทน
moutonjr

-1

การเข้ารหัสรหัสผ่านในสคริปต์ที่คาดไว้นั้นเหมือนกันกับการใช้รหัสผ่านแบบไม่มีรหัสผ่าน (sudo) แบบไม่มีรหัสผ่านจริง ๆ แล้วแย่กว่าเดิมเนื่องจากอย่างน้อยที่สุด sudo จะบันทึกคำสั่งของตน


-1

วิธีหนึ่งคือใช้ตัวเลือก read-s .. วิธีนี้อักขระรหัสผ่านจะไม่ถูกสะท้อนกลับไปที่หน้าจอ ฉันเขียนสคริปต์เล็ก ๆ สำหรับกรณีการใช้งานบางอย่างและคุณสามารถดูได้ในบล็อกของฉัน: http://www.datauniv.com/blogs/2013/02/21/a-quick-little-expect-script/




-11
su -c "Command" < "Password"

หวังว่ามันจะเป็นประโยชน์


1
มันไม่ใช่. "su: ต้องเรียกใช้จากเทอร์มินัล" คือคำตอบของสิ่งนี้
thelogix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.