How to establish a SSH connection in Python - python

I am using Python 3.6.6 and i need to establish a SSH connection to a server.
I have the IP and port for the server, and i use my credentials to login, usually through putty. The servers is on Linux/Suse .
I need to get the list of directories in the server folder, and copy the content of one of the files out. I am using paramiko, and i need the connection to be open so i can execute and interact with the server.
I am not sure i am clear enough.
Below is my code
import paramiko
nbytes = 4096
hostname = '123.123.123.123'
port = 22020
username = 'uname'
password = 'pwd'
command = 'vi log'
client = paramiko.Transport((hostname, port))
client.connect(username=username, password=password)
stdout_data = []
stderr_data = []
session = client.open_channel(kind='session')
session.exec_command(command)
while True:
if session.recv_ready():
stdout_data.append(session.recv(nbytes))
if session.recv_stderr_ready():
stderr_data.append(session.recv_stderr(nbytes))
if session.exit_status_ready():
break
print ("rec status: ", session.recv_ready())
print ("exit status: ", session.recv_exit_status())
print ("".join(stdout_data))
print ("".join(stderr_data))
session.close()
client.close()

Related

Extract backups from Mikrotik with python

I have to extract backups from Mikrotik with python and save them in my server so these backups are saved in my computer and also on the servers. I've been searching for info about it but didn't have any luck. Can someone help me?
""" Authentication for remote desktops through ssh protocol """
import paramiko
from getpass import getpass
import time
HOST = 'xxx.xxx.xxx.xxx'
PORT ='xxx'
USER = 'xxxxxxx'
""" data =dict(hostname=HOST, port=PORT, username=USER) """
if name == 'main':
# try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy( paramiko.AutoAddPolicy())
password = getpass ('Insert password: ')
client.connect(HOST, PORT, username=USER, password=password)
stdin, stdout, stderr = client.exec_command('ls')
#tried everything here
time.sleep(1)
result = stdout.read().decode()
# except paramiko.ssh_exception.AuthenticationException as e:
# print('Failed authentication')
print(result)
You cannot do that with plain SSH. It will execute RouterOS commands (so no ls). The task can be done with FTP or SFTP (if you prefer SSH) client:
$ sftp admin#192.0.2.1
admin#192.0.2.1's password:
Connected to 192.0.2.1.
sftp> ls
flash
sftp> cd flash
sftp> ls
MikroTik-20210509-1756.backup MikroTik-20210509-1938.backup skins
sftp> get MikroTik-20210509-1756.backup
Fetching /flash/MikroTik-20210509-1756.backup to MikroTik-20210509-1756.backup
MikroTik-20210509-1756.backup 100% 345KB 808.0KB/s 00:00
sftp> exit

Is there a way to remotely port forward in Python 3? Ex: ssh jumpserver -L 8000:internal_server_name:8000 -N

I have a manual process of port forwarding using OS based SSH forwarding currently and I would like to do this through Python so that the connection auto closes after. Similar to how a 'with open' would work for a file write.
I am currently using it like so:
ssh jumpserver -L 8000:internal_server_name:8000 -N
and calling the api locally like so:
http://localhost:8000/get-answer/
This method works, but again, I am looking for a using/with open method.
I tried this without luck:
remote_host = "internal_server_name"
remote_port = 8000
local_port = 8000
ssh_host = "jumpserver"
ssh_port = 22
user = "ubuntu"
pkey = "~/.ssh.id_rsa"
transport = paramiko.Transport((ssh_host, ssh_port))
# Command for paramiko-1.7.7.1
transport.connect(hostkey = None,
username = user,
password = None,
pkey = pkey)
try:
forward_tunnel(local_port, remote_host, remote_port, transport)
except KeyboardInterrupt:
print ('Port forwarding stopped.')
sys.exit(0)

I want to copy a .wav file from my current system to linux server using python

Any one have idea then please suggest, This is how I'm doing now. bt not working.
Here I'm trying to copy my newtext.wav file to server location.
def copyToServer():
success = os.system("scp D:/AMRITESH/ContractMonitoring/newtext.wav
root#xxx.xxx.x.xxx:/usr/share/asterisk/sounds")
if (success != True):
print(success)
print "Connection Error"
else:
print "Connection Established"
def createSSHClient(server, port, user, password):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, user, password)
print "Connection Established Here"
return client
ssh = createSSHClient('xxx.xxx.x.xxx', 'xx', 'username', 'password')
scp = SCPClient(ssh.get_transport())
print "Sending file to server"
scp.put('D:/AMRITESH/ContractMonitoring/'+fileName, '/usr/share/asterisk/sounds')

Paramiko server: Redirect the output of a SUBPROCESS to a channel

I am trying to implement a (local fake) server with paramiko that responds to custom commands just like the original for testing purposes. Mainly copying from the supplied demo server, I managed to come up with this custom method to handle exec_requests for the server implemented via paramiko.ServerInterface:
def check_channel_exec_request(self,channel,command):
print("User wants to execute '%s'" %(command))
comm_main, comm_add = command.decode().split(sep=" ",maxsplit=1)
if comm_main in self.allowed_commands:
chout = channel.makefile("w")
subprocess.Popen(command,stdout=chout)
return True
else:
return False
After the server is running via:
PORT = 50007 # The same port as used by the server
HOST = 'localhost'
host_key = paramiko.RSAKey(filename = <FILEPATH>)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST,PORT))
sock.listen(1)
conn, addr = sock.accept() # Connected!
with conn:
trans = paramiko.Transport(conn)
trans.add_server_key(host_key)
trans.set_subsystem_handler("job",JobHandler)
server = FakeCluster() # Custom class sublassing paramiko.ServerInterface
trans.start_server(server=server)
chan = trans.accept() # Accept authentication from client
while trans.is_active(): # Do not close until inactive
time.sleep(1)
chan.close()
the client would try to execute echo 123 in the following manner:
PORT = 50007 # The same port as used by the server
HOST = 'localhost'
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind((HOST,PORT))
ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(HOST, PORT,username=<USERNAME>,password=<PASSWORD>)
ssh.exec_command("echo 123")
Right now, I am getting the error trying to execute the subprocess that 'ChannelFile' has no attribute 'fileno'. Furthermore I am wondering how to later execute a python script as a custom command called by exec_command. (Maybe by calling a batchfile that calls the python script?)
your question is really very confusing , here is what i did for communicating with remote server .
local machine : window
Remote Machine :ubuntu
Command on remote machine :'who'
import paramiko
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.268.21.26',port=22,username='root',password='default')
stdin,stdout,stderr=ssh.exec_command('who')
output=stdout.readlines()
print '\n'.join(output)
#output
#root tty7 2017-11-28 14:13 (:0)
#if you wish to execute a python file there , this should work
stdin,stdout,stderr=ssh.exec_command('python file.py')

connect to third server using script

I can do ssh from one server to another using this:
# ssh root#1.2.4.148
The following code is doing the same in pythonic way:
import paraminko
#paramiko.util.log_to_file('ssh.log') # sets up logging
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('1.2.4.148')
stdin, stdout, stderr = client.exec_command('ls -l')
But if I need to connect to third server from the second server, I can do this:
# ssh -t root#1.2.4.148 ssh root#1.2.4.149
How is this done in python?
My current server (250) has password less keys saved with 148 server for easy access. But connection to 149 from 148 will need password if that matters.
This python function will connect to middle_server first and then to last_server. It will execute the command "mycommand" on last_server and return it's output.
def myconnect():
middle_server='1.2.3.4'
middle_port=3232
middle_user='shantanu'
middle_key_filename='/root/.ssh/id_rsa.pub'
last_server='6.7.8.9'
last_port=1224
last_user='root'
last_password='xxxxx'
mycommand='pwd'
import paramiko
proxy_client = paramiko.SSHClient()
proxy_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy_client.connect(middle_server, port=middle_port, username=middle_user, key_filename=middle_key_filename)
transport = proxy_client.get_transport()
dest_addr = (last_server, last_port)
local_addr = ('127.0.0.1', 1234)
channel = transport.open_channel("direct-tcpip", dest_addr, local_addr)
remote_client = paramiko.SSHClient()
remote_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
remote_client.connect('localhost', port=last_port, username=last_user, password=last_password, sock=channel)
(sshin1, sshout1, ssherr1) = remote_client.exec_command(mycommand)
print sshout1.read()
except:
print "error"
return 0

Categories