With Python you would normally use MySQL Connector/Python or the older MySQLdb to connect from Python to MySQL, but there are more options.
There are also multiple Python implementations: CPython (the main implementation), PyPy, Jython and IronPython. PyPy tries to be faster than CPython by using a Just-in-Time compiler. Jython runs on the JVM and IronPython runs on the .NET CLR.
Connector/Python by default (Without the C Extension) is a pure Python implementation and can work with most if not all implementations. And for MySQLdb there is a drop-in replacement called PyMySQL, which is a pure python implementation.
So there are many options already. But for at least Jython it is also possible to use a Java (JDBC) driver.
But why would you use a different Python implementation? There are multiple reasons for that:
- Speed. PyPy can be faster and Jython has no Global Interpreter Lock (GIL) , which can allow for more concurrent execution.
- To access 'native' code. e.g. call Java code from Jython or C# from IronPython.
- Use existing infrastructure. You can deploy a Jython application on Tomcat.
- Create testcases, healthchecks etc. which uses the same settings and infrastucture as your Java application with the benefits of a scripting language.
I wanted to test how Connector/J behaves with regards to TLS (the successor of SSL).
Setup
The first step is to get Jython, and Connector/J on your system. On Fedora 23 this is easily done with a dnf install jython mysql-connector-java
.
Then I used MySQL Sandbox to setup a MySQL 5.7.10 sandbox. To enable TLS I did a ./my sql_ssl_rsa_setup
, which is the Sandbox version of mysql_ssl_rsa_setup. If you have a pre-5.7 version then you can use mysslgen instead.
To convert the CA certificate from the PEM format to the Java Key Store (JKS) format I used keytool.
$ keytool -importcert -trustcacerts -file ca.pem -keystore /tmp/mysql57keystore.jks
Enter keystore password:
Re-enter new password:
Owner: CN=MySQL_Server_5.7.10_Auto_Generated_CA_Certificate
Issuer: CN=MySQL_Server_5.7.10_Auto_Generated_CA_Certificate
Serial number: 1
Valid from: Fri Jan 08 16:23:16 CET 2016 until: Mon Jan 05 16:23:16 CET 2026
Certificate fingerprints:
MD5: B5:B5:2B:53:5C:91:A2:6A:64:B5:C9:12:85:A0:CE:CC
SHA1: 85:F1:AB:14:15:33:65:A8:71:4D:00:A6:C6:FC:8F:7F:BE:95:BA:B0
SHA256: CB:B9:D5:BC:26:76:37:3A:66:67:99:95:5B:3B:8E:95:84:6C:A4:5F:52:39:EF:2A:23:36:6E:AB:B0:3E:81:E0
Signature algorithm name: SHA256withRSA
Version: 1
Trust this certificate? [no]: yes
Certificate was added to keystore
Then I had to set my CLASSPATH in order for Jython to find Connector/J.
$ export CLASSPATH=/usr/share/java/mysql-connector-java.jar
Running the test
I used this to test the database connetion:
#!/usr/bin/jython
from __future__ import with_statement
from com.ziclix.python.sql import zxJDBC
from java.lang import System
System.setProperty("javax.net.ssl.trustStore","/tmp/mysql57keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword","msandbox");
jdbc_url = 'jdbc:mysql://127.0.0.1:18785/test?useSSL=true'
with zxJDBC.connect(jdbc_url, 'msandbox', 'msandbox', 'com.mysql.jdbc.Driver') as c:
with c.cursor() as cur:
cur.execute('SHOW SESSION STATUS LIKE \'Ssl_%\'')
for result in cur:
print('%-40s: %s' % result)
raw_input('Press any key to continue...')
This resulted in a working connection. From the database side it looks like this:
mysql> SELECT ATTR_NAME, ATTR_VALUE FROM
-> performance_schema.session_connect_attrs WHERE PROCESSLIST_ID=40;
+------------------+----------------------+
| ATTR_NAME | ATTR_VALUE |
+------------------+----------------------+
| _runtime_version | 1.8.0_65 |
| _client_version | 5.1.36-SNAPSHOT |
| _client_name | MySQL Connector Java |
| _client_license | GPL |
| _runtime_vendor | Oracle Corporation |
+------------------+----------------------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM performance_schema.status_by_thread WHERE
-> THREAD_ID=(SELECT THREAD_ID FROM performance_schema.threads
-> WHERE PROCESSLIST_ID=40) and VARIABLE_NAME LIKE 'Ssl_version';
+-----------+---------------+----------------+
| THREAD_ID | VARIABLE_NAME | VARIABLE_VALUE |
+-----------+---------------+----------------+
| 65 | Ssl_version | TLSv1 |
+-----------+---------------+----------------+
1 row in set (0.00 sec)
I wanted to see if upgrading Connector/J would change anythong. So I downloaded the latest release and change my CLASSPATH to only include that.
mysql> SELECT ATTR_NAME, ATTR_VALUE FROM
-> performance_schema.session_connect_attrs WHERE PROCESSLIST_ID=45;
+------------------+----------------------+
| ATTR_NAME | ATTR_VALUE |
+------------------+----------------------+
| _runtime_version | 1.8.0_65 |
| _client_version | 5.1.38 |
| _client_name | MySQL Connector Java |
| _client_license | GPL |
| _runtime_vendor | Oracle Corporation |
+------------------+----------------------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM performance_schema.status_by_thread WHERE
-> THREAD_ID=(SELECT THREAD_ID FROM performance_schema.threads
-> WHERE PROCESSLIST_ID=45) and VARIABLE_NAME LIKE 'Ssl_version';
+-----------+---------------+----------------+
| THREAD_ID | VARIABLE_NAME | VARIABLE_VALUE |
+-----------+---------------+----------------+
| 70 | Ssl_version | TLSv1.1 |
+-----------+---------------+----------------+
1 row in set (0.00 sec)
And it did. Connector/J 5.1.38 uses TLSv1.1 instead of TLSv1.0
No comments:
Post a Comment