Назад | Перейти на главную страницу

использование su внутри сценария оболочки

Я автоматизирую процесс развертывания и хочу иметь возможность просто вызвать один .sh-файл на моем компьютере, сделать его сборку и загрузить .zip на сервер, а затем выполнить кучу вещей на сервере. Одна из вещей, которые мне нужно сделать, требует, чтобы я был root. Итак, я хочу сделать следующее:

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

Это вообще возможно?

Рассматривали ли вы вместо этого sudo без пароля?

Вместо su используйте sudo с NOPASSWD, установленным в sudoers для соответствующей команды (команд). Вы захотите сделать разрешенный набор команд как можно более ограниченным. Если вы не знакомы с синтаксисом файла sudoer, то запуск сценария для корневых команд может быть самым чистым и самым простым способом обеспечения безопасности. Для команд / скриптов, требующих загрузки всего окружения, sudo su - -c command работает, хотя может быть излишним.

Вы можете передать команду в качестве аргумента 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 переключатель (требуется, если нужно ввести пароль root):

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

Надеюсь, это поможет :-)

То, что вы описываете, возможно с ожидать.

Нет. Даже если вы получите пароль к su, вам все равно придется иметь дело с тем, что su откроет новую оболочку, что означает, что ваши дальнейшие команды не будут ей переданы. Вам нужно будет написать сценарий для корневых операций вместе со вспомогательным исполняемым файлом, который может вызывать его с соответствующими привилегиями.

Напишите сценарий ожидания. Я знаю, что вы уже нашли ответ на этот вопрос, но это может быть полезно, если вам нужно войти на несколько серверов, требующих интерактивного ввода пароля.

Это язык, основанный на 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

Я знаю, что это немного поздно, но я бы лично использовал Net :: SSH :: Expect, доступный на CPAN.

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

Вы можете использовать 'ssh example.com su -lc "$ cmd"'.

Если команда содержит параметры, вы должны заключить их в кавычки, иначе su может их съесть (su: invalid option - 'A').

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'