0

I need to update files on 10+ remote hosts. The way our systems were designed is we have got a user say $user which ssh into any remote hosts with password say $passwd, post successful login, $user can only run one command on remote hosts which is sudo su - root (this is as defined in /etc/sudoers)

My issue is that, I am unable to sudo su - root from my script, below is my code

(Note - I have already tried invoke_shell() and get_transport().)

import paramiko, re, os 
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
action_item = int(input("Welcome on-board ...\nPlease choose from following \n1 - Global Update\n2 - Specific Update\n Please input as 1 or 2 :"))
if action_item == 2:
    hostName = input("Please provide 'IPADDRESS' of Specific Remote Client :")
    os.system('touch /tmp/hosts_file_specific && umask 113 /tmp/hosts_file_specific')
    os.system('hostName='+hostName+' && echo "$hostName" >> /tmp/hosts_file_specific')
    hosts_file = r'/tmp/hosts_file_specific'
elif action_item == 1:
    hosts_file = r'/etc/hosts'
else:
    print("Invalid input, shutting down the application")
with open(hosts_file) as file:
    for line in file:
        line = re.findall( r'[0-9]+(?:\.[0-9]+){3}',line)
        if len(line) > 0:
            line = line[0]
        else:
            line = '127.0.0.1'
        if line == '127.0.0.1':
            pass
        else:
            print("Trying to connect - "+line)
            try:

                ssh_client.connect(hostname=line,username=$user,password=$passwd)
                stdin,stdout,stderr=ssh_client.exec_command("pgrep mttrapd")
                outData = stdout.readlines();
                outData = re.findall(r'[0-9]+',outData[0])
                outData = int(outData[0])
                print("[Probe = nco_p_mttrapd] and PID = ",outData)
            except TimeoutError:
                outData = -1
                pass
            if outData > 0:
                ftp_client = ssh_client.open_sftp()
                localfilepath1 = r"/tmp/Python_361/rules.tar"
                remotefilepath1 = r"/tmp/rules.tar"
                ftp_client.put(localfilepath1,remotefilepath1)
                ftp_client.close()
                stdin, stdout, stderr = ssh_client.exec_command('sudo su - root')
                stdin.write("\n")
                stdin.flush()
                stdin, stdout, stderr = ssh_client.exec_command("whoami")
                print(stdout.readlines())
          elif outData == -1:
                print("Host is unreachable - Please contact your network administrtor, nothing to do")
          else:
                print("mttrapd probe is not running on this host, nothing to do")

    file.close()

The output that I receive is as follows

Welcome on-board ...
Please choose from following
1 - Global Update
2 - Specific Update
 Please input as 1 or 2 :2
Please provide 'IPADDRESS' of Specific Remote Client :x.x.x.x
Trying to connect - x.x.x.x
[Probe = nco_p_mttrapd] and PID =  12345
['$user\n']
Trying to connect - x.x.x.x
[Probe = nco_p_mttrapd] and PID =  12345
**['$user\n'] #--------> I need this to be ['root\n']**
jww
  • 97,681
  • 90
  • 411
  • 885
sulabh chaturvedi
  • 3,608
  • 3
  • 13
  • 25
  • 1
    You run a command, it finishes, your program continues. Probably look at https://stackoverflow.com/questions/37586811/pass-commands-as-input-to-another-command-su-ssh-sh-etc – tripleee Nov 28 '17 at 09:50
  • what do you mean by *unable to sudo su - root*? any error? –  Nov 28 '17 at 10:16
  • I am unable to perform commands as root when doing sudo su - root from a script (remote in my case). consider you have a script where you first do sudo su - root and then run, whoami from the very same script and expect that, output to whoami will be root. However, in my case whoami gives me $user and not root which is the problem. Hope this explains... – sulabh chaturvedi Nov 28 '17 at 10:24
  • @tripleee - expect solves the problem and I understand now the issue. – sulabh chaturvedi Nov 28 '17 at 10:46

1 Answers1

1

This would not work:

stdin, stdout, stderr = ssh_client.exec_command('sudo su - root')
stdin, stdout, stderr = ssh_client.exec_command("whoami")

which is basically the same as following comamnds:

[local-host] # ssh user@host sudo su - root
[local-host] # ssh user@host whoami

Instead you should write like this:

stdin, stdout, stderr = ssh_client.exec_command('sudo su - root')
stdin.write('whoami\n')
# Here stdout.readlines() would not work as it would keep reading
# until EOF (which means the `sudo` comamnd has exited).
print(stdout.channel.recv(1024) )
pynexj
  • 19,215
  • 5
  • 38
  • 56