Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the go-mysql-driver with ssl on aws with a mysql rds instance

I have a RDS instance running on AWS and I want to know how to connect to that instance over ssl.

From this link Using SSL with mysql database. AWS sets up our database registered with a certificate and provides the root certificate for download. AWS rds root ca

Now the go-mysql-driver provides this information in there documentation to setup an ssl connection.

rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile("/path/ca-cert.pem")
if err != nil {
   log.Fatal(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
   log.Fatal("Failed to append PEM.")
}
clientCert := make([]tls.Certificate, 0, 1)
certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-    key.pem")
if err != nil {
   log.Fatal(err)
}
clientCert = append(clientCert, certs)
mysql.RegisterTLSConfig("custom", &tls.Config{
                         RootCAs: rootCertPool,
                         Certificates: clientCert,
                        })
db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")

The example indicates that I need a client certificate and client key.

But amazon only provides the root certificate. How can I use that with go-mysql-driver to connect to my mysql instance?

like image 638
Jonathan Neitz Avatar asked Feb 10 '17 16:02

Jonathan Neitz


People also ask

How enable SSL in RDS MySQL?

For Amazon RDS for Oracle instances, you can turn on SSL mode by adding the SSL option in your custom option group. Amazon RDS for Oracle supports Transport Layer Security (TLS) versions 1.0 and 1.2. To use the Oracle SSL option, use the SQLNET. SSL_VERSION option setting in your option group.

How do I enforce SSL in RDS?

To enforce SSL, simply enable the newly introduced rds. force_ssl parameter ("0" by default) through the Parameter Groups page on the RDS Console, or through the CLI. Database instances that have this parameter enabled will only accept SSL connections.

Can I encrypt connection between my application and my DB Instance using SSL?

You can use Secure Socket Layer (SSL) or Transport Layer Security (TLS) from your application to encrypt a connection to a DB instance running MariaDB, Microsoft SQL Server, MySQL, Oracle, or PostgreSQL.

How do I connect to AWS RDS MySQL?

Sign in to the AWS Management Console and open the Amazon RDS console at https://console.aws.amazon.com/rds/ . In the navigation pane, choose Databases to display a list of your DB instances. Choose the name of the MySQL DB instance to display its details. On the Connectivity & security tab, copy the endpoint.


2 Answers

I'd add a comment to the previous answer, but my reputation isn't high enough. This is working for me:

    rootCertPool := x509.NewCertPool()
    pem, err := ioutil.ReadFile("/path/ca-cert.pem")
    if err != nil {
       log.Fatal(err)
    }
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
       log.Fatal("Failed to append PEM.")
    }
    mysql.RegisterTLSConfig("custom", &tls.Config{
                             ServerName: "qcaurora.cb556lynvxio.us-east-1.rds.amazonaws.com",
                             RootCAs: rootCertPool,
                            })
    db, err := sql.Open("mysql", "user:pass@tcp(qcrds.example.com:3306)/databasename?tls=custom")

The only change from the above is the addition of the ServerName field. I've also clarified the address field for use with a CNAME dns entry and using a password. If you don't use a CNAME to RDS, you could leave out the ServerName field.

I'm using go 1.11 with go-sql-driver/mysql version v1.4.1.

like image 200
fishybell Avatar answered Sep 19 '22 04:09

fishybell


From looking at the docs here and here and here, it looks like you simply need to set the RootCAs value to the root certificate you obtained from AWS. You don't need to set the Certificates value since you aren't using a client cert. So the code would look something like:

rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile("/path/ca-cert.pem")
if err != nil {
   log.Fatal(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
   log.Fatal("Failed to append PEM.")
}
mysql.RegisterTLSConfig("custom", &tls.Config{
                         RootCAs: rootCertPool,
                        })
db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
like image 29
Mark B Avatar answered Sep 19 '22 04:09

Mark B