Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "must be run from a terminal" when switching to root user using Paramiko module in Python

I am trying to automate a task through a Python script. The idea is to login as a regular user and then send a su command and switch to the root account.

The reason I can't directly login as root is that SSHD doesn't allow root logins.

Here's what I have:

ip='192.168.105.8'
port=22
username='xyz'
password='abc'
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,port,username,password)
print ("SSH connection established")

stdin,stdout,stderr=ssh.exec_command('sudo fast.sh')
    outlines=stdout.readlines()
    outlines+=stderr.readlines()
    resp=''.join(outlines)
    print(resp)

Now, I want to send the su command and echo the root password. I am aware this is not good practice but I need a quick and easy way to test this so I am OK with that.

However, when I do this stdin,stdout,stderr=ssh.exec_command('su') and provide the password, I get an error

su: must be run from a terminal

Can some one help me to solve this.

I am running Python script on my Windows laptop to ssh into a Linux device and then switch to the root user using the su command and echo the password so that I can run other commands as root.

Thanks.

like image 541
user2500239 Avatar asked Dec 17 '25 18:12

user2500239


1 Answers

First, as you know, automating su or sudo is not the correct solution.

The correct solution is to setup a dedicated private key with only privileges needed for your task. See also Allowing automatic command execution as root on Linux using SSH.


Anyway, your command fails because sudo is configured to require an interactive terminal with requiretty option in sudoers configuration file (as a way to deter its automation).

Paramiko (correctly) does not allocate a pseudo terminal for exec channel by default.

Either remove the requiretty option.

If you cannot remove it, you can force Paramiko to allocate pseudo terminal using get_pty parameter of exec_command method:

ssh.exec_command('sudo fast.sh', get_pty=True)

But that's not a good option, as it can bring you lot of nasty side effects. Pseudo terminal is intended for an interactive use, not for automating command execution. For some examples, see

  • Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
  • Remove of unwanted characters when I am using JSch to run command
  • Removing shell stuff (like prompts) from command output in JSch
like image 187
Martin Prikryl Avatar answered Dec 19 '25 07:12

Martin Prikryl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!