שאלה כיצד ניתן להפעיל פקודה מורכבת באופן שרירותי באמצעות sudo מעל ssh?


יש לי מערכת שאני יכול להתחבר אליה רק ​​תחת שם המשתמש שלי (myuser), אבל אני צריך להפעיל פקודות כמו משתמש אחר (scriptuser). עד כה, יש לי לבוא עם הבאות כדי להפעיל את הפקודות שאני צריך:

ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""

עם זאת, כאשר אני מנסה להפעיל פקודה מורכבת יותר, כגון [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory" אני מסתבך במהירות עם ציטוט. אני לא בטוח איך אני יכול להעביר את זה למשל הפקודה מורכבת bash -c, מתי \" כבר מתוחם את הגבולות של הפקודה אני עובר (ולכן אני לא יודע איך לצטט / tmp / ספרייה כלשהי, הכוללת רווחים.

האם יש פתרון כללי שמאפשר לי להעביר כל פקודה, לא משנה עד כמה מורכב / משוגע הציטוט הוא, או שזה סוג של הגבלה הגעתי? האם יש פתרונות אפשריים נוספים ואולי אף קריאים יותר?


76
2017-09-02 09:21




העתק סקריפט ל- $ Remote ולאחר מכן בצע אותו. - Iain
זה יעבוד, אבל אני מוצא פתרון אשר משאיר שום קבצי Script מאחורי (במקרה שמשהו נכשל וכו ') יהיה קצת מנקה. - VoY
יש את התסריט RM עצמו בסוף כל ריצה - thanasisk
שקול להשתמש בד fabfile.org. יכול לגרום לך החיים הרבה יותר קל אם אתה צריך הרבה sudo הרבה. - Nils Toedtmann
אם יש לך Ansible מותקן פקודה זו מציגה את התיעוד עבור מקרה השימוש שלך: ansible-doc script - bbaassssiiee


תשובות:


טריק שאני משתמש בו לפעמים הוא להשתמש base64 כדי לקודד את הפקודות, ואת הצינור אותו כדי לרסק על האתר השני:

MYCOMMAND=$(base64 -w0 script.sh)
ssh user@remotehost "echo $MYCOMMAND | base64 -d | sudo bash"

זה יהיה לקודד את התסריט, עם כל פסיקים, backslashes, ציטוטים ומשתנים בתוך מחרוזת בטוחה, ולשלוח אותו לשרת השני. (-w0 נדרש להשבית גלישת שורות, המתרחשת בעמודה 76 כברירת מחדל). בצד השני, $(base64 -d) יהיה לפענח את התסריט להאכיל אותו כדי bash להיות להורג.

מעולם לא קיבלתי שום בעיה עם זה, לא משנה כמה מורכב היה התסריט. פותר את הבעיה עם בריחה, כי אתה לא צריך לברוח כלום. זה לא יוצר קובץ על המארח מרחוק, ואתה יכול להריץ סקריפטים מורכבים מאוד בקלות.


138
2017-09-02 13:10



או אפילו: ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash" - Niklas B.
ראוי לציין כי ברוב המקרים אתה יכול להחליף lzop או gzip עבור base64 עבור זמני העברה מהירה יותר. עם זאת, ייתכנו מקרים קצה. YMMV. - CodeGnome
שים לב, אבל אם זה סקריפט, אני לא מצפה כל העברה להיות יותר מ kb כמה. - ThoriumBR
יש כאן גם שימוש חסר תועלת בהד. base64 script | ssh remotehost 'base64 -d | sudo bash' יהיה מספיק :) - hobbs
נבדק היום ועובד לחלוטין. תודה. - Soham Chakraborty


ראה -tt אפשרות? קרא את ה ssh(1) מדריך ל.

ssh -tt root@host << EOF
sudo some # sudo shouldn't ask for a password, otherwise, this fails. 
lines
of
code 
but be careful with \$variables
and \$(other) \`stuff\`
exit # <- Important. 
EOF

דבר אחד אני עושה לעתים קרובות להשתמש vim ולהשתמש :!cat % | ssh -tt somemachine טריק.


32
2017-09-02 13:01



כמובן :!cat % | (command) ניתן לעשות זאת :w !(command) או :!(command) < %. - Scott
כן. הקו שלי הוא התעללות חתול - moebius_eye


אני חושב שהפתרון הקל ביותר טמון בשינוי ההערה של @ thanasisk.

יצירת סקריפט, scp זה למכונה, ולאחר מכן להפעיל אותו.

יש לך את התסריט rm עצמה בהתחלה. הקליפה פתחה את הקובץ, כך שהוא נטען, ולאחר מכן ניתן להסיר ללא בעיות.

על ידי ביצוע דברים בסדר זה (rm הראשון, דברים אחרים השני) זה יהיה גם להסיר כאשר הוא נכשל בשלב כלשהו.


9
2017-09-02 11:26





אתה יכול להשתמש %q פורמט עם ציון printf כדי לטפל במשתנה שנמלט לך:

cmd="ls -al"
printf -v cmd_str '%q' "$cmd"
ssh user@host "bash -c $cmd_str"

printf -v כותב את הפלט למשתנה (במקרה זה, $cmd_str). אני חושב שזו הדרך הפשוטה ביותר לעשות את זה. אין צורך להעביר קבצים או לקודד את מחרוזת הפקודה (ככל שאני אוהב את הטריק).

הנה דוגמה מורכבת יותר המראה שהיא פועלת עבור דברים כמו סוגריים מרובעים או אמפרסנדס מדי:

$ ssh user@host "ls -l test"
-rw-r--r-- 1 tom users 0 Sep  4 21:18 test
$ cmd="[[ -f test ]] && echo 'this really works'"
$ printf -v cmd_str '%q' "$cmd"
$ ssh user@host "bash -c $cmd_str"
this really works

לא בדקתי את זה עם sudo אבל זה צריך להיות פשוט כמו:

ssh user@host "sudo -u scriptuser bash -c $cmd_str"

אם תרצה, תוכל לדלג על צעד ולהימנע מהצבת המשתנה הבינוני:

$ ssh user@host "bash -c $(printf '%q' "$cmd")"
this really works

או אפילו פשוט למנוע יצירת משתנה לחלוטין:

ssh user@host "bash -c $(printf '%q' "[[ -f test ]] && echo 'this works as well'")"

7
2017-09-04 20:10



זה פתרון מדהים. אני באמת צריך להשתמש printf לפני למצב דומה, אבל אני תמיד שוכח את זה. תודה על פרסום זה :-) - Jon L.


הנה הדרך "הנכונה" (התחבירית) לבצע משהו כזה ב- bash:

ssh user@server "$( cat <<'EOT'
echo "Variables like '${HOSTNAME}' and commands like $( uname -a )"
echo "will be interpolated on the server, thanks to the single quotes"
echo "around 'EOT' above.
EOT
)"

ssh user@server "$( cat <<EOT
echo "If you want '${HOSTNAME}' and $( uname -a ) to be interpolated"
echo "on the client instead, omit the the single quotes around EOT."
EOT
)"

לקבלת הסבר יסודי כיצד זה עובד, ראה https://stackoverflow.com/a/21761956/111948


6
2018-05-28 17:48





האם אתה מודע לכך שאתה יכול להשתמש sudo לתת לך פגז שבו אתה יכול להפעיל פקודות כמשתמש נבחר?

-i, --login

הפעל את המעטפת שצוין על ידי ערך מסד הנתונים של משתמש היעד כמקרה כניסה. משמעות הדבר היא כי קבצי משאבים ספציפיים כגון כניסה                    .profile או .login יקראו על ידי הקליפה. אם צוין פקודה, הוא מועבר לקליפה לביצוע באמצעות אפשרות הקליפה -c. אם לא                    הפקודה שצוין, פגז אינטראקטיבי מבוצע. sudo מנסה לשנות את ספריית הבית של המשתמש לפני הפעלת הקליפה. קום-                    המנדט מופעל עם סביבה דומה לזו שהמשתמש יקבל בעת הכניסה. סעיף איכות הסביבה ב- sudoers (5) Manual document-                    מראות כיצד האפשרות -i משפיעה על הסביבה שבה פקודה מופעלת כאשר מדיניות הסודור נמצאת בשימוש.


4
2017-09-03 09:22



זה נראה לי הפתרון הברור. > sudo -i-brian - code_monk
זה עובד הכי טוב בשילוב עם "ssh-t" במקרה של גישה מרחוק. אשר נכלל בשאלה, אבל נושא חוזר על "אני לא יכול לקרוא את זה / כל / דף" אנשים. :) - dannysauer


ניתן להגדיר את התסריט במחשב המקומי ולאחר מכן cat ואת הצינור אותו למחשב המרוחק:

user@host:~/temp> echo "echo 'Test'" > fileForSsh.txt
user@host:~/temp> cat fileForSsh.txt | ssh localhost

Pseudo-terminal will not be allocated because stdin is not a terminal.
stty: standard input: Invalid argument
Test

3
2017-09-02 09:39



UUOC אתה יכול להשתמש < - Iain
באפשרותך לשנות את הדוגמה כך שתכלול sudo -u scriptuser? האם heredoc יהיה שמיש בהתחשב שאני צריך משתנים בסקריפט אני יהיה צנרת אל המכונה? - VoY
ניסיתי: echo "sudo `cat fileForSsh.txt`" | ssh ... אבל אני כל הזמן מקבל sudo: sorry, you must have a tty to run sudo. - jas_raj
למרות ש השאלה הזו עשוי לעזור אם אתה יכול לקבל את /etc/sudoers הקובץ השתנה - jas_raj
זה עובד בשבילי: ssh -tq user@host "sudo bash -s" < test.sh - AVee


פשוט וקל.

משתמש "@ bash-s" <script.sh


1
2017-09-03 20:15