I want to ssh into a remote server, change user then execute a script. I'm using subprocess
to do this but it appears sudo -u userB -i
is not changing user.
HOST = 'remote_server'
USER = 'userA'
CMD = ' whoami; sudo -u userB -i; whoami'
ssh = subprocess.Popen(['ssh', '{}@{}'.format(USER, HOST),CMD],
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = ssh.stdout.readlines()
if not result:
err = ssh.stderr.readlines()
print('ERROR: {}'.format(err))
else:
print "success"
print(result)
$ success
$ ['userA\n', 'userA\n']
When I replaced with CMD ='sudo -u userB -i && whoami'
, I got this error:
ERROR: ['sudo: sorry, you must have a tty to run sudo\n']
On the terminal, I'm able to do passwordless ssh, sudo -u userB -i && whoami
答案 0 :(得分:5)
sudo
已配置为要求terminal emulation。通常这样做是为了实际上防止您要尝试实现的自动化。在尝试绕过该限制之前,请与您的服务器管理员联系。不需要限制,那么管理员可以为您关闭它。还是有限制的原因,并且管理员对您试图绕过它感到不满意。
可以通过从sudoers
file中删除requiretty
选项来关闭限制(默认情况下该选项为关闭状态)。
要使ssh
对其命令行上提供的命令使用终端仿真,您需要使用-t
switch。但是,要使-t
真正生效,首先需要从终端运行ssh
。由于subprocess.Popen
不是终端,您将获得:
因为stdin不是终端,所以不会分配伪终端
要绕过它,您必须使用两个-t
开关:-tt
。
致@SuryaSekharMondal(对此问题提供了赏金):You are using Paramiko,而不是ssh
。我上面写的与您无关。
答案 1 :(得分:0)
将此行插入远程服务器上的/etc/sudoers
将解决此问题:
Defaults !requiretty
答案 2 :(得分:0)
我会用一个小的C程序解决这个问题,并给它suid权限,即
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
// #include <stdio.h>
#include <string.h>
int main(int argc,char *argv[]){
setuid(0);//su
char *cmd="/usr/sbin/hddtemp";
char *arg[]={(char *)"hddtemp",(char *)"--numeric"};
#define array_size(x) (sizeof(x)/sizeof(*x))
int size=array_size(arg);
size_t i,n=size+argc;
char **args=malloc((n)*sizeof(char*));
if(args==NULL)return 255;
for(i=0;i<size;i++){
args[i]=malloc(strlen(arg[i])+1);
if(args[i]==NULL)return 255;
strcpy(args[i],arg[i]);
}
for(i=0;i<argc-1;i++){
args[size+i]=malloc(strlen(argv[i+1])+1);
if(args[size+i]==NULL)return 255;
strcpy(args[size+i],argv[i+1]);
}
// printf ("total args %2zu\n",i);
// for(i=0;i<n;i++)printf ("args[%2zu] : %s\n",i,args[i]);
execv(cmd,args);
return 1;
}
首先,使用:
gcc -Wall program.c -o program
然后将chown和chmod更改为
chown 0:userB program
chmod 4750 program
而且,如果您不需要将硬编码的参数与传递的参数混合,则可以使用以下代码:
#include <unistd.h>
int main(int argc,char *argv[]){
setuid(1000); //user id of userB
char *cmd="/usr/bin/whoami";
execv(cmd,argv);
return 1; // indicate error if execv() didn't succeed.
}
通常,每个管理员都会建议您不要在 / etc / suders 中添加例外,这是有充分理由的。