Python script to connect via SSH tunnel to MySQL database at Namecheap - python

I am trying something since two days googling and reading forums without any success.
I have a MySQL database hosted at Namecheap.com that I need to access from my local linux machine via a Python script for creating tables and entries.
Namecheap say"
"Remote MySQL connection is disabled on our shared servers due to security reasons, but you can easily setup SSH tunnel between your PC and our server using SSH-client (for example, Putty) with the MySQL port (3306) forwarding. After completing it you will have port 3306 on your local machine listening and forwarding to your remote server's localhost on port 3306. Thus you can connect to the remote server's MySQL database effectively as though it were running on your local box. "
And give an example using PuTTY
"Create a session in PuTTY using your server IP-address as hostname and port 21098"
The point is that I need my Python script to do this automatically without any prompting for password, etc.
Have read something about paramiko but didn't get the point as SSH is something new to me (apart of accessing my linux machine).
I can successfully login manually via command line into my hosting account after having entered password, but this is just about all because then do not know how to run then script that is on my machine.
ssh -p 21098 my_user_name#server137.web-hosting.com
Edit:
Great, something is at least happening now after having cleaned up my python directory (remaining paramiko.py file created problems).
Also made a small change on line 2 of your script (ssh = SSHClient() ->> ssh = paramiko.SSHClient())
Then did the following:
ssh -p 21098 my_username#server137.web-hosting.com
to login into the remote host, and after successful login entering my password
ssh-keygen -t rsa
created a key without pasphrase which I afterwards recuperated via ftp to save it in my local machine folder
/home/daniel/python_scripts/sshkey
back to my local machine I then run below python script
#!/usr/bin/python
import paramiko
#clean the screen
os.system('clear')
myPkey = paramiko.RSAKey.from_private_key_file('/home/daniel/python_scripts/sshkey/key')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #if you want to auto add the host RSA key
ssh.connect('server137.web-hosting.com', 21098, 'my_username', pkey=myPkey)
sys.exit()
but this is what I got:
Traceback (most recent call last):
File "./my_vimeo.py", line 13, in <module>
ssh.connect('server137.web-hosting.com', 21098, 'my_username', pkey=myPkey)
File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 307, in connect
look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
File "/usr/local/lib/python2.7/dist-packages/paramiko/client.py", line 519, in _auth
raise saved_exception
paramiko.ssh_exception.AuthenticationException: Authentication failed.
'my_username' is obviously not the one as shown....
Whatsoever, there is something that I did not understand and obviously did wrong.....

Paramiko is really what you're looking for.
Basically, it is an SSH Client (like PuTTY, for one..) that even has TTY support.
Essentially, you would use their class SSHClient and call the connect method. You can do it without a password. However, you will need a public key, which paramiko also supports in lieu of a password.
So, somewhere along the line, when you do ssh -p 21098 my_user_name#server137.web-hosting.com, what you're saying is to server137, check the public key in my hostkeys file, and please verify I can connect.
You could then use the public key instead:
import paramiko
myPkey = paramiko.RSAKey.from_private_key_file('<private_key_path_on_your_server>')
ssh = SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #if you want to auto add the host RSA key
ssh.connect('server137.web-hosting.com', 21098, 'my_user_name', pkey=myPkey
You can see how to set up your keys here: Paramiko ssh connection without password
Paramiko documentation for SSHClient here: Paramiko Client docs

Related

Paramiko can't find keys from ssh-agent on Windows

I am trying to connect to a test device on my local network using paramiko and SSH. If I specify the filename of my key and its passphrase, I can connect to the device without a problem. However, since my script is meant to run on any machine that has the key added to the ssh-agent, I am trying to find a way around that.
ssh-add -l shows me that the key is active in my ssh-agent, but if I use the get_keys() method from the paramiko.Agent-class, there's just an empty list, meaning to me that Paramiko either can't connect to the ssh-agent or doesn't have the permissions to get the keys.
From shell, I can just connect to the device with ssh root#IPADDRESS. When I try to connect to device with Paramiko without specifying the path to the key and its passphrase, I'm just getting the "Authentication failed" error.
import paramiko
import os
def createSSHClient(server, port, user):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(server, port, username=user)
return client
ssh = createSSHClient('IPADDRESS', 22, 'root')
Checking SSH_AUTH_SOCK in os.environ gives me back False, but as far as I know, SSH on Windows doesn't quite work like on Unix/Linux.
Paramiko can talk to Windows OpenSSH ssh-agent since 2.10 only (and it was buggy in 2.10.3). Make sure you have the latest version of Paramiko.
Older versions could talk to PuTTY Pageant only.

Can I connect to a mysql database on another server?

I have a mysql database on a server for work. I ssh ont the server and then enter the database using mysql -u username -p at which time the command line will prompt me for my password.
I'd like to access the database remotely for some development. I see that mysql.connector is a library for connecting to mysql databases, but can I ssh onto the server and then access the database using python?
You can use SSH tunneling to redirect a port listening on your local machine to a port on the remote machine.
ssh -L9999:localhost:3306 me#my.work.com
This will redirect traffic from port 9999 on your machine to port 3306 on my.work.com. We gave localhost to -L since we want to tunnel to the server itself. We could also create a tunnel through your work server to some machine accessible to it only.
Now you can connect your connector on your own machine using port 9999 and the traffic is tunneled to my.work.com:3306.
You can use the tunnel.py code from https://gist.github.com/shnjp/856179.
with make_tunnel('me#mywork.com:3306') as t:
mysql.connector.connect(host='localhost',
database='mysql',user='root',password='PASS')
This assumes that your localhost doesn't have any application running on port 3306. If you have some, then you need to use "port=" argument in make_tunnel and provide a different port to use on the localhost.
You can also connect from python to the database without using any tunnel.
For that, enable the mysql server to allow connections from the outside uncommenting and changing the bind-address line in the /etc/mysql/my.cnf file to bind-address = 0.0.0.0. After that, restart the server with sudo service mysql restart and finally grant permissions to your user to access from the outside GRANT SELECT,INSERT,UPDATE,DELETE ON your_database.* TO 'your_user'#'%' IDENTIFIED BY 'your_pass';
Now you'll be able to connect from python to the database
import mysql.connector
ip_of_the_database = 'x.x.x.x'
cnx = mysql.connector.connect(host = ip_of_the_database,
user = 'your_user',
password = 'your_pass',
database = 'your_database')

Error when connecting to SFTP server using Python Pysftp

I am executing a Python script on my Linux server that uses pysftp to connect to another server in order to read files that are sitting in a directory of that remote server. When I run the script, it fails out while connecting to the remote server and creates a text file with the title: 'This service allows sftp connections only.'
This file is created inside my project directory. Below is the part of my code that is failing:
def sftp_get_file(sftp_host, sftp_username):
with pysftp.Connection(sftp_host, sftp_username) as sftp:
# transfer file from remote to local
sftp.get(remote_file, local_file)
Code is very simple and works when I've tested it using my local server as the remote server. When I tested it in the new environment by actually depending on SFTP, then it failed. Any suggestions? Is pysftp using SSH at some point when it should be using only SFTP?
Turns out the problem was due to me performing sftp.execute('ls') a couple lines down in the script. The server I was remoting onto only supported sftp commands and that command was forbidden.

Python execute remote application using server resource

I am trying to ran a matlab executable application from Python on a remote server.
I used following code:
os.system("\\Server-01\\D$\\matlab_t.exe 7.25 16") # 7.25 and 16 are input arguments of matlab_t.exe
The above code is running on my local machine. I noticed that it is using resources (CPU and memory) of my local machine, while I am trying to use resources on the remote server.
May I know how I can execute it using server resource?
Thanks.
That command will run on your computer, the path may be pointing to a remote server, but no one has told the remote server that it should execute code, only that they need to serve the matlab_t.exe file.
You have to use a mechanism to access the remote server. Normally ssh is used for this purpose, but the ssh daemon has to be running on the remote server and also you need to have access (ask you admin about that).
Then you can use python like this:
import paramiko
ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd_to_execute_on_remote_server)
In python, the os.system command only executes the command on the local machine. What you want is a local command that will get the server to execute it by itself.
If the server is Windows based then you can use PsExec to do this, if the server is Linux based then using ssh with a python library (like the other answer demonstrates) would probably be the way to go.
Using PsExec, your command in os.system would be something like:
psexec.exe \\Server-01 -u <username> -p <password> D:\matlab_t.exe 7.25 16
If you server needed no authentication, you could remove the username and password flags.

scp using paramiko doesnt work - ssh works fine

I have been able to use ssh and issue command in the remote server. Now I want to scp files from the remote server but that just seems like its impossible. I'm totally new to python and Paramiko. The error is permission denied in my local directory of darn windows. The files are supposed to come from the Mac. Any other really really simple example I can use to scp files from a remote Linux machine to my local Windows machine?
import paramiko
hostname = '192.xx.1.xx'
password = 'pop123'
username = "husbad2"
port = 22
mypath='C:\\Users\\handsonexpert\\Documents'
remotepath='/Users/ihussain/testdir/file3.txt'
t = paramiko.Transport((hostname, 22))
t.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put(mypath, remotepath)
To retrieve files from a remote host into a local directory:
......
localpath='C:\\Users\\handsonexpert\\Documents\\file3.txt'
remotepath='/Users/ihussain/testdir/file3.txt'
......
sftp.get(remotepath, localpath)
You're not using scp here, but SFTP (SFTPClient).
If you're set on using scp, maybe take a look at this paramiko scp client, there is an example of how to use it here.
Aside, out of general security interests and programming style, don't hard code your password and user credentials, and especially never publish them in a public forum like SO. We don't need them and you don't need to post them.

Categories

Resources