Search code examples
mysqlsslamazon-rdspymysql

Is there any documentation around this PyMysql/Mysql behavior?


This is the pymysql code I am using to connect to the database. I am testing with an AWS RDS Mysql instance with Mysql verison 5.7.22. I am getting the certificate from https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html

pymysql.connect(secret_dict['host'], user=secret_dict['username'],
    passwd=secret_dict['password'], port=port, db=dbname, 
    connect_timeout=5, ssl={'ca': './rds-combined-ca-bundle.pem'})

This code works with my test database with the user with ssl enabled and the user wo ssl enabled. - (Via ALTER USER 'encrypted_user'@'%' REQUIRE SSL; )

My question is is this pymysql behavior that I am seeing true of any MySQL verison database or documented anywhere? The behavior I am referring to is that if you add the ssl option to the connect call, it should work (successful connection) regardless or not the actual user has SSL required on it. I prefer not to test with every Mysql version :)

From taking a look at the pymysql code, what it seems to do is check if there are any ssl parameters associated with the request, adds it to an ssl map, and then creates a ctx_object from that ssl map and uses that ctx_ object when initializing a socket with the database.


Solution

  • Just found this on the Mysql 7 documentation guide

    "On the server side, the --ssl option specifies that the server permits but does not require encrypted connections. This option is enabled by default, so it need not be specified explicitly."

    "By default, MySQL client programs attempt to establish an encrypted connection if the server supports encrypted connections, with further control available through the --ssl-mode option:"

    "In the absence of an --ssl-mode option, clients attempt to connect using encryption, falling back to an unencrypted connection if an encrypted connection cannot be established. This is also the behavior with an explicit --ssl-mode=PREFERRED option."

    "PREFERRED: Establish an encrypted connection if the server supports encrypted connections, falling back to an unencrypted connection if an encrypted connection cannot be established. This is the default if --ssl-mode is not specified."

    So I believe what's happening is that pymysql doesn't specify the ssl-mode option so the ssl client side mode being used is PREFERRED which means that the client(pymysql) will try to establish an ssl connection(which I think fails because the user doesn't require it) and then fallback to the unencrypted connection which will be successful.