import paramiko
client = paramiko.SSHClient()
client.load_system_host_keys()
ip = '192.168.100.6'
client.connect(ip, username='root', password='mima')
i, o, e = client.exec_command('apt-get install sl -y --force-yes')
print o.read(), e.read()
client.close()
i used this example.. it is working fine but i want after login server1 to login server2
i mean nested ssh .
can't you call the ssh command from inside of your client.exec_command?
like:
client.exec_command('ssh user#host2 "apt-get install sl -y --force-yes"')
You exec the command "ssh" in the client, and not apt-get.
You can't really start a paramiko session on the client as long as your python program isn't there. The software you start using ssh must live on that machine.
Perhaps first scp a copy of your software, and start that using a parameter like -recursive_lvl = 1 ?
Related
I have to monitor 8 to 9 servers. I am thinking of creating a python script that will create a menu to login to any servers and after using ssh to login to the server, can I be able to execute commands in the server as the 'user' specified in the ssh. Please see the command below in python. I am importing 'os' to execute the bash commands.
server_login = "ssh {}#{}".format('user_name','10.111.0.10')
os.system(server_login)
you can install paramiko for this
pip install paramiko
then the script can be like
import paramiko
host = "google.com"
port = 22
username = "user"
password = "Pass"
command = "ls"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port, username, password)
stdin, stdout, stderr = ssh.exec_command(command)
lines = stdout.readlines()
print(lines)
If paramiko isn't your style, I can think of two other ways to do this:
run the command: ssh <user>#<host> <command> for every command via os.system calls. This gets rather cumbersome when you're using passwords for SSH instead of keys.
run ssh <user>#<host> with the subprocess library instead so you can get access to stdin and stdout and run multiple commands in the session
import subprocess
p = subprocess.Popen(['ssh','root#example.com'], stdout=PIPE, stdin=PIPE)
p.stdin.write("ls\n")
print(p.stdout.read())
I'm writing python script executing bash script inside virtualbox VM using paramiko python library. The code snippet below:
stdin, stdout, stderr = i[2].exec_command("\"\Program Files\Oracle\VirtualBox\VBoxManage.exe\" guestcontrol \"virtnet_proxy\" run --exe \"/home/username/show_ip.sh\" --username username --password password" )
exit_status = stdout.channel.recv_exit_status()
if exit_status == 0:
proxy_ip=stdout.readlines()
print ("got proxy ip from host ", i[0], proxy_ip, stderr.readlines())
Connects to windows host and
should print ip address of a VM's interface. If you run this command in cmd it works fine but using paramiko ssh client, stdout is empty. If you run similar code except you connect to linux virtualbox host (and run linux command) stdout.readlines() works fine and contains output of bash script. Stderr output:
VBoxManage.exe: warning: Error getting stdout handle: VERR_NOT_IMPLEMENTED\r\n', 'VBoxManage.exe: warning: Error getting stderr handle: VERR_NOT_IMPLEMENTED\r\n
Bash script:
ips=$(hostname --all-ip-addresses)
read -ra arr <<< "$ips"
echo"${arr[0]}"
As i said stdout is empty only if you connect to windows host and run vboxmanage command on guest machine.
Thank You in advance,
Wojtek
EDIT: I've changed ssh server on windows host from OpenSSH to FreeSSHd and the code worked !
I am trying to do a ssh to my local machine - 127.0.0.1, which works fine.
Next, I am trying to run two commands through ssh client. However, I see that the next command fails. I could see that my tap device is created. However, the tap device is not turned up. Here is my code. I tried the ifconfig and it works fine.
However, it is the sudo commands that is creating a problem.
self.serverName is 127.0.0.1
def configure_tap_iface(self):
ssh = paramiko.SSHClient()
print('SSH on to PC')
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.serverName, username='zebra', password='Zebra#2018')
stdin, stdout, stderr = ssh.exec_command('ifconfig')
#print(stdout.read())
session = ssh.get_transport().open_session()
session.get_pty()
session.exec_command('sudo ip address add 192.168.0.1/24 dev cloud_tap && sudo ip link set cloud_tap up')
session.close()
time.sleep(3)
ssh.close()
You can use sudo sh -c 'commands' to run multiple shell commands in a single sudo invocation.
session.exec_command("sudo sh -c 'ip address add 192.168.0.1/24 dev cloud_tap && ip link set cloud_tap up'")
I have a nat and it has various server
So from my local server I want to go to nat and then from nat i have to ssh to other machines
Local-->NAT(abcuser#publicIP with key 1)-->server1(xyzuser#localIP with key 2)
nat has different ssh key
and each of the server has different ssh key
how can i accomplish this type of multihop ssh using fabric
I tried using env.roledefs feature but it doesnt seems to be working
also I am not sure how to define two ssh keys.I know we can define a list of keys with env.key_filename but issue is will it check each key with each server?How can I be more specific and match a key with one server only
I have tried using command from my local machine
fab deploy -g 'ec2-user#54.251.151.39' -i '/home/aman/Downloads/aws_oms.pem'
and my script is
from __future__ import with_statement
from fabric.api import local, run, cd, env, execute
env.hosts=['ubuntu#10.0.0.77']
env.key_filename=['/home/ec2-user/varnish_cache.pem']
def deploy():
run("uname -a")
It's possible. Double hop to 10.0.0.2 (and list files) via gateway hop 10.0.0.1. Basically, you simply nest the connections with the gateway parameter.
# coding: utf-8
from fabric import Connection
path = '/'
conn1 = Connection(host='user1#10.0.0.1', connect_kwargs={'password': '***'})
conn2 = Connection(host='user2#10.0.0.2', connect_kwargs={'password': '***'}, gateway=conn1)
result = conn2.run(f'''cd {path} && ls -al''', hide=True)
conn2.close()
conn1.close()
msg = "Ran {0.command!r} on {0.connection.host}, got stdout:\n{0.stdout}"
print(msg.format(result))
Please remember to run the SSH connection manually once to introduce the servers to each other!
Install via
pip3 install --upgrade fabric
pip3 install cryptography==2.4.2 # optional to hide some annoying warnings
http://docs.fabfile.org/en/latest/concepts/networking.html
Python 3.6+.
In order to connect to remote hosts via an intermediate server, you can use the --gateway command-line option :
http://docs.fabfile.org/en/latest/usage/fab.html#cmdoption-g
Or, alternatively, set the env.gateway variable inside your fabfile :
http://docs.fabfile.org/en/latest/usage/env.html#gateway
For more detail information, see:
http://docs.fabfile.org/en/stable/concepts/networking.html#ssh-gateways
My scenario is I need to login to a remote machine and then do a sudo to another account like (sudo su anotheract) and then run the other required command.
But I am able to successfully connect to remote machine using below script. But the scripts hangs in the line where I am executing the sudo command(sudo su anotheract)
Can you please help me find the fix for this code?
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
ssh.connect(hostname='XX.XXX.XX.XX',port=22, username='myname',password='XXXXX')
ssh.exec_command=("sudo su anotheract")
stdout,stdin,stderr=ssh.exec_command("java -jar /usr/share/XXX/LogR.jar")
print stdout.readlines()
One (not very safe) way to do it is to pipe the password in. The caveat is that the user that you are using to connect to the box using paramiko should have sudo rights.
For example:
supass = 'some_pass'
stdout, stdin, stderr = ssh.exec_command('echo %s | sudo -S anotheract' % supass)
Again, this is not a very safe implementation but gets the job done in a jiffy.
import pxssh
ssh = pxssh.pxssh()
ssh.login('host', 'user', 'password')
ssh.sendline("sudo su anotheract")
ssh.prompt('yourrootpassword')
And in paramiko on most linux systems you cant do sudo commands thats because sudo expect commands from tty and then it isnt raise exception, but you can try method invokeshell, but I used paramiko many years ago I dont remember what was been wrong with it. If you want send various commands on shell you could use pxssh.
It can hangen because sudo waits for password. Try to add NOPASSWD: statement to the /etc/sudoers.
user ALL = NOPASSWD: /bin/true
Also it is impossible to change user using su and then continue do to something after su is finished. When su is finished, you are back to your original shell of the original user.
So you need to run all commands with sudo:
stdout,stdin,stderr = ssh.exec_command=("sudo -u anotheract java -jar /usr/share/XXX/LogR.jar")