How to alter session with paramiko - python

I want to write a script using python. It should connect via ssh to the server and execute few commands.
The problem is, it's required to change user during connection.
As example, it's possible in WinSCP:
http://winscp.net/eng/docs/ui_login_scp#shell (Parameter Shell: You can also make use of the option to alter session startup. For example to change the user after login (known as su))
So to connect with propper rights to my ssh server I must write following command into 'Shell' field in WinSCP:
sudo su - user
I need this very feature in paramiko.
And I can't execute sudo su - user after connection is established, cause my password isn't correct. It works only when I use this 'Shell' field.
Nevertheless, when I'm connecting to the server using PuTTY(win) or ssh(linux), I don't need to enter any options, from the start it allows me to have propper rights. Seems strange for me.
I don't know how to develop it using python/paramiko.
Help me pls.

Related

Running a python script which uses paramiko to ssh into other server and perform db refresh from jenkins

I have a python script that does some Database operations from an ec2 server by SSHing into another server using paramiko. The script runs fine when I run it directly from the server as ec2-user but when I run the same from Jenkins I get a permission error on /home/ec2-user/.ssh/id_rsa file.
used python3.8 /home/ec2-user/db_refresh.py command to run the script from Jenkins
After some reading and with the help of whomai command, I found that's expected since Jenkins runs the scripts as Jenkins user and no one part from the owner has permissions to read private keys in ~/.ssh/ folder.
I could change the permission so that everyone can read ec2-user's private key but I think that would be a terrible idea(As far as I've read) and I think ssh wouldn't even work if anyone apart from the owner has read permission to that private key(I remember reading it somewhere but not sure)
sshcon = paramiko.SSHClient()
sshcon.connect(MYSQL_HOST, username=SSH_USERNAME, key_filename='/home/ec2-user/.ssh/id_rsa')
That is how SSH into my database server using paramiko.
Can I run my scripts from jenkins as ec2-user or is there some other way that I can overcome this.
In the end, it turned to be quite simple(stupid me)
I just created a key pair for Jenkins user and used it for doing my operations.
One thing to note is since jenkins is service account normal su jenkins won't work. I had to do this sudo su -s /bin/bash jenkins.

Using a Python library to interact with adb and change to su on a device which doesn't have sudo

I'm currently using pure-python-adb to automate a few tasks using Python. The device I'm using is a Busybox based UNIX system, which has limited number of commands. It doesn't have sudo. The task I'm trying to accomplish is change the permission, owner and group of a new file that I have just pushed into the device. The problem right now is that in order to change the permission of a file, I should be in su mode. And to be in su, I have to give the password. This is where I'm stuck at. I'm unable to give the password to su.
This is what I have so far:
from ppadb.client import Client as AdbClient
client = AdbClient(host="127.0.0.1", port=5037)
device = client.device("device-6000")
device.shell("<command>")
I can pass normal commands like ls -lh or cd <PATH>, but I can't change to su. When I do pass su, the console just hangs. So I tried to pass the password along with the command using one of the answers I found online, echo <PW> | su -s, but the error I"m getting is,
'su: must be run from a terminal\r\n'
Is there any way to automate this task using Python?

MySQL Refusing Remote Connections

Using:
MySQL/MariaDB Ver 14.14 Distrib 5.7.23
Ubuntu 16.04.5 LTS (GNU/Linux 2.6.32-042stab131.1 x86_64)
Everything works perfectly from the local machine (a remote dedicated server) such as PYPMyAdmin, SQLAlchemy, etc, but it will not accept any remote connections. I can telnet to the MySQL port, it gives me a login prompt, and I have already set the remote user up with:
GRANT ALL PRIVILEGES ON . TO 'admin'#'%' IDENTIFIED BY 'p4$$w0rd' WITH GRANT OPTION;
FLUSH PRIVILEGES;
And yet I still get the following error when I try to login remotely via Python/SQLAlchemy. "Access denied for user 'admin'#'myrdns.myisp.net"
Is there some additional security feature that I need to tweak that I am unaware of to enable remote access to one server from another?
You need to change/add grants for your desired username in order to access your database remotely, i.e.
GRANT ALL PRIVILEGES ON *.* TO 'user'#'%' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;
You'll need to issue the following command as well, before being able to connect.
FLUSH PRIVILEGES;
Since you (probably) did it already, you might wish to check your config file, in order to see if there's any bind address being set. In case of editing your config file, you'll need to issue server restart.
Sometimes it's due to some firewall blocking rules as well, but you'll need to confirm and resolve it on your network/machine if that's the case.
Be warned, however, that it is advised that you set up SSL certificate if you allow remote access to your database.
Also be aware that you can issue remote login without logging in "directly", i.e. you can connect to your remote machine/server via SSH client, then connect to your mysql server via localhost/127.0.0.1 address.

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.
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

Options to run a commnd remotely over ssh

I have numerous test servers. These test servers get re-imaged frequently, and they have the same user account and password after being re-imaged. I want to write a python script that runs a command remotely over ssh on one of these servers, without prompting user for a password, and gathers the output of the command. In some circumstance I want to run one command, get output, analyze the output. In other situation, I want to run several commands at a time (possibly run a script file). I read many postings about running commands remotely, using third party packages (e.g. paramiko). Is there a recommended way to achieve this task without using additional packages ? The server from which my script will be run might not have the package installed.
Or should I used pexpect ?
Ideally I would like to use subprocess and capture the output (providing password as an argument). Of course, my script has to handle the case when the client is logging for first time, and prompted to add ssh key to .ssh/knownhosts file.
Thank you,
Ahmed.
If host key security is not an issue (you are on a trusted network etc), you can bypass the host checking. And if you use key-based authentication there is no need for a password prompt:
ssh -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -oPasswordAuthentication=no \
-n doctor#tardis some_cmd
This way you can just use subprocess as if you executed some_cmd locally.

Categories

Resources