Connect to remote database using SSH tunneling using Python - python

I am trying to connect to remote database using SSH tunneling however I am getting error. I am not sure exactly what is wrong, as when I create ssh tunnel from command line I am able to access the database, however same is not working from python.
command to create ssh tunner, which is working fine.
ssh -L 30080:phpmyadmin-www:80 root#host
however, following code is not working.
def __init__(self, host="127.0.0.1", user="root", password="pass", db="database"):
sshtunnel.DEFAULT_LOGLEVEL = logging.DEBUG
with SSHTunnelForwarder(
('hubif-delphi-dev.qa-egnyte.com', 22),
ssh_private_key="/home/egnyte/.ssh/id_rsa",
ssh_username="root",
remote_bind_address=('host', 80),
local_bind_address=('127.0.0.1', 30080)) as server:
print "successfully connected to ssh"
con = MySQLdb.connect(user=user, passwd=password, db=db, host='127.0.0.1', port=server.local_bind_port)
self.cur = con.cursor()
I am getting following error, while trying to create MySQL connection.
2017-03-06 10:20:23,509| ERROR | Secsh channel 0 open FAILED: Connection refused: Connect failed
2017-03-06 10:20:23,509| ERROR | Could not establish connection from ('127.0.0.1', 30080) to remote side of the tunnel
---------------------------------------- Stacktrace removed ----------------------------------------
super(Connection, self).__init__(*args, **kwargs2)
_mysql_exceptions.OperationalError: (2013, "Lost connection to MySQL server at 'reading initial communication packet', system error: 0")

Related

Docker SDK - Can't connect to DB from HOST

I want to create a temporary MySQL database for unit testing in Python. I decided to go with docker as the tests will be run on different machines.
As a first thing I run the container:
client = docker.from_env()
container = client.containers.run("ubuntu/mysql", detach=True, ports={3306:3307},environment={
'MYSQL_USER':'mysqluser',
'MYSQL_PASSWORD':'password',
'MYSQL_DATABASE':'mydb',
})
print('Container Started : {}'.format(container.status))
And then I try to connect using SQLAlchemy:
engine = sa.create_engine(f'mysql+pymysql://mysqluser:password#localhost:3307/mydb')
engine.connect()
which returns:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
EDIT
After putting sleep(10) after container.run, the response is different:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
Do you know what I'm doing wrong?
What I want to do is to connect to MySQL database on port 3307 (as one server already runs on the host). Then I want to create and populate a table.
EDIT2
Switching ports to {3307:3306} returns error:
docker.errors.APIError: 500 Server Error for http+docker://localhost/v1.41/containers/67a04b384bf3d39407881d4dfc73961932a3ce72fe8dc82c3cd6aedd57da2821/start: Internal Server Error ("driver failed programming external connectivity on endpoint hopeful_leakey (97840eb42d2c09b5e9754b634481d8e048c57ba2de8ffc10b34261de2f76600b): Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use")

Can't connect to MySQL server, No connection could be made because the tared machine actively refused it

I am trying to connect to a MySQL db on my ubuntu VPS with python and I am using this code
import pymysql
conn= pymysql.connect(host='remotehost',port='3306',
user='user',password='password',db='db')
a = conn.cursor()
sql = 'SELECT * from `users`;'
a.execute(sql)
countrow = a.execute(sql)
print("Number of rows :",countrow)
data = a.fetchone()
print(data)
When I run the code I get the following error
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'remotehost' ([WinError 10061] No connection could be made because the target machine actively refused it)")
I have checked my MySQL db and the 'user' that I am connecting to the server with has the "Any host" hostname set. I can't seem to fix this issue.
Fixed by commenting out
bind-address = 127.0.0.1 in /etc/mysql/mysql.conf.d/mysqld.cnf

Can I use Python Peewee with sshtunnel?

I've tried to use Peewee with sshtunnel to connect to a remote mysql db:
with SSHTunnelForwarder(
('server.pt', 9922),
ssh_password="pass_ssh",
ssh_username="user_ssh",
remote_bind_address=('localhost', 3306)) as server:
myDB = pw.MySQLDatabase("dbname", user="db_user", passwd="db_pass")
But I get an error
OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
Could you help me?
You probably need to include the local port that you've bound the tunnel to from the server object:
myDb = pw.MySQLDatabase("dbname", host="localhost", port=server.local_bind_port, user="db_user", passwd="db_pass")
See here for an example.

How to specify port number using mysql-connector-python (error 2003)

I am trying to connect via SSH to a MySQL server from my local Windows machine. The SSH connection works fine, but I am unable to connect to the MySQL server when running the following Python script:
import mysql.connector
import sys
import time
import paramiko
host = 'remote-ssh-host'
i = 1
while True:
print("Trying to connect to %s (%i/30)" % (host, i))
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, port=22, username='sshuser', password='sshpwd')
print("Connected to %s" % host)
break
except paramiko.AuthenticationException:
print("Authentication failed when connecting to %s" % host)
sys.exit(1)
except:
print("Could not SSH to %s, waiting for it to start" % host)
i += 1
time.sleep(2)
# If we could not connect within time limit
if i == 30:
print("Could not connect to %s. Giving up" % host)
sys.exit(1)
cnx = mysql.connector.connect(user="mysqluser", password="mysqlpwd",
host="mysqlhost",
port=3307)
Here is the output:
Trying to connect to remote-ssh-host (1/30)
Connected to remote-ssh-host
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\mysql\connector\network.py", line 469, in open_connection
self.sock.connect(sockaddr)
TimeoutError: [WinError 10060]
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\path\to\script\ssh_mysql_test.py", line 50, in <module>
port="3307"
...
File "C:\Python34\lib\site-packages\mysql\connector\network.py", line 472, in open_connection
errno=2003, values=(self.get_address(), _strioerror(err)))
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'mysqlhost:3307' (10060)
Similar questions have been asked here and here, but I think this problem has to do with the way mysql-connector-python handles the connection string for the port number, because when using the Putty terminal I can make it work:
login as: sshuser
sshuser#remote-ssh-host's password:
sshuser#remote-ssh-host:~$ mysql -h mysqlhost -P 3307 -u mysqluser -p
Enter password:
...
mysql>
But, when specifying the port number in the same way as e.g. the mysql-connector-python does:
login as: sshuser
sshuser#remote-ssh-host's password:
sshuser#remote-ssh-host:~$ mysql -h mysqlhost:3307 -u mysqluser -p
Enter password:
ERROR 2005 (HY000): Unknown MySQL server host 'mysqlhost:3307' (0)
I realize the error numbers are different (2003 vs. 2005), but I think that they are related. So the question actually is: How can I format the port number in such a way that the connection executes as -h hostname -P port instead of -h hostname:port?
The problem is that your ssh and MySQL connections are completely separated. In order for your MySQL connection to work through ssh, you need to tunnel the MySQL connection through the ssh one.
The first SO topic you linked actually provides the answer to this problem: uses an ssh tunnelling component to create the tunnel and the MySQL connection is directed through the tunnel.
server = SSHTunnelForwarder(
('host', 22),
ssh_password="password",
ssh_username="username",
remote_bind_address=('127.0.0.1', 3306))
The above code binds the ssh connection to port 3306 of the localhost. So any connection made to 127.0.0.1:3306 will be tunnelled through the ssh connection to the remote server.
engine = create_engine('mysql+mysqldb://user:pass#127.0.0.1:%s/db' % server.local_bind_port)
In the above code the MySQL connection is made to 127.0.0.1:3306, therefore it will be tunnelled though the ssh connection. You need to follow the same pattern: create an ssh tunnel bound to a local port and in your MySQL connection string specify this local port instead of the remote one.

Python connect to MySQL server using SSHTunnelForwarder and MySQLdb

I'm tring to understand what I should do in order to connect to a remote MySQL server using SSH.
from sshtunnel import SSHTunnelForwarder
with SSHTunnelForwarder(
('192.168.0.60', 22),
ssh_password="MySSHPASSWORD",
ssh_username="MUSSHUserName",
remote_bind_address=('192.168.0.30', 3306)) as server:
conn = MySQLdb.connect(user='UserNameOnSQLSERVER', passwd='PasswordOnSQLSERVER', host='192.168.0.60', db='myDB',
port=server.local_bind_port)
I've been able to connect to this server with the above configuration throw MySQL Workbench and Run queries and everything worked great
The problem is that when I'm trying to connect this DB by the above code I keep getting error:
_mysql_exceptions.OperationalError: (2003, "Can't connect to MySQL server on '192.168.0.60' (10060)")
I also tried to change the ip in MySQLdb.connect to be
conn = MySQLdb.connect(user='kiboUser', passwd='Lb24#db30#kL68', host='192.168.0.60', db='dbKiboDashboard',
port=server.local_bind_port)
and I got the following error:
_mysql_exceptions.OperationalError: (2003, "Can't connect to MySQL server on '192.168.0.30' (10060)")
Can please someone help me understand what im doing wrong
Thanks
remote_bind_address is the one you are tunneling into. Make sure to verify the server's TCP port that is listening.
To verify this, you could try the command
netstat
or
netstat -tln
This should work:
with SSHTunnelForwarder(
('ServerIP', sshport), #The server's IP and SSH port
ssh_password="MySSHPASSWORD",
ssh_username="MUSSHUserName",
remote_bind_address=('127.0.0.1', 3306)) as server: #The server's TCP IP and port, you're tunneling
conn = MySQLdb.connect(user='UserNameOnSQLSERVER', passwd='PasswordOnSQLSERVER', host='127.0.0.1',
port=server.local_bind_port) #Your TCP IP and port (your end of the tunnel)

Categories

Resources