我有以下任务:
- 该命令必须通过 ssh 在 bash 脚本中以 root 身份在服务器上远程运行,并且必须在变量中获取命令输出。
- 以 root 身份通过 ssh 登录已被禁用。
- 服务器上的 sudo 被禁用,所以我必须使用 su。
- 编辑:因为我想在 bash 中使其尽可能自动化,所以密码必须存储在命令内部
我用谷歌搜索了好几天,但似乎找不到解决方案。
这里提出的解决方案:ssh 到服务器并切换用户并更改目录
ssh -t username@hostname "sudo su - otheruser -c \"cd /path/to/directory && command\""
不起作用,因为 sudo 在服务器上被禁用:
有人有解决办法吗?
答案1
通过 SSH 登录(作为非特权用户),然后运行不带任何参数的命令su
以更改为 root 用户。您将需要 root 密码才能执行此操作。然后运行您想要运行的任何命令。
编辑:如果您想在一行中完成此操作,可以使用以下命令:
ssh username@hostname "su -c \"code_here\""
如果这不起作用,请确保通过passwd
以 root 身份运行来启用 root 密码。这将要求您输入新的 root 密码。
额外的:要以除 root 之外的其他用户身份运行命令(请注意,这需要目标用户的密码):
ssh username@hostname "su - username_of_target -c \"code_here\""
答案2
也许有些偏离主题,但这可以通过 Python 和帕拉米科模块:
#!/usr/bin/python2
import time
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('127.0.0.1', port=22, username='user', password='pass')
stdin, stdout, stderr = ssh.exec_command('su')
time.sleep(0.1) # some enviroment maybe need this.
stdin.write('root_password_goes_here\n')
[ add extra code here to execute a command ]
stdin.flush()
print (stdout.readlines())
ssh.close()
应该注意的是,从安全角度来看,将密码存储在脚本中通常是一个坏主意。确保您为脚本设置了适当的权限(例如 chmod 740)
答案3
与将 root 密码放入脚本中相比,您可以使用可执行文件来减少安全噩梦setuid
。
setuid
可执行文件都以 root 身份运行,无论哪个用户执行它们。
这样做的主要优点是,如果有人偷了您的笔记本电脑,他们可以smartctl -a /dev/sda
以 root 身份运行,但除此之外仅拥有您的用户权限。或者甚至更少,如果您使用稍后提到的强制命令设置公钥。
编写一个简单的 C 程序smartctl_wrapper.c
,仅运行您需要的脚本或程序,如下所示:
#include <unistd.h>
int main() {
//depending on your use case, you may want
//setuid(0), setgid(0), and/or setegid(0) here
execl("/full/path/to/smartctl","smartctl","-a","/dev/sda",(char*) NULL);
}
并将其编译为gcc smartctl_wrapper.c -o smartctl_wrapper
.
然后将其设置为属于 root 以及应该能够运行它的组。这些命令应以 root 身份运行:
chown root:some_group smartctl_wrapper
然后将其设为setuid
可执行文件。还可以防止任何用户对其进行编辑:
chmod 4510 smartctl_wrapper
现在,这是一个可执行文件,任何具有 root 权限的成员都可以运行some_group
,无需任何密码。
现在你可以简单地使用 ssh 运行它:
ssh [email protected] /path/to/smartctl_wrapper
如果服务器允许,您可以使用公钥设置 ssh 连接,以允许无需密码的连接。您还可以使用强制命令所以这个键除了运行这个脚本之外没有任何用处。
如果服务器不允许,您可以制作一个包含 ssh 密码的脚本。在这种情况下,我强烈建议您为此创建一个具有最小权限和/sbin/nologin
.
或者,对于您的特定用例,避免完全以 root 身份运行命令可能更有意义ssh
。例如,您可以使用 安排此命令定期运行cron
。您可以使用以下命令编辑 root 的 crontab:
su -c crontab -e -u root
并添加以下行:
5 0 * * sun smartctl -a /dev/sda >> /some/path/to/log/some/non/root/user/can/read
给出的行将每周运行一次该命令,即周日午夜后 5 分钟。您可以根据自己的喜好进行调整,按照以下说明进行操作定时任务(5)。
然后你就可以用ssh
它来读取日志。
答案4
于是,经过4个小时的额外网络爬行,我终于成功了!大的感谢@jeroen-it-nerdbox 给我对此的见解:
任务是从 smartctl(需要 root 凭据)、禁用 ssh-root 和禁用 sudo 的服务器获取数据。这当然也适用于 sudo 而不是 su。
这是 Python 中带有 Paramiko 实现的完整可行代码。
#!/usr/bin/python2
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('rootserver.domain.com', port=22, username='admin', password='adminpass')
stdin, stdout, stderr = ssh.exec_command('/bin/su root -c "smartctl -a /dev/sda > /tmp/smartctl_output"', get_pty=True)
stdin.write('rootpass\n')
stdin.flush()
print (stdout.readlines())
ssh.close()