ใช้ su ภายในของเชลล์สคริปต์


12

ฉันกำลังทำให้กระบวนการปรับใช้เป็นไปโดยอัตโนมัติและฉันต้องการเรียกไฟล์. sh หนึ่งไฟล์บนเครื่องของฉันให้ฉันสร้างและอัปโหลด. zip ไปยังเซิร์ฟเวอร์แล้วทำสิ่งต่าง ๆ บนเซิร์ฟเวอร์ หนึ่งในสิ่งที่ฉันต้องทำคือให้ฉันต้องรูต ดังนั้นสิ่งที่ฉันต้องการทำคือ:

ssh user@172.1.1.101 <<END_SCRIPT
su - 
#password... somehow...
#stop jboss
service server_instance stop
#a bunch of stuff here
#all done!
exit
END_SCRIPT

เป็นไปได้ไหม


+1 คำถามที่ดี ปัญหาที่พบบ่อย
gMale

คำตอบ:


15

คุณถือว่า sudo น้อยกว่ารหัสผ่านแทน?


1
นี่คือวิธีการที่ฉันใช้ในอดีต คุณสามารถ จำกัด sudo ไปยังคำสั่งที่ต้องการ (เริ่ม / หยุดบริการ), จำกัด สิทธิ์ที่ผู้ใช้ต้องแม่นยำในสิ่งที่คุณต้องการ มันยังคงรู้สึก clunky แต่ใช้งานได้
ทำเครื่องหมาย

นี่คือสิ่งที่ฉันลงเอยด้วยการทำ ...
cmcculloh

5

แทนที่จะเป็น su ให้ใช้ sudo กับชุด NOPASSWD ใน sudoers สำหรับคำสั่งที่เหมาะสม คุณจะต้องตั้งค่าคำสั่งที่อนุญาตเท่าที่จะทำได้ ให้มันเรียกใช้สคริปต์สำหรับคำสั่งรูทอาจเป็นวิธีที่สะอาดที่สุดและง่ายที่สุดที่จะทำให้ปลอดภัยหากคุณไม่คุ้นเคยกับไวยากรณ์ของไฟล์ sudoer สำหรับคำสั่ง / สคริปต์ที่ต้องการโหลดสภาพแวดล้อมแบบเต็มsudo su - -c commandทำงานได้แม้ว่าอาจจะเกินกำลัง



3

คุณสามารถส่งคำสั่งเป็นอาร์กิวเมนต์ไปยัง SSH เพื่อเรียกใช้คำสั่งนั้นบนเซิร์ฟเวอร์แล้วออก:

ssh user@host "command to run"

นอกจากนี้ยังใช้งานได้กับรายการคำสั่งหลายคำสั่ง:

ssh user@host "command1; command2; command3"

หรืออีกทางหนึ่ง:

ssh user@host "
        command1
        command2
        command3
"

อย่างที่ผู้ใช้คนอื่น ๆ ชี้ให้เห็นก่อนหน้าฉันการรันsuบนเซิร์ฟเวอร์จะเปิดเชลล์ใหม่แทนการรันคำสั่งที่ตามมาในสคริปต์ในฐานะรูท สิ่งที่คุณต้องทำคือใช้อย่างใดอย่างหนึ่งsudoหรือsu -cและบังคับให้การจัดสรร TTY ไปยัง SSH ด้วย-tสวิตช์ (จำเป็นถ้าคุณต้องการป้อนรหัสผ่านรูท):

ssh -t user@host 'su - -c "command"'
ssh -t user@host 'sudo command'

วิธีสรุปสิ่งที่คุณต้องการทำคือ:

#!/bin/bash
ssh -t user@172.1.1.101 "
        sudo some_command
        sudo service server_instance stop
        sudo some_other_command
"

เนื่องจากsudoโดยทั่วไปจะจดจำระดับการอนุญาตของคุณเป็นเวลาสองสามนาทีก่อนที่จะขอรหัสผ่านรูทอีกครั้งเพียงแค่sudoเตรียมคำสั่งทั้งหมดที่คุณต้องใช้เนื่องจากรูทน่าจะเป็นวิธีที่ง่ายที่สุดในการรันคำสั่งในฐานะรูทบนเซิร์ฟเวอร์ การเพิ่มNOPASSWDกฎสำหรับผู้ใช้ของคุณ/etc/sudoersจะทำให้กระบวนการราบรื่นขึ้น

ฉันหวังว่านี่จะช่วยได้ :-)


หากท่านต้องการข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มว่ากฎการตรวจสอบตัวอย่างที่ด้านล่างของNOPASSWD man sudoersนอกจากนี้อย่าลืมใช้visudoเมื่อแก้ไขsudoersไฟล์ของคุณเพื่อหลีกเลี่ยงความเสียหาย!
jabirali

ฉันไม่สามารถใช้คำสั่ง su - -c "เพื่อทำงานได้ ฉันจะให้รหัสผ่านสำหรับ su ได้อย่างไร
cmcculloh

หากคุณเลือกที่จะใช้su -cแทนคุณsudoควรรัน SSH ด้วย-tแฟล็ก - คุณจะได้รับพร้อมท์ให้ใส่รหัสผ่านรูทบนเซิร์ฟเวอร์เมื่อคำสั่งถูกเรียกใช้งาน การให้รหัสผ่านโดยตรงไปยังsuอาร์กิวเมนต์บรรทัดคำสั่งไม่ได้รับการสนับสนุน (เท่าที่ฉันรู้) และไม่แนะนำ - เนื่องจากง่าย ๆps -ef | grep suเปิดเผยข้อโต้แย้งทั้งหมดที่ส่งไปยังsuรวมถึงรหัสผ่านใด ๆ ที่ให้จาก commandline ...
jabirali

สำหรับวิธีที่คุณเรียกใช้su -cSSH: ssh -t user@host 'su -lc "<br /> echo this is a test <br /> echo this is another test<br /> "<br />'
jabirali

แทนที่<br />ข้างต้นด้วยบรรทัดใหม่ในสคริปต์ของคุณ หัวข้อ:คุณสามารถเพิ่มบรรทัดใหม่ในความคิดเห็น ServerFault ได้หรือไม่ ที่จะเป็นประโยชน์มากเมื่อโพสต์โค้ด ...
jabirali

2

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


2
คำสั่ง su ส่วนใหญ่ยอมรับอ็อพชัน -c ซึ่งจะใช้เป็นอาร์กิวเมนต์ที่คำสั่งรัน ฉันยอมรับว่าสคริปต์บนเซิร์ฟเวอร์นั้นน่าจะดีที่สุดเมื่อเทียบกับการส่ง cmds ทั้งหมดผ่าน ssh
Aaron Bush

1

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

มันเป็นภาษาที่มีพื้นฐานมาจาก TCL ดังนั้นอาจเป็นเรื่องแปลกเมื่อเทียบกับสคริปต์เชลล์แบบเก่า แต่มันจะจัดการกับการป้อนข้อความอัตโนมัติและคุณคาดเดาว่า "คาดหวัง" เอาท์พุทบางอย่างก่อนที่จะเข้าสู่การป้อนรหัสผ่านอัตโนมัติหรือการเพิ่มระดับสิทธิ์

นี่เป็นลิงค์ที่ดีในฐานะคู่มือ: http://bash.cyberciti.biz/security/expect-ssh-login-script/

ในกรณีที่ไซต์หยุดทำงาน:

#!/usr/bin/expect -f
# Expect script to supply root/admin password for remote ssh server
# and execute command.
# This script needs three argument to(s) connect to remote server:
# password = Password of remote UNIX server, for root user.
# ipaddr = IP Addreess of remote UNIX server, no hostname
# scriptname = Path to remote script which will execute on remote server
# For example:
#  ./sshlogin.exp password 192.168.1.11 who
# ------------------------------------------------------------------------
# Copyright (c) 2004 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# ----------------------------------------------------------------------
# set Variables
set password [lrange $argv 0 0]
set ipaddr [lrange $argv 1 1]
set scriptname [lrange $argv 2 2]
set arg1 [lrange $argv 3 3]
set timeout -1
# now connect to remote UNIX box (ipaddr) with given script to execute
spawn ssh root@$ipaddr $scriptname $arg1
match_max 100000
# Look for passwod prompt
expect "*?assword:*"
# Send password aka $password
send -- "$password\r"
# send blank line (\r) to make sure we get back to gui
send -- "\r"
expect eof

1

ฉันรู้ว่ามันค่อนข้างช้า แต่ฉันจะใช้ Net :: SSH :: คาดหวังจาก CPAN

http://search.cpan.org/~bnegrao/Net-SSH-Expect-1.09/lib/Net/SSH/Expect.pod


คาดว่าจะดีมากในหลาย ๆ กรณีถ้าคุณไม่สามารถใช้สคริปต์ ssh / bash ปกติได้ อย่างไรก็ตามมันจะกลายเป็น clunky อย่างรวดเร็วและทำให้คุณคิดว่า "สิ่งที่คุณพบ" ในระยะไกล หากคุณสามารถเปลี่ยนระบบเป้าหมายหรือมีอิทธิพลต่อวิธีการที่จะทำงานที่ทุกคนฉันจะแนะนำให้พยายามเส้นทางที่แตกต่างกันเป็นครั้งแรก จุดดีที่จะนำมันมาที่นี่แม้ว่า
Theuni

0

คุณสามารถใช้ 'ssh example.com su -lc "$ cmd"'

เมื่อคำสั่งมีตัวเลือกคุณต้องอ้างมันมิฉะนั้น "su" อาจกินได้ ("su: ตัวเลือกที่ไม่ถูกต้อง - 'A')

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.