Fork me on GitHub
Teleport

Database Access with Self-Hosted MySQL

This chapter covers a past release: 6.1. We recommend the latest version instead.

Self-Hosted MySQL

Create Certificate/Key Pair

Teleport uses mutual TLS for authentication to MySQL instances. As such, self-hosted MySQL instances must be configured with Teleport's certificate authority and a certificate/key pair that Teleport can validate.

To create these secrets, use the tctl auth sign command. Note that it requires a running Teleport cluster and should be run on the auth server.

# Export Teleport's certificate authority and generate certificate/key pair
# for host db.example.com with a one year validity period.
$ tctl auth sign --format=db --host=db.example.com --out=server --ttl=8760h

Flag descriptions:

  • --format=db: instructs the command to produce secrets in the format suitable for configuring a database server.
  • --host=db.example.com: server name to encode in the certificate, should match the hostname Teleport will be connecting to the database at.
  • --out=server: name prefix for output files.
  • --ttl=8760h: certificate validity period.

The command will create 3 files: server.cas with Teleport's certificate authority and server.crt/server.key with generated certificate/key pair.

Certificate Rotation
Teleport signs database certificates with the host authority. As such, when performing host certificates rotation, the database certificates must be updated as well.

Configure MySQL Server

To configure MySQL server to accept TLS connections, add the following to MySQL configuration file mysql.cnf:

[mysqld]
require_secure_transport=ON
ssl-ca=/path/to/server.cas
ssl-cert=/path/to/server.crt
ssl-key=/path/to/server.key

Additionally, MySQL database user accounts must be configured to require a valid client certificate:

CREATE USER 'alice'@'%' REQUIRE X509;
ALTER USER 'alice'@'%' REQUIRE X509;

By default the created user may not have access to anything and won't be able to connect so let's grant it some permissions:

GRANT ALL ON `%`.* TO 'alice'@'%';

See Configuring MySQL to Use Encrypted Connections in MySQL documentation for more details.

Configure Teleport

Teleport Database Access is available starting from the 6.0 release.

Download the appropriate version of Teleport for your platform from our downloads page.

Follow the installation instructions.

Start Auth/Proxy Service

Create a configuration file for a Teleport service that will be running auth and proxy servers:

teleport:
  data_dir: /var/lib/teleport
  nodename: test
auth_service:
  enabled: "yes"
proxy_service:
  enabled: "yes"
  # Set public address proxy will be reachable at.
  public_addr: teleport.example.com:3080
  # MySQL proxy is listening on a separate port and needs to be enabled
  # on the proxy server.
  mysql_listen_addr: 0.0.0.0:3036
ssh_service:
  enabled: "no"

Start the service:

$ teleport start --config=/path/to/teleport.yaml

Generate a short-lived join token for the database service and save it for example in /tmp/token:

$ tctl tokens add \
    --type=db \
    --db-name=test \
    --db-protocol=mysql \
    --db-uri=mysql.example.com:3306

Create Role and User

Create the role that will allow a user to connect to any database using any database account:

$ tctl --config=/path/to/teleport.yaml create <<EOF
kind: role
version: v3
metadata:
  name: db
spec:
  allow:
    db_labels:
      '*': '*'
    db_names:
    - '*'
    db_users:
    - '*'
EOF

Create a user assigned to the db role we've just created:

$ tctl --config=/path/to/teleport.yaml users add --roles=admin,db testuser

Start Database Service with CLI Flags

For a quick try-out, Teleport database service doesn't require a configuration file and can be launched using a single CLI command:

$ teleport start --debug \
   --roles=db \
   --token=/tmp/token \
   --auth-server=teleport.example.com:3080 \
   --db-name=test \
   --db-protocol=mysql \
   --db-uri=mysql.example.com:3306 \
   --labels=env=dev

Note that the --auth-server flag must point to the Teleport cluster's proxy endpoint because database service always connects back to the cluster over a reverse tunnel.

Start Database Service with Config File

Below is an example of a database service configuration file that proxies a single self-hosted MySQL database:

teleport:
  data_dir: /var/lib/teleport-db
  nodename: test
  # Proxy address to connect to. Note that it has to be the proxy address
  # because database service always connects to the cluster over reverse
  # tunnel.
  auth_servers:
  - teleport.example.com:3080
db_service:
  enabled: "yes"
  # This section contains definitions of all databases proxied by this
  # service can contain multiple items.
  databases:
    # Name of the database proxy instance used to reference in CLI.
  - name: "example"
    # Free-form description of the database proxy instance.
    description: "Example MySQL"
    # Database protocol.
    protocol: "mysql"
    # Database address, MySQL server endpoint in this case.
    #
    # Note: this URI's hostname must match the hostname specified via --host
    # flag to tctl auth sign command.
    uri: "mysql.example.com:3306"
    # Labels to assign to the database, used in RBAC.
    static_labels:
      env: dev
auth_service:
  enabled: "no"
ssh_service:
  enabled: "no"
proxy_service:
  enabled: "no"
Tip
A single Teleport process can run multiple different services, for example, multiple database access proxies as well as running other services such an SSH service or an application access proxy.

Start the database service:

$ teleport start --config=/path/to/teleport-db.yaml --token=/tmp/token

Connect

Once the database service has joined the cluster, log in to see the available databases:

$ tsh login --proxy=teleport.example.com:3080 --user=testuser
$ tsh db ls
Name    Description   Labels
------- ------------- --------
example Example MySQL env=dev

Note that you will only be able to see databases your role has access to. Read about Role-Based Access Control for more details.

To connect to a particular database server, first, retrieve credentials from Teleport using tsh db login command:

$ tsh db login example
Tip
You can be logged into multiple databases simultaneously.

You can optionally specify the database name and the user to use by default when connecting to the database instance:

$ tsh db login --db-user=root --db-name=mysql example

When logging into a MySQL database, tsh automatically configures a section in the option file with the name of client_<cluster-name>-<database-service-name> which mysql client can refer to via "group suffix" flag.

Suppose the cluster name is root, then you can connect to the database using the following mysql command:

# Use default database user and database name.
$ mysql --defaults-group-suffix=_root-example
# Specify database user and database name explicitly.
$ mysql --defaults-group-suffix=_root-example --user=alice --database=metrics

To log out of the database and remove credentials:

# Remove credentials for a particular database instance.
$ tsh db logout example
# Remove credentials for all database instances.
$ tsh db logout
Have a suggestion or can’t find something?
IMPROVE THE DOCS