Configuring MySQL SSL in Magento (to get your HIPAA auditor off your back)
Magento Security

Configuring MySQL SSL in Magento (to get your HIPAA auditor off your back)

I’ve been asked a few times now if there is a way to use encrypted MySQL connections in Magento.  Most of the time it is when merchants are selling medical products and HIPAA requirements come into play.  I am not an expert in HIPAA, nor do I want to be, but with the cost of vulnerabilities on the rise it made sense to at least look into it and get a good answer on how to do it.

The answer, to my surprise, is that there is no way of doing it out of the box.  The reason is actually very, very simple.  The PDO options that allow you to initiate SSL on MySQL are passed in as numerical values.  For example, the value for PDO::MYSQL_ATTR_SSL_KEY is 1007.  Shouldn’t be a problem, right?  Just pass in a numerical value for the config.

That works in the Zend Framework adapter, but it does not work for Magento.  All database configurations are stored in the local.xml file and the XML specification does not allow numbers for XML node names.  So no matter how you try to slice it it looks like getting the SSL settings into the Magento adapter will not work without a code change.  The Internet seems to confirm this.

But that doesn’t mean that it can’t be done.  So  I wrote a quick Magento adapter that allows you to pass in the constant values.  The implementation is about 10 lines of code and it’s super easy to test.

  1. Download the code from github.
  2. Configure MySQL – Note that when you create the server certificate you MUST use the IP address or hostname that you will be using in your Magento configuration
  3. Configure Magento

For step 3 first copy the Github code into your Magento installation.  Then modify your configuration such as this

<config>
 <global>
   <resources>
     <default_setup>
       <connection>
         <host><![CDATA[127.0.0.1]]></host>
         <username><![CDATA[root]]></username>
         <password><![CDATA[]]></password>
         <dbname><![CDATA[magentoee_114]]></dbname>
         <initStatements><![CDATA[SET NAMES utf8]]></initStatements>
         <model><![CDATA[mysql4]]></model>
         <type><![CDATA[secure_pdo_mysql]]></type>
         <pdoType><![CDATA[]]></pdoType>
         <active>1</active>
         <secure_driver_options>
           <MYSQL_ATTR_SSL_KEY>/etc/mysql-ssl/client-key.pem</MYSQL_ATTR_SSL_KEY>
           <MYSQL_ATTR_SSL_CERT>/etc/mysql-ssl/client-cert.pem</MYSQL_ATTR_SSL_CERT>
           <MYSQL_ATTR_SSL_CA>/etc/mysql-ssl/ca.pem</MYSQL_ATTR_SSL_CA>
         </secure_driver_options>
       </connection>
     </default_setup>
   </resources>
 </global>
</config>

The main difference is the node secure_driver_options.  Internally, what the driver does is append that to PDO:: and gets the value of the constant.  Then it adds it to the driver_options configuration array (notably absent since this adapter overwrites it) using the numerical values of the constants instead of node names.

Run the test script secure.mysql.test.php in your browser (or CLI).

There you go.

Note

  1. This is not an officially sanctioned Magento code example
  2. I have not tested it for performance, security, gremlins.
  3. I have built this as a proof of concept only
  4. Use at your own risk.
  5. If you find issues in the code, or a better implementation, feel free to contribute or let me know

Leave a Reply

Your email address will not be published. Required fields are marked *