# Passwordless Access to AWS RDS MySQL

{% hint style="danger" %}

### <mark style="color:red;">**The BastionZero product is maintained for existing BastionZero customers only.**</mark>&#x20;

Moving forward, we are natively rebuilding BastionZero’s technology as Cloudflare’s [Access for Infrastructure](https://developers.cloudflare.com/cloudflare-one/applications/non-http/infrastructure-apps/) service.
{% endhint %}

## Introduction

In this guide, we'll show you how to set up passwordless access to your RDS MySQL databases without the need for traditional passwords.

{% hint style="info" %}
**There are nine steps to this process:**

1. Prepare Your BastionZero Account
2. Configure AWS IAM Policy and Role
3. Launch an EC2 Instance
4. Install the BastionZero Agent on EC2 Instance
5. Create & Configure an RDS Database
6. Attach RDS MySQL Instance to EC2 Instance
7. Enable SSL Between RDS MySQL and EC2 Instances
8. Create BastionZero Database Target
9. Create BastionZero Access Policy
   {% endhint %}

## Preparing Your BastionZero Account

For the purposes of this guide, we will assume you have already[ signed up for a BastionZero account](https://cloud.bastionzero.com/signup), have your[ BastionZero account integrated with your IdP](https://docs.bastionzero.com/docs/admin-guide/authentication/sso-management), and have the[ ZLI installed on your local machine](https://docs.bastionzero.com/docs/deployment/installing-the-zli). Once that is complete, we’ll do a few things in our BastionZero account to set ourselves up for success as outlined below:

* Log in to BastionZero web app at[ cloud.bastionzero.com](https://cloud.bastionzero.com)
* Create a registration key

We can grab a registration key from the BastionZero web interface at[ cloud.bastionzero.com](https://cloud.bastionzero.com). Once you sign in, select "Create" in the upper righthand corner and choose "API Key."

<figure><img src="https://lh6.googleusercontent.com/qYr6iWp60F4VBZk8jetdky-x5aMOoIqtCZzXrK2KRsBntRYZHYmEQIs326iwKhifWCeUIXSq1P9nt_7kbYtj4wqka5LtP6gzJIlznMGNDyS3In4FfLxFConOsvHTS28uk8T1EzWuM16wwexHeNvXVXI" alt=""><figcaption></figcaption></figure>

We'll use this registration key for installing the agent below. Hang on to it!

## AWS IAM Configuration

### Attach Permissions Policies

* Log in to the [AWS Console](https://console.aws.amazon.com/).
* Head to the [IAM](https://console.aws.amazon.com/iam/home) policies page. Click on "Create policy."

<figure><img src="https://2296692744-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FB1x0ofz14evTHlwIRKaW%2Fuploads%2FmU5VJkD4IIngd72hxr4f%2Fimage.png?alt=media&#x26;token=ad2ae5fc-60ff-4781-9672-013bf28b112e" alt=""><figcaption></figcaption></figure>

* In the JSON tab of the create policy screen, replace any existing content with the following JSON. You need to modify the following with information that is specific to your account:\
  \- `RDS_DATABASE_REGION`\
  \- `YOUR_AWS_ACCOUNT_ID`\
  \- `DBI_RESOURCE_ID`\
  \- `DB_USERNAME`\
  \
  Below is an example policy that outlines the structure the needed information must follow. Find more information about creating and using an IAM policy for IAM database access policies [here](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html). ***If you have multiple database roles that need access, you must include a resource statement (line 8) for each role.***<br>

  <pre class="language-json" data-line-numbers><code class="lang-json">{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "rds-db:connect",
              "Resource": [
              "arn:aws:rds-db:RDS_DATABASE_REGION:YOUR_AWS_ACCOUNT_ID:dbuser:DBI_RESOURCE_ID/DB-USERNAME"
              ]
          }
      ]
  }
  </code></pre>
* Here is an example of a policy that says, "Allow database users `read_only`, `read_write`, and `admin` to connect to my database identified by the id `db-ABCDEFGHIJKLMNOPQRSTUVWXYZ1`, which is in my AWS account `123456789012` in the `us-east-1` region."<br>

  <pre class="language-json" data-line-numbers><code class="lang-json"><strong>{
  </strong>    "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "rds-db:connect",
              "Resource": [
              // If you have multiple database users who need passwordless access, 
              // you MUST add a line for each db-username 
              // i.e., 3 users read_only, read_write, and admin may look like this:
               "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFGHIJKLMNOPQRSTUVWXYZ1/read_only",
               "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFGHIJKLMNOPQRSTUVWXYZ1/read_write",
               "arn:aws:rds-db:us-east-1:123456789012:dbuser:db-ABCDEFGHIJKLMNOPQRSTUVWXYZ1/admin"
              ]
          }
      ]
  }
  </code></pre>
* Click on "Next."
* Name the policy, for example, "RDS\_MySQL\_Impersonation\_Policy."
* Click on "Create policy."

### **Creating IAM Role**

* Access [IAM (Identity & Access Management)](https://console.aws.amazon.com/iam/home) in the AWS console.
* Click on "Roles" then "Create role."

#### Set Up the Trust Relationship

* Select "AWS service" as the type of trusted entity.
* For the service that will use this role, choose "EC2."
* Click on "Next."

<figure><img src="https://lh4.googleusercontent.com/4h7MkBR8KAqaY0UJGQVjqfmSd4iRRjSoQNL1Ve00fQAh9hn8gsrBdh10vxMPPwdiHLsTtec6xJqaCt0cCaftu9I7pP3vyDHgjNm2FQcThCmNkS27oOv4oLw4uY3jSxnmItTy4zr7vH47_A-DftiFNWs" alt=""><figcaption></figcaption></figure>

#### Attach the Newly Created Policy To the Role

* In the search box, search for the name of the policy you just created (e.g., "RDS\_MySQL\_Impersonation\_Policy").
* Check the box next to your newly created policy.
* Click "Next."

<figure><img src="https://2296692744-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FB1x0ofz14evTHlwIRKaW%2Fuploads%2F4aBdDyUI4CI9dkqc6CQU%2FScreenshot%202024-04-11%20at%2013.36.04.png?alt=media&#x26;token=f8aebc06-5641-409c-9be4-4cb84efc2476" alt=""><figcaption></figcaption></figure>

#### Review and Create the Role

* Enter a memorable role name, for instance, "RDS MySQL Impersonator."
* Review the role and click "Create role."
* Now you have successfully created an IAM Role User "RDS MySQL Impersonator" with a role that allows "RDS MySQL Impersonator" to authenticate as a database user.

## Launch an EC2 Instance

* Navigate to the [EC2 Dashboard](https://us-west-1.console.aws.amazon.com/ec2/home) by selecting "EC2" from the list of services.
* Click on the "Launch Instances" button.
* Give your instance a name.
* Choose an Amazon Machine Image (AMI).
* Choose an instance type (we’re using `t.2 micro` for this example).

### Create a New Key Pair or Choose an Existing One

* When you launch your instance, you need to select a key pair that you'll use to SSH into your instance to install the BastionZero agent. If you don't have an existing key pair, you can create a new one. Be sure to download and securely store the private key file (`.pem`).

### Configure Advanced Details

* In the "Advanced Details" section, look for the "IAM instance profile" field. It is in this drop-down list that you'll select the IAM role that you want to assign to the EC2 instance. Click on the "IAM instance profile" drop-down list and you should see the "RDS MySQL Impersonator" role that you created earlier. Select this role.

<figure><img src="https://lh6.googleusercontent.com/QDo0McoA-2F_cYCd-jDbzgPt3PbCSVVNGezAKo3oY8dsAi2pwMdcvbB0rE-2n1OhE0SzYiWtrskttaAhTtopF1m4vYN2hRAdV3zQMreWVxEzEixM_7lC6fwUC53k7ITGC19DukVFBZtXjH6-3o2nwq4" alt=""><figcaption></figcaption></figure>

* After you've selected the role, continue to configure storage, add tags, and configure the security group as per your requirements.
* Review your choices and then click "Launch."

### View Instances

* Click on "View Instances" to go back to your EC2 Dashboard. Here, you should see your instance launching.
* It may take a few minutes for your instance to launch. Once it's running, you can connect to it using the key pair that you specified when launching the instance.

## Install the BastionZero Agent on EC2

* SSH into your EC2 instance.
* Download and install the BastionZero agent according to the instructions provided by BastionZero[ here](https://docs.bastionzero.com/docs/deployment/installing-the-agent#install-using-apt). You'll need your registration key from the "Preparing Your Account" section above.
* Verify that the agent is available in the targets interface at[ cloud.bastionzero.com](https://cloud.bastionzero.com/admin/targets).
* Name the agent something memorable; we'll need it when we create a database target [below](#add-a-database-target-in-bastionzero).

## Create and Configure RDS MySQL Database

### Navigate To the RDS Dashboard

* From the services list, select "RDS" to access the RDS Dashboard.

### Create a New RDS Database

{% hint style="info" %}
If you have a pre-existing RDS MySQL database, skip through to "Configure the Database." Depending on how your database is set up, you may need to make some adjustments to allow for passwordless access.
{% endhint %}

* Click on "Create database."
* Select the "Standard Create" method and choose the MySQL engine.
* Make any adjustments to details such as the version that suits your needs.
* Enter the details under "Settings." Here, the Master username will be "admin" by default, and you will be asked to enter a password. Remember this password, as you will need it to connect to the database and add your passwordless user(s).

### Configure the Database

* Specify the Database details as needed like DB instance identifier, instance size, storage, etc.
* Under "Connectivity," make sure your database is publicly accessible if you need to access it from outside of AWS.
* Choose the VPC, Subnet Group, Publicly Accessible settings, VPC Security Group(s), and Availability Zone based on your needs.
* <mark style="color:purple;">**MOST IMPORTANTLY**</mark>: **under the "Database authentication" section, you must select "Password and IAM database authentication." For existing databases, you may need to select "Modify" and update this setting.**

### Start the Database

* After all the details have been specified, click on "Create database" at the bottom of the page.
* Your RDS MySQL instance will now be set up. This can take a few minutes.

## Attach RDS Instance To EC2 Instance

* In the database menu, click “Actions” in the top right and select “Set up EC2 connection.”<br>

  <figure><img src="https://lh5.googleusercontent.com/3IbJ3sdXDMVtPhPzVwk-Twn4WAAbR7t_77jCs1aywcqa2_896K_37V9eZYES3RwXY_qy6lm439vdI6-hIkR24Ob7QKZ62T-bLK2C04lvDDMeC3lPm_vgjundTMit5BBTuPpo8jvuzg-rZyzKP2bugKA" alt=""><figcaption></figcaption></figure>
* Select the EC2 instance from above and click “Confirm and set up.”

<figure><img src="https://lh4.googleusercontent.com/NL-lDbZmaaggxWDDktosnXUx-FSOq3arHume0jTsFa7_UWTRiY3jagXt0T9kSLj-5oS-TzMwpgy3vNCl5isoL7rt7mprlHHjXSeDfzJ85168YSPVEXvma0kKohf4LQ33GmhYar0kZFgbFbIiI1y0LI4" alt=""><figcaption></figcaption></figure>

## Configure Secure Connection to the Database

In order to enable passwordless access to your MySQL database, ensure that your [database and server can communicate via SSL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/mysql-ssl-connections.html#MySQL.Concepts.SSLSupport). To do this, you must upload an Amazon certificate bundle for your specific AWS region(s) to your associated EC2 instance. These bundles contain both the intermediate and root certificates for an AWS region. Find those bundles [here](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html).&#x20;

Use your preferred file transfer protocol to upload the `.pem` file (i.e., for `us-west-1` , the bundle is named `us-west-1-bundle.pem`) to your EC2 instance. Make sure this is in an accessible directory.

## Configure the Database User On Your MySQL Database

* After the database is available, click on the DB instance name to get the details, including the endpoint.
* Use a SQL client to connect to the database (such as the CLI tool `mysql` or a GUI like DBeaver). You'll need the endpoint, port (usually `3306` for MySQL), username (`admin`), and the password you created earlier.
* Once you're connected to your database as the `admin`, you can create a new user (or modify an existing one). This user or set of users should match the `DB_USERS` you included in your [IAM policy](#attach-permissions-policies) earlier in this guide. \
  \
  Run the following commands to [create and configure the database user](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html#UsingWithRDS.IAMDBAuth.DBAccounts.MySQL), `read_only`. If you are modifying an existing user, you'll want to user `ALTER` rather than `CREATE`.<br>

  <pre class="language-sql" data-line-numbers><code class="lang-sql">CREATE USER read_only IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
  ALTER USER 'read_only'@'%' REQUIRE SSL; 
  </code></pre>
* You can now exit out of your database.

## Create BastionZero Targets & Policies

### Add a Database Target in BastionZero

* Navigate to the "[Targets](https://cloud.bastionzero.com/admin/targets)" section of the BastionZero cloud app.
* Click the "Create" button in the top right and select "Database."
* Give your target a name (e.g., `rds-mysql`).
* Select the Proxy Target or Proxy Environment as the proxy type. This should be either the target you installed the BastionZero agent on that has access to your database, or an environment with multiple targets with the BastionZero agent installed.
* Select "Service account injection" for the Authentication Type.
* Set the Database Type to "AWS MySQL."
* In the "Remote Host" field, enter the instance connection name from AWS RDS (e.g., `mysql-example.1230xabcxlia.us-west-1.rds.amazonaws.com`). **Based on the authentication method and database type chosen, BastionZero will prepend the protocol prefix if it is not provided with the instance name; so you can safely omit the** `rds://`**.**
* In the "Remote Port" field, enter the remote database port (e.g., `3306`).
* In the “Local Host” field, enter `localhost`.
* Set the “Local Port” to your desired local port (e.g., “1501”). If you do not require this target to open on a specific port, we recommend you leave this field blank, and BastionZero will choose an available port for you at time of connection.
* Select the environment to place this database target into.&#x20;
* Click "Add" to create the database target.
* You should see this target appear on the Targets page.

<figure><img src="https://2296692744-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FB1x0ofz14evTHlwIRKaW%2Fuploads%2FpZnWx6qWEeYwvN3yd2pd%2FScreenshot%202024-03-07%20at%2016.20.39.png?alt=media&#x26;token=76e02e57-0f4f-4193-b1bc-3139fe958590" alt=""><figcaption></figcaption></figure>

### Add a Proxy Policy In BastionZero

* Navigate to the "[Policies](https://cloud.bastionzero.com/admin/policies/overview)" section of the BastionZero web app.
* Click on "Create" in the top right and select "Policy."
* In the “Policy Type” select “Proxy.”
* In the "Policy Name" field, enter a name for your policy.
* In the "Users" section, add users from your IdP who you’d like to be able to access the remote database (this can also include groups or service accounts if those need access, too).
* Under "Resource Type" - you can either opt to write a policy against the database target explicitly by using the "Targets" section or an environment. In this example, the below policy is written for targets in the AWS environment.
* In the “Allowed Target Users” section, add the database user from AWS (e.g., `alice`).
* Click "Save" to create the policy.

<figure><img src="https://2296692744-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FB1x0ofz14evTHlwIRKaW%2Fuploads%2FT16s5aIXp2zRRUKNkqBS%2FScreenshot%202024-03-07%20at%2016.22.47.png?alt=media&#x26;token=00070875-9b17-44a4-b937-776d3b11cdbc" alt=""><figcaption></figcaption></figure>

### Establish a Connection to the Database Using the ZLI

* From your terminal using the zli, run:<br>

  <pre class="language-bash" data-line-numbers><code class="lang-bash">zli connect {database_username}@{database target name}
  </code></pre>

The command line will output a `localhost` address where the connection to your database is hosted. It may look something like `localhost:1234`. The port number will either be the port number you assigned when creating the target or an available port that BastionZero assigned for you.&#x20;

## Connect to the Database

### CLI Client

For those using MySQL CLI, you can access your database passwordlessly by doing the following:

```
mysql -h 127.0.0.1 -P {port number} -u {database_username} --ssl-mode=DISABLED -p
```

When prompted for the password, press enter. BastionZero is handling the authentication to your database passwordlessly in the background.&#x20;

{% hint style="info" %}
While the command line arguments may read like SSL is not enabled for this connection, all communication between BastionZero and your database is being conducted via SSL. Using passwordless databases removes the hassle of users generating authorization tokens, etc. and instead, this is handled by BastionZero. Thus, the connection command for the user is much simpler.&#x20;
{% endhint %}

### Database GUI

In your database client, you’ll need to specify the port to connect to and your username.

<figure><img src="https://2296692744-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FB1x0ofz14evTHlwIRKaW%2Fuploads%2FAaqHkIBao7VRtToz2JWi%2FScreenshot%202024-03-07%20at%2016.24.05.png?alt=media&#x26;token=2552f9b9-29d2-49b3-a66f-7db664e6cb2b" alt=""><figcaption></figcaption></figure>

## Conclusion

Congratulations! You have successfully completed all the necessary steps to set up your passwordless access to AWS RDS MySQL. You should now be able to establish a secure connection to your database using the ZLI and your specified username. This marks the completion of your setup and configuration process.&#x20;
