Tag Archives: RDS and IAM authentication

How to connect RDS with AWS IAM authentication

A quick post listing step by step procedure to connect RDS database configured with IAM authentication.

RDS with IAM authentication

We are considering RDS running MySQL and configured with AWS IAM authentication option throughout this post. However, if you are using a different database engine, consider editing commands/arguments whenever necessary.

Basically, we will be creating a local database user that leverages AWS IAM for authentication. Then EC2 will be configured with an IAM role or aws configure that has appropriate policies defined. And lastly, the user will generate an authentication token and log into the RDS database.

Why should we use IAM authentications for RDS?

Here is a list of reasons that are helpful to understand the benefits of the IAM authentications option for RDS.

  1. IAM tokens used to log into the RDS database are valid for 15 minutes only. So they are more secure than permanent username/password pairs, and administrators don’t need to enforce/manage password reset policies.
  2. IAM tokens are generated by making API calls to the AWS IAM service whenever needed. As a result, storing tokens is useless, and even if someone does, that does not pose a security threat due to its short life.
  3. Applications can use EC2 instance profiles for generating tokens, so there is no need to store authentication information anywhere for applications to consume.

What you need?

You should be equipped with below inventory before hand –

  1. RDS instance up and running configured with IAM DB authentication.
  2. EC2 instance configured with AWS CLI (make sure SG allows the connectivity between EC2 and RDS on database port)
  3. Master user login to RDS datatase
  4. Access to AWS IAM service.

Creating user on database for the RDS access

For this step, you need to log in to the RDS database with the master user and create a new user. If you are on windows, you can use a lightweight tool like Sqlectron, or if you are already on EC2, you can use CLI as well –

Create DB user

For SQL CLI :

[root@kerneltalks ~]# mysql -h kerneltalks-rds.cn8uwrapea4b.us-east-1.rds.amazonaws.com -P 3306 -u admin -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.0.20 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> CREATE USER 'kt_iam_user' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS' REQUIRE SSL;
Query OK, 0 rows affected (0.01 sec)

Make necessary changes to username and RDS endpoint!

Create IAM role for RDS access

  • Navigate to AWS IAM
  • Create the IAM policy (sample policy below)
  • If you intend to use the EC2 instance profile, create an IAM role for AWS service EC2 and attach the IAM policy to it.
  • If you intend to use only IAM users, then make sure you configure your CLI with aws configure command by supplying access key ID and secret access key.
  • Make necessary changes to the resource section!
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:us-east-1:986532147:dbuser:db-kerneltalks-rds/kt_iam_user"
         ]
      }
   ]
}

Download the SSL root certificate available for all regions from S3 bucket. This certificate required while making RDS connection since we enforced SSL on the database user. This ensures data is encrypted in flight.

[root@kerneltalks ~]#  wget https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem
--2021-07-03 14:44:12--  https://s3.amazonaws.com/rds-downloads/rds-ca-2019-root.pem
Resolving s3.amazonaws.com (s3.amazonaws.com)... 52.216.205.189
Connecting to s3.amazonaws.com (s3.amazonaws.com)|52.216.205.189|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1456 (1.4K) [binary/octet-stream]
Saving to: ‘rds-ca-2019-root.pem’

100%[===================================================================================================================================>] 1,456       --.-K/s   in 0s      

2021-07-03 14:44:12 (81.2 MB/s) - ‘rds-ca-2019-root.pem’ saved [1456/1456]

Now your EC2 or IAM user is ready to access RDS.

Connect to RDS using IAM token

It’s time for you to generate an IAM token and connect to RDS. We will save the token in the Shell variable for easy management and pass that shell variable token into RDS connect command. If the downloaded certificate is not in the PWD then use the absolute path for the pem file.

[root@kerneltalks ~]# token=`aws rds generate-db-auth-token --hostname kerneltalks-rds.cn8uwrapea4b.us-east-1.rds.amazonaws.com  --port 3306 --region us-east-1 --usernam
e kt_iam_user`
[root@kerneltalks ~]# mysql -h kerneltalks-rds.cn8uwrapea4b.us-east-1.rds.amazonaws.com -P 3306 --ssl-ca=rds-ca-2019-root.pem -u kt_iam_user --password=$token --protocol
=tcp
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 59
Server version: 8.0.20 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 

And you are connected!

Here we have used IAM token as password to connect to RDS database! Make a note that, these generated tokens are good only for 15 minutes. If you are using connect command after 15 minutes you need to generate the token again.

Just for anote, token looks like this –

[root@kerneltalks ~]# echo $token
kerneltalks-rds.cn8uwrapea4b.us-east-1.rds.amazonaws.com:3306/
NXZG4BNZMCVY%2F20210703%2Fus-east-1%2Frds-db%2Faws4_request&X-Amz-SignedHeaders=host&X-Amz-Date=20210703T153110Z&X-Amz-Signature=04605698c01f3de6b2d7a7a48ddf28008d290795e11e
e4ac89587cbb3cdd9661

Understanding the authentication flow

For your understanding, lets see how authentication flows under the hood –

  1. User runs the token generation command with database name, port, region and username for which token to be generated.
  2. RDS sends back API token with 15 min lifespan. It requires your EC2 Instance role/IAM user to have rds connect permission. We covered this by defining IAM policy.
  3. The user attempt to connect to RDS using the token acquired in the previous step.
  4. A secure connection establishes, and the user logs in only if
    • The root certificate is valid
    • IAM permissions are in place and valid for db:connect
    • Supplied username has RDS authentication set in the database
    • The supplied token is generated for the same username, and currently, it’s not expired.
  5. A user granted access and logs in. SQL prompt will be presented.