використовуючи 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 необхідними командами (запустити / зупинити послугу), обмеживши привілеї, які користувач має саме на те, що вам потрібно. Він усе ще відчуває незграбність, але працює.
Марк

Це насправді те, що я закінчила робити ...
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на сервері запустить нову оболонку замість виконання наступних команд у скрипті як root. Що вам потрібно зробити, це використовувати або 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до всіх команд, які потрібно запустити як root, найімовірніше, найпростіший спосіб запустити команди як root на сервері. Додавання NOPASSWDправила для вашого користувача в /etc/sudoersзробить процес ще більш плавним.

Я сподіваюся, що це допомагає :-)


Якщо вам потрібна додаткова інформація про додавання цього NOPASSWDправила, перегляньте приклади внизу сторінки man sudoers. Крім того, не забудьте використовувати visudoпід час редагування sudoersфайлу, щоб уникнути поломки!
jabirali

Я не можу заставити команду su - -c "працювати". Як я можу подати пароль для su?
cmcculloh

Якщо ви вирішите використовувати su -cзамість sudo, вам слід запустити SSH з -tпрапором - вам буде запропоновано кореневий пароль на сервері при виконанні команди. Надання пароля безпосередньо suв якості аргументу командного рядка не підтримується (наскільки я знаю) і не рекомендується - оскільки просте ps -ef | grep suрозкриває всі передані аргументи su, включаючи будь-який пароль, наданий з командного рядка ...
jabirali

Щодо того, як ви посилаєтесь su -cна SSH: 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.
Аарон Буш

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. Однак він також стає справді незграбним і змушує вас припускати "все, що ви знайдете" на віддаленому кінці. Якщо ви можете змінити цільову систему або вплив , як він веде себе взагалі я б рекомендував спробувати інший маршрут першим. Хороший момент піднести це сюди, хоча.
Теуні

0

Ви можете використовувати 'ssh example.com su -lc "$ cmd"'.

Коли команда містить варіанти, вам потрібно її цитувати, інакше "su" може з'їсти їх ("su: invalid option -" A ").

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.