在shell脚本中使用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

Answers:


15

您是否考虑过使用无密码的sudo?


1
这是我过去使用的方法。您可以将sudo限制为必需的命令(启动/停止服务),从而将用户所拥有的特权限制为您所需要的权限。它仍然感觉笨拙,但是有效。
标记

这实际上是我最终要做的...
cmcculloh 2010年

5

代替su,使用在sudoers中设置了NOPASSWD的sudo来执行适当的命令。您将希望允许的命令集尽可能地受限制。如果您不熟悉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在服务器上运行将启动新的Shell,而不是以root身份执行脚本中的后续命令。您需要执行的操作是使用sudosu -c,然后使用-t开关强制将TTY分配给SSH (如果需要输入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将使过程更加流畅。

我希望这有帮助 :-)


如果您需要有关添加该NOPASSWD规则的更多信息,请查看底部的示例man sudoers。另外,请记住visudo在编辑sudoers文件时使用以避免损坏!
jabirali 2010年

我无法使su--c“命令”正常工作。我将如何提供su的密码?
cmcculloh

如果选择使用su -c而不是sudo,则应使用带有-t标志的SSH运行-执行命令时,系统将提示您在服务器上输入root密码。su不支持(据我所知)直接提供密码作为命令行参数(据我所知),也不推荐-因为简单地ps -ef | grep su显示了传递给所有参数的参数su,包括
从命令行

至于您如何su -c通过SSH 调用:ssh -t user@host 'su -lc "<br /> echo this is a test <br /> echo this is another test<br /> "<br />'
jabirali 2010年

<br />以上内容替换为脚本中的换行符。离题您可以在ServerFault注释中添加换行符吗?发布代码段时,这将非常有用...
jabirali 2010年

2

不会。即使您将密码设置为su,您仍然必须处理su将打开一个新shell 的事实,这意味着您的其他命令将不会传递给它。您将需要为根操作编写脚本以及可以以适当特权调用它的帮助程序可执行文件。


2
大多数su命令接受-c选项,该选项会将要运行的命令作为参数。我同意服务器上的脚本可能最好,而不是通过ssh发送所有cmds。
亚伦·布什

1

写一个期望脚本。我知道您已经找到了答案,但是如果您必须登录到一堆需要交互式密码输入的服务器,这可能会有所帮助。

这是一种基于TCL的语言,因此与普通的旧Shell脚本相比可能有点怪异。但是它可以处理文本输入的自动化,而且您猜到了,它可以在输入任何类型的自动密码输入或特权升级之前“期望”某些输出。

这是一个很好的指南链接: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

我知道这有点晚了,但是我个人将使用CPAN提供的Net :: SSH :: Expect。

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


如果您不能使用常规的ssh / bash脚本,则在许多情况下,Expect确实很不错。但是,它也很快变得笨拙,使您在远程端承担“无论发现什么”的责任。如果它的行为,您可以更改目标系统或影响在所有我会建议先尝试不同的路线。不过,在这里提出来的好点。
Theuni 2012年

0

您可以使用“ ssh example.com su -lc“ $ cmd”“。

当command包含选项时,需要用引号引起来,否则“ su”可能会吞掉它们(“ su:无效选项-'A')。

ssh -AX -tt example.com 'su -lc "tmux new-session -A"'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.