Skip to content

Secure SSL defaults #61

@wojtekmach

Description

@wojtekmach

We should ship with secure by default SSL configuration [1]. Currently we use OTP defaults.

I couldn't get this reliably to work, here's what I tried when setting verify: :verify_peer.

First of all, self-signed certificates automatically created by MySQL doesn't seem to work with verification:

Host name identity verification with VERIFY_IDENTITY does not work with self-signed certificates created automatically by the server, or manually using mysql_ssl_rsa_setup (see Section 6.3.3.1, “Creating SSL and RSA Certificates and Keys using MySQL”). Such self-signed certificates do not contain the server name as the Common Name value.

(https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.html)

I tried manually creating self-signed certs using [2] with different Common Name but no luck too. Same error:

iex> MyXQL.Client.connect(ssl: true, ssl_opts: [verify: :verify_peer, cacertfile: 'tmp/certs/client-cert.pem'])
{:error,
 {:tls_alert, {:unknown_ca, 'received CLIENT ALERT: Fatal - Unknown CA'}}}

Generating valid self-signed certificates is crucial to be able to run this on CI.

I then tried running tests against AWS Aurora (Provisioned, MySQL 5.7).

First, got protocol version error:

iex> opts = [hostname: "xxx.rds.amazonaws.com", ...]
iex> cacertfile = '/Users/wojtek/Downloads/rds-ca-2015-root.pem',
iex> MyXQL.Client.connect(opts ++ [ssl: true, ssl_opts: [cacertfile: cacertfile, verify: :verify_peer]])
{:error,
 {:tls_alert,
  {:protocol_version, 'received CLIENT ALERT: Fatal - Protocol Version'}}}

That instance only supports TLSv1 so we force that versions:

iex> MyXQL.Client.connect(opts ++ [ssl: true, ssl_opts: [cacertfile: cacertfile, verify: :verify_peer, versions: [:tlsv1]]])
{:error,
 {:tls_alert,
  {:handshake_failure,
   'received CLIENT ALERT: Fatal - Handshake Failure - {bad_cert,hostname_check_failed}'}}}

Finally, with ssl_verify_fun I was able to get this to work:

iex> MyXQL.Client.connect(opts ++ [ssl: true, ssl_opts: [cacertfile: cacertfile, verify: :verify_peer, versions: [:tlsv1], verify_fun: &:ssl_verify_hostname.verify_fun/3]])
{:ok, %{...}}

However, I'd prefer not to add a dependency.

[1] https://blog.voltone.net/post/23
[2] https://dev.mysql.com/doc/refman/8.0/en/creating-ssl-files-using-openssl.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions