SSH Tunnel to MariaDB - python

I've looked at several very similar examples, but I'm doing something wrong...probably because I'm mixing up local or remote binding addresses or well, not sure. I've yet to find a document that can describe what each is supposed to be to a newb like me.
I have a raspberry pi in a robot which has MariaDB installed. I can connect to the server from my PC with SQL Workbench.
I have a second Pi that needs a python script that can send data to the first pi...
IP Addresses, names and passwords have been changed to protect the innocent, but the whole thing is a closed network anyways.
import mysql.connector
import sshtunnel
_host = Robot's IP Address
_ssh_port = 22
_username = Robot user login
_password = Robot Password
_remote_bind_address = Robot's IP Address
_remote_mysql_port = 3308
_local_bind_address = Second Pi's IP Address
_local_mysql_port = 3308
_db_user = Database User Name
_db_password = Database Password
_db_name = "joycap"
with sshtunnel.SSHTunnelForwarder(
(_host, _ssh_port),
ssh_username=_username,
ssh_password=_password,
remote_bind_address=(_remote_bind_address, _remote_mysql_port),
local_bind_address=(_local_bind_address,_local_mysql_port)
) as tunnel:
connection = mysql.connector.connect(
user=_db_user,
passwd=_db_password,
host=_local_bind_address,
database=_db_name,
port=_local_mysql_port)
Here's the error I'm current getting...
pi#raspberrypi:~ $ python dbtest1.py
2018-04-05 06:11:42,262| ERROR | Secsh channel 0 open FAILED: Connection refused: Connect failed
2018-04-05 06:11:42,277| ERROR | Could not establish connection from ('Second Pi's IP Address', 3308) to remote side of the tunnel
Traceback (most recent call last):
File "dbtest1.py", line 29, in <module>
port=_local_mysql_port)
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/__init__.py", line 184, in connect
return MySQLConnection(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 100, in __init__
self.connect(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/abstracts.py", line 733, in connect
self._open_connection()
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 241, in _open_connection
self._do_handshake()
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/connection.py", line 108, in _do_handshake
packet = self._socket.recv()
File "/usr/local/lib/python2.7/dist-packages/mysql/connector/network.py", line 248, in recv_plain
raise errors.InterfaceError(errno=2013)
mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query
Would appreciate any advice! Would think someone would have made a video on doing this by now :)
Regards,
Matt

Finally worked it out through trial and error.
_host = "192.168.8.1" #Server where database is hosted
_ssh_port = 22 #ssh port
_username = "pi" #user name to host server
_password = "raspberry" #password to host server
_remote_bind_address = "127.0.0.1" #local connection IP to db on host(should probably not change)
_remote_mysql_port = 3306
_local_bind_address = "0.0.0.0" #local bind address(should probably not change)
_local_mysql_port = 3306
_db_user = "databaseuser"
_db_password = "databasepass"
_db_name = "databasename"

Related

How to fix "LDAPInvalidPortError: Port must be an integer"

I'm trying to connect to a server using LDAP. I've gotten the script to work on a test server that didn't use a specific port number. When trying to connect to our Dev-System, which uses a specific port I receive the following error:
File "site-packages\ldap3\core\server.py", line 117, in__init__
ldap3.core.exceptions.LDAPInvalidPortError: port must be an integer
[7836] Failed to execute script ldap_query
In the past we used python-ldap which didn't have an issue with a specified port in the ldap.initialize('LDAP://cd-dir...net/(Port)') command. The piece of code that generates the error can be seen below.
def ldap_connect(address, dn, password)
server = Server(address)
try:
conn = Connection(server, dn, password, auto_bind = True)
print('Authentication Successful')
print(conn.extend.standard.who_am_i())
except: LDAPBindError as err:
print(LDAPBindError)
ldap_connect('LDAP://cd-dir-cd-test....net:port/dc=cd...dc=com', 'user', 'password')
To solve the issue I tried taking the port number out of the address and instead put it in the following way:
server = Server(address, port = XXX)
That solved the "port must be an integer" error. However, that didn't solve the problem. The new error that I'm receiving is:
File "site-packages\ldap3\core\connection.py", line 325, in__init__
File "site-packages\ldap3\core\connection.py", line 340, in do_auto_bind
File "site-packages\ldap3\strategy\sync.py", line 56, in open
File "site-packages\ldap3\strategy\base.py", line 151, in open
ldap3.core.exceptions.LDAPSocketOpenError: invalid server address
[5976] Failed to execute script ldap_query
How can I solve this issue? Is there another way to set the port that I don't know of?
Best wishes,
You're passing an ldap:// URI to ldap_connect, but it looks like the ldap3.Server class expects an hostname or address. That is, you're currently trying to do this:
server = Server('ldap://cd-dir-cd-test.example.net:port')
When what you need is:
server = Server('cd-dir-cd-test.example.net', port=port)
And of course port must be an integer, not a string. You can use the ldap3.utils.uri.parse_uri method to extract the information you want from an ldap URI:
from ldap3 import Server, Connection
from ldap3.utils.uri import parse_uri
def ldap_connect(uri, dn, password):
parsed = parse_uri(uri)
server = Server(parsed['host'], use_ssl=parsed['ssl'], port=parsed['port'])
conn = Connection(server, dn, password, auto_bind = True)
print('Authentication Successful')
print(conn.extend.standard.who_am_i())
return conn
conn = ldap_connect('LDAP://cd-dir-cd-test....net:port/dc=cd...dc=com',
'user', 'password')

Cannot acquire connection to Neo4j database

I am trying to connect to my Neo4j graph database server from a new machine. I can successfully connect from an older machine but do not wish to use the older one anymore.
I have reduced the problem to a simple script that returns an exception:
from neo4j.v1 import GraphDatabase, basic_auth
auth = basic_auth("username","password")
session = GraphDatabase.driver("bolt://remote.server:7687",auth=auth).session()
statement = """MATCH (a:Protein)
WHERE a.name={name}
RETURN a.Accession"""
tx = session.begin_transaction()
record = tx.run(statement,{'name':"ARCH_HUMAN"}).single()
print record['a.Accession']
session.close()
And the error message is:
File "Test.py", line 10, in <module>
tx = session.begin_transaction()
File "/home/username/anaconda2/lib/python2.7/site-packages/neo4j/v1/api.py", line 432, in begin_transaction
self._connect()
File "/home/username/anaconda2/lib/python2.7/site-packages/neo4j/v1/api.py", line 269, in _connect
self._connection = self._acquirer(access_mode)
File "/home/username/anaconda2/lib/python2.7/site-packages/neo4j/v1/direct.py", line 52, in acquire
raise ServiceUnavailable("Cannot acquire connection to {!r}".format(self.address))
neo4j.exceptions.ServiceUnavailable: Cannot acquire connection to Address(host='remote.server', port=7687)
Port 7687 is open (confirmed via netstat -tulpn and iptables -L), and neo4j is configured to listen to 0.0.0.0:7687. In addition, .neo4j/known_hosts contains an entry for host 0.0.0.0
What's strange is that I get a different error message (neo4j.exceptions.AuthError) if I break the authentication by using an incorrect password. So the connection is being made to check the password, but still I cannot connect with the correct auth.
What's going on?
I too had the same issue and turns out the driver was the issue.
I did some experiments and found out that the last driver that it works for is neo4j-driver==v1.1.0 but the next version neo4j-driver==v1.2.0 it stops working for some reason.
Try uncomment dbms.connectors.default_listen_address=0.0.0.0 And check this
# Bolt connector
dbms.connector.bolt.enabled=true
dbms.connector.bolt.tls_level=OPTIONAL
dbms.connector.bolt.listen_address=:7687
# HTTP Connector. There must be exactly one HTTP connector.
dbms.connector.http.enabled=true
dbms.connector.http.listen_address=:7474
# HTTPS Connector. There can be zero or one HTTPS connectors.
dbms.connector.https.enabled=true
dbms.connector.https.listen_address=:7473

can't login with Paramiko ssh client

local-host --->Aterm server (security server ) -----> target-machine(
I am trying to write a code in Python using Paramiko to first SSH from local-host to the target-machine. From the target-machine, I want to capture some outputs and store them locally either as a variable or as a file (havent got to that point yet). I found an example from stackoverflow where they talk about using nested SSH with paramiko, and I follow it but I get stuck here:
i need just reaching the target-machine
My code:
import paramiko
import sys
import subprocess
hostname = '10.10.10.1'
port = 22
username = 'mohamed.hosseny'
password ='Pass#1'
client = paramiko.Transport((hostname, port))
client.connect(username=username, password=password)
client.close()
but i found the below error message :
Traceback (most recent call last):
File "C:/Users/mohamed.hosseny/Desktop/Paramiko.py", line 13, in <module>
client = paramiko.Transport((hostname, port))
File "C:\Python27\lib\site-packages\paramiko\transport.py", line 332, in
__init__
'Unable to connect to {}: {}'.format(hostname, reason))
SSHException: Unable to connect to 10.10.10.1: [Errno 10060] A connection
attempt failed because the connected party did not properly respond after
a period of time, or established connection failed because connected host
has failed to respond
paramiko.Transport is a lower level API. Don't use it unless you have a good reason. Instead, you can use paramiko.SSHClient.

Why python code cannot connect to RabbitMQ remotely?

I'm trying to connect from the one machine to another remote server with installed RabbitMQ.
The RabbitMQ is working perfectly locally, but when I connect to it from the another machine then an error is occurs:
root#xxx:~# python3 rabbitmq.py
Traceback (most recent call last):
File "rabbitmq.py", line 8, in <module>
connection = pika.BlockingConnection(pika.ConnectionParameters(parameters))
File "/usr/local/lib/python3.4/dist-packages/pika/connection.py", line 652, in __init__
self.host = host
File "/usr/local/lib/python3.4/dist-packages/pika/connection.py", line 392, in host
(value,))
TypeError: host must be a str or unicode str, but got <ConnectionParameters host=111.111.111.111 port=5672 virtual_host=product ssl=False>
root#xxx:~#
TypeError: host must be a str or unicode str, but got ConnectionParameters host=111.111.111.111 port=5672
virtual_host=product ssl=False
The Python code on other remote machine:
import pika
credentials = pika.PlainCredentials(username='remoteuser', password='mypassword')
parameters = pika.ConnectionParameters(host='111.111.111.111', port=5672, virtual_host='/', credentials=credentials)
#connection = pika.BlockingConnection(pika.ConnectionParameters('111.111.111.111:15672')) # --- it doesn't work too
connection = pika.BlockingConnection(pika.ConnectionParameters(parameters))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
User "remoteuser" has admin rights and access to virtual host "/"
http://111.111.111.111:15672/#/users
Name Tags Can access virtual hosts Has password
remoteuser administrator / ●
What is the problem?
you have double wrapped parameters, change:
connection = pika.BlockingConnection(pika.ConnectionParameters(parameters))
to:
connection = pika.BlockingConnection(parameters)

SSH tunnel from Python is closing automatically

I need some advice about the structure of my program. I'm connecting to an external MySQL database using sshtunnel. It's now working correctly (I can issue SQL commands and get results) but only if the commands are in the same function as the opening of the connection. If they're in a different function, the tunnel closes automatically before I can use it. (See code below - it closes between the two checkpoints.) So my questions are:
Should I check that the connection is open every time I want to use it? How do I do that?
How do I use the connection from a different function? I've seen a property called "keepalive" in sshtunnel (which will keep the connection open for a specified length of time) - is this what I need? How do I use it?
Can I forget about closing the tunnel manually?
Anything else that would help me get this working? As you can probably tell, I'm a newbie on the subject!
Thanks.
Python script:
import pymysql, shlex, shutil, subprocess
import logging
import sshtunnel
from sshtunnel import SSHTunnelForwarder
import iot_config as cfg
def OpenRemoteDB():
global remotecur, remotedb
sshtunnel.DEFAULT_LOGLEVEL = logging.DEBUG
with SSHTunnelForwarder(
(cfg.sshconn['host'], cfg.sshconn['port']),
ssh_username = cfg.sshconn['user'],
ssh_private_key = cfg.sshconn['private_key_loc'],
ssh_private_key_password = cfg.sshconn['private_key_passwd'],
remote_bind_address = ('127.0.0.1', 3306)) as server:
remotedb = None
remotedb = pymysql.connect(host='127.0.0.1', user=cfg.remotedbconn['user'], passwd=cfg.remotedbconn['passwd'], db=cfg.remotedbconn['db'], port=server.local_bind_port)
remotecur = remotedb.cursor()
print("Checkpoint 1")
#The next three lines work fine
# remotecur.execute("SELECT ActionID, Description FROM cmAction")
# for r in remotecur:
# print(r)
def SyncActions():
print("Checkpoint 2")
#the next three lines don't work (because the connection has closed)
remotecur.execute("SELECT ActionID, Description FROM cmAction")
for r in remotecur:
print(r)
# Main program starts here
OpenRemoteDB()
SyncActions()
Output:
2016-10-06 12:34:21,088| WAR | MainThrea/0954#sshtunnel | Could not read SSH configuration file: ~/.ssh/config
2016-10-06 12:34:21,153| INF | MainThrea/0981#sshtunnel | 0 keys loaded from agent
2016-10-06 12:34:21,963| DEB | MainThrea/1160#sshtunnel | Private key file (/etc/ssh/lavenham_private_key.key, <class 'paramiko.rsakey.RSAKey'>) successfully loaded
2016-10-06 12:34:22,003| INF | MainThrea/0901#sshtunnel | Connecting to gateway: lavenham.co.uk:22 as user 'lavenham'
2016-10-06 12:34:22,062| DEB | MainThrea/0904#sshtunnel | Concurrent connections allowed: True
2016-10-06 12:34:22,117| DEB | MainThrea/1300#sshtunnel | Trying to log in with key: b'611711d06f2b671960c3458d25ca3c20'
2016-10-06 12:34:23,083| INF | Srv-39033/1334#sshtunnel | Opening tunnel: 0.0.0.0:39033 <> 127.0.0.1:3306
Checkpoint 1
2016-10-06 12:34:23,290| INF | MainThrea/1350#sshtunnel | Shutting down tunnel ('0.0.0.0', 39033)
2016-10-06 12:34:23,424| INF | Srv-39033/1340#sshtunnel | Tunnel: 0.0.0.0:39033 <> 127.0.0.1:3306 released
2016-10-06 12:34:23,426| DEB | MainThrea/1363#sshtunnel | Transport is closed
Checkpoint 2
Traceback (most recent call last):
File "/home/pi/Documents/iot_pm2/2016-10-06.py", line 33, in <module>
SyncActions()
File "/home/pi/Documents/iot_pm2/2016-10-06.py", line 27, in SyncActions
remotecur.execute("SELECT ActionID, Description FROM cmAction")
File "/usr/local/lib/python3.4/dist-packages/pymysql/cursors.py", line 146, in execute
result = self._query(query)
File "/usr/local/lib/python3.4/dist-packages/pymysql/cursors.py", line 296, in _query
conn.query(q)
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 819, in query
self._affected_rows = self._read_query_result(unbuffered=unbuffered)
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 1001, in _read_query_result
result.read()
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 1285, in read
first_packet = self.connection._read_packet()
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 945, in _read_packet
packet_header = self._read_bytes(4)
File "/usr/local/lib/python3.4/dist-packages/pymysql/connections.py", line 981, in _read_bytes
2013, "Lost connection to MySQL server during query")
pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')
As per steven-rumbalski's comment above:
Replace: with SSHTunnelForwarder(...) as server
With: server = SSHTunnelForwarder(...)
Then wrap: server.start() ... server.stop()
around the code you want to be sent via the SSH Tunnel.
Here is the converted code:
import pymysql, shlex, shutil, subprocess
import logging
import sshtunnel
from sshtunnel import SSHTunnelForwarder
import iot_config as cfg
def OpenSSHTunnel():
global server
sshtunnel.DEFAULT_LOGLEVEL = logging.DEBUG
server = SSHTunnelForwarder(
(cfg.sshconn['host'], cfg.sshconn['port']),
ssh_username = cfg.sshconn['user'],
ssh_private_key = cfg.sshconn['private_key_loc'],
ssh_private_key_password = cfg.sshconn['private_key_passwd'],
remote_bind_address = ('127.0.0.1', 3306)
)
def OpenRemoteDB():
global remotecur, remotedb
remotedb = None
remotedb = pymysql.connect(
host='127.0.0.1',
user=cfg.remotedbconn['user'],
passwd=cfg.remotedbconn['passwd'],
db=cfg.remotedbconn['db'],
port=server.local_bind_port
)
remotecur = remotedb.cursor()
print("Checkpoint 1")
def SyncActions():
print("Checkpoint 2")
# this should now work as expected
remotecur.execute("SELECT ActionID, Description FROM cmAction")
for r in remotecur:
print(r)
# Main program starts here
OpenSSHTunnel()
server.start()
OpenRemoteDB()
SyncActions()
server.stop()

Categories

Resources