9

I'm trying to connect Django to a MySQL database which is accessible through an SSL connection. How do I configure this?

My first guess would be setting the 'OPTIONS' property of the database definition. However, I can't find info on what possible options to use. The option 'ssl': '/map/to/ca-cert.pem' does not work.

The following command seems to work:

mysql -h url.to.host -u lizard -p --ssl-ca=./ca-cert.pem

Edit: Ok I'm looking at the python-mysqldb documentation... maybe I can find the answer there.

4 Answers 4

18

Django uses the Python MySQLdb library to interface with MySQL. Looking at the MySQLdb connection documentation, it looks like the ssl option requires a dictionary argument. So this might work:

'OPTIONS': {'ssl': {'key': '/map/to/ca-cert.pem'}}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. It also works with 'ca' instead of 'key'. The answer was on this page: dev.mysql.com/doc/refman/5.5/en/mysql-ssl-set.html
It seems that 'ca' is the correct option, 'key' on its own caused MySQL to not verify the contents. Read more about it here: stackoverflow.com/questions/7287088/… and here: bugs.mysql.com/bug.php?id=62743
15

The MySQL client must be provided with three keys:

  • CA cert
  • client cert
  • client key

See the MySQL documentation for the instructions for creating these keys and setting up the server.

NOTE: There is an open issue that seems to be related to using openssl v1.0.1 to create the certificates for mysql 5.5.x

This is an example entry for the Django settings file:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  
        'NAME': '<DATABASE NAME>',                     
        'USER': '<USER NAME>',
        'PASSWORD': '<PASSWORD>',
        'HOST': '<HOST>', 
        'PORT': '3306',
        'OPTIONS':  {
            'ssl': {'ca': '<PATH TO CA CERT>',
            'cert': '<PATH TO CLIENT CERT>',
            'key': '<PATH TO CLIENT KEY>'
            }
        }
    }
}

1 Comment

I'm not entirely sure the "must be" in the first sentence is correct unless cert+key authentication is being used (in contrast to just encrypting the network traffic).
3

I was getting a "SSL connection error: SSL_CTX_set_default_verify_paths failed') "error when running python manage.py migrate

I used pip to install django-mysql-ssl package. It still wasn't working. I had to change "ca" to "ssl-ca" and now it works.

'OPTIONS':  {
                    'ssl': {'ssl-ca': '<PATH TO CA CERT>',

                            }
                      }

I'm not sure if it is actually using encryption, but it no longer throws an error. I am running local django app connected to an AWS mariaDB instance.

Edit: django-mysql-ssl package is not required starting from Django 1.8, as the functionality is built-in now. See Dependencies section in the package description here

Dependencies

This application is confirmed to work with Django 1.5. It should also work with Django 1.6-1.7. This plugin is not necessary for Django 1.8, as the capability is built into the core.

2 Comments

I got the same error and 'ssl': {'ssl-ca': '<PATH TO CA CERT>' worked for me too. Also, I see the path to the CA cert can be anything, even non-existent, and it still works fine. See stackoverflow.com/a/54543985/8645590.
"I'm not sure if it is actually using encryption" @BBaker, the connection will be encrypted, I checked by doing SHOW SESSION STATUS LIKE 'Ssl_cipher'.
0

In case of SSL encrypted connection will probably need cipher parameter

DATABASE = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_name',
        'USER': 'user',
        'PASSWORD': 'pass',
        'HOST': 'host',
        'PORT': '3306',
        'OPTIONS': {
            'ssl': {
                'ca': 'path/to/pem',
                'key': 'path/to/pem',
                'cert': 'path/to/pem',
                'cipher': 'AES128-SHA' #| 'AES128-SHA256' | 'DHE-RSA-AES256-SHA'
            }
        }
    }
}

MySQL passes a default cipher list to the SSL library. More details can be found here:

  1. https://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-protocols-ciphers.html#encrypted-connection-cipher-configuration
  2. https://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-protocols-ciphers.html#encrypted-connection-protocol-negotiation

Can't leave comments for @Drew answer, so let it be new one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.