Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for How to use AWS Roles Anywhere
Polar Squad profile imageJanne Pohjolainen
Janne Pohjolainen forPolar Squad

Posted on

     

How to use AWS Roles Anywhere

What is AWS Roles Anywhere?

AWS Roles Anywhere enables you to use AWS Policies and AWS Roles for workloads such as servers, containers and applications that are running outside AWS without having to create long-term credentials.

AWS Roles Anywhere uses SSL certificates to manage workload access through IAM Roles and handing over short-living session keys.

How does AWS Roles Anywhere work?

A workload needs to have an SSL certificate (and a private key) that is signed by a Certificate Authority configured in AWS Roles Anywhere as a Trust Anchor. It is possible to configure external CAs or to use an AWS Private CA.

AWS Roles Anywhere Profiles map which IAM Roles are possible to be assumed by the workload. The workload is then given a short-living session keys which grants access to AWS services according to the role policies.

This is more secure than if user credentials or other long-term credentials are used, as they usually have much more access than a single role. It's also possible to set boundaries for the roles added to the Profile which override the role's policies.

What use-cases does AWS Roles Anywhere have?

These roles can be used in any kind of workload running outside AWS that needs access to the resources in the cloud. For example,

  • On-premises databases servers could connect to S3 to fetch data.

  • If you use Kubernetes in a private cloud, you can create a role that gives the application container running in the cluster permissions to specific AWS resources only.

  • If you already have an existing CA and PKI (Public-Key Infrastructure) system, another use case is to use AWS Roles Anywhere to use the existing certificates to grant access to AWS services.

Let's dive in deeper...

Some infrastructure is needed first

First, a Certificate Authority (CA) is needed. For this example, we will create an AWS Private CA and then create an AWS Roles Anywhere trust anchor for it.
After that, we will create an IAM Role with S3 read-only access and a Roles Anywhere Profile that links the IAM role to the trust anchor and CA.

We will not dive deep into these and concentrate more on the workload side. Terraform code used to create CA, trust anchor, profile, role and an S3 bucket for this example can be found inhttps://github.com/jpohjolainen/aws_roles_anywhere

Once run, Terraform will output the ARNs of the newly created CA, trust anchor, role and profile, and also a S3 bucket name.

These will be needed later on for creating a certificate for signing in to AWS and when revoking a certificate.

Speaking of certificates, let's create a new certificate request and get a certificate from the CA.

Note: Only the first private CA will be free for 30 days. If you create one and then delete it and create another, you will need to pay for the CA immediately. A private CA costs 300€ ($400) a month.

Note 2: It is also possible to create your own CA with an OpenSSL command and configure it using external CA. Here is how to do that:https://aws.amazon.com/blogs/security/iam-roles-anywhere-with-an-external-certificate-authority/

Creating a certificate and private key for our application

Create Certificate Signing Request (CSR) and a new Private Key.

Create CSRapp-cert.csr and private keyapp-private-key. Change the Subject to your liking. C=Country, ST=State, OU=Organization Unit, O=Organization and CN=Common Name (name of app, or hostname/domain)

openssl req-new-newkey rsa:2048\-out"app-cert.csr"\-keyout"app-private.key"\-subj"/C=DE/ST=Berlin/OU=DevOps/CN=app1"
Enter fullscreen modeExit fullscreen mode

The previous command prompted for password for the private key, but we need to remove it as this is for an application

openssl rsa-in"app-private.key"-out"app-private-nopass.key"
Enter fullscreen modeExit fullscreen mode

Request a certificate from the CA based on the CSR.

aws acm-pca issue-certificate\--certificate-authority"arn:aws:acm-pca:eu-west-1:xxxxxx:certificate-authority/zzzzzzzzz"\--csr"fileb://app-cert.csr"\--signing-algorithm"SHA256WITHRSA"\--validityValue=365,Type="DAYS"
Enter fullscreen modeExit fullscreen mode

The --csr option really hasfileb:// instead offile://. It is used to read files in binary format in the AWS CLI.

Note: The following signing algorithms are available: SHA256WITHECDSA, SHA384WITHECDSA, SHA512WITHECDSA, SHA256WITHRSA, SHA384WITHRSA and SHA512WITHRSA.
The specified signing algorithm family (RSA or ECDSA) must match the algorithm family of the CA's secret key.

The validity type can be YEARS, MONTHS, DAYS and the number as the value, END_DATE with value of YYYYMMDDHHMMSS or ABSOLUTE with a unix timestamp as the value.

Get the CertificateARN from the reply. It is used in next section.

Download the issued certificate.

Use the AWS CLI to download the certificate from the private CA

aws acm-pca get-certificate\--certificate-arn"arn:aws:acm-pca:eu-west-1:xxxxxx:certificate-authority/zzzzzzzzz/certificate/af7d3bf5c562a7d91f9310da8ae6ea8d"\--certificate-authority-arn"arn:aws:acm-pca:eu-west-1:xxxxxx:certificate-authority/zzzzzzzzz"\--output json\ |jq-r'.Certificate, .CertificateChain'> app-cert.pem
Enter fullscreen modeExit fullscreen mode

Note: This usesjq to get the certificate in JSON format. It's possible to use--output text and direct that to a file, but then you need to edit the file to move the second-----BEGIN CERTIFICATE----- to its own line.

Show the certificate

openssl x509-in app-cert.pem-noout-text
Enter fullscreen modeExit fullscreen mode

Creating a container with an application

Once we have the certificate and the private key created, we need to have a configuration for AWS.
$HOME/.aws/config is used by AWS SDK and CLI for getting access to AWS by signing in with the certificate and assume the role.

AWS provides a tool to help with the sign-in called AWS Signing Helper. In this example, it is downloaded inside the Dockerfile when building the image.
https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html

.aws/config

The helper tool can then be used in the file$HOME/.aws/config to login to the AWS when SDK or CLI is used. Here we need the ARNs that the Terraform code above returns. Save this to a file calledaws-config. The Dockerfile expects this name:

[default]credential_process=/usr/local/bin/aws_signing_helper credential-process --certificate /app/app-cert.pem --private-key /app/app-private-nopass.key --trust-anchor-arn arn:aws:rolesanywhere:eu-west-1:xxxxxx:trust-anchor/yyyyyyyy --profile-arn arn:aws:rolesanywhere:eu-west-1:xxxxxx:profile/ccccccc --role-arn arn:aws:iam::xxxxxx:role/RolesAnywhere
Enter fullscreen modeExit fullscreen mode

Note: Change the--trust-anchor-arn,--profile-arn and--role-arn to values gotten from Terraform code.

Small application

Here is a small Python code to print S3 buckets. Save this to a filegets3buckets.py

importboto3importtimedefhello_s3():s3_resource=boto3.resource("s3")print("Hello, Amazon S3! Let's list your buckets:")forbucketins3_resource.buckets.all():print(f"\t{bucket.name}")if__name__=="__main__":whileTrue:hello_s3()time.sleep(5)
Enter fullscreen modeExit fullscreen mode

Copy the certificate, private key, aws-config and the above python code into a directory.

Dockerfile

Create aDockerfile in the same directory as the certificates and the other files previously created:

FROM debian:stable-slimARG homedir=/appRUNDEBIAN_FRONTEND=noninteractive apt-get update\&& apt-get upgrade\&& apt-getinstall--no-install-recommends-y\        awscli\        curl\        python3-boto3\&&rm-rf /var/lib/apt/lists/*# Download AWS Signing HelperRUNcd /usr/local/bin\&& curl-LO https://rolesanywhere.amazonaws.com/releases/1.1.1/X86_64/Linux/aws_signing_helper\&&chmod0755 aws_signing_helper# Create user to run the appRUNadduser--system--home"$homedir"--no-create-home--shell /bin/false userappRUNmkdir"$homedir"&&chownuserapp"$homedir"# After this everything is run under the userUSER userappCOPY --chown=userapp --chmod=0600 ./app-cert.pem "$homedir"# This should never be copied inside the image. It should be mounted from outsideCOPY --chown=userapp --chmod=0600 ./app-private-nopass.key "$homedir"RUNmkdir"$homedir"/.aws\&&chmod0700"$homedir"/.aws# Copy the aws-configCOPY --chown=userapp --chmod=0644 ./aws-config "$homedir"/.aws/configCOPY --chown=userapp --chmod=0755 gets3buckets.py "$homedir"WORKDIR "$homedir"CMD python3 /app/gets3buckets.py
Enter fullscreen modeExit fullscreen mode

Note: The private key should never be baked into the container except when testing locally. The private key should be in a secret store like AWS Secrets Manager and then mounted from there when using inside Kubernetes.

Build the container

docker build-t s3rolesanywhere:test.
Enter fullscreen modeExit fullscreen mode

When running the container, it will use the certificate and the private key with the aws_signing_helper tool to request AWS secrets and session keys, and assume the role. It will then print the buckets from S3 every 5 seconds.

docker run-ti--rm s3rolesanywhere:test
Enter fullscreen modeExit fullscreen mode

The output should be something like this:

Hello, Amazon S3! Let's list your buckets:    private-ca-crl-xxxxxxxx    ...
Enter fullscreen modeExit fullscreen mode

Revoking certificate

Get certificate serial number

To revoke a certificate, you need to have its Serial number. You can get it from the certificate withopenssl command

openssl x509-in app-cert.pem-noout-serial
Enter fullscreen modeExit fullscreen mode

Revoke certificate in AWS Private CA

Then, you can revoke the certficate in AWS Private CA with the following command

aws acm-pca revoke-certificate\--certificate-authority-arn <ARN of CA>\--certificate-serial <Serial of the cert to revoke>\--revocation-reason"<Reason for revoking>"
Enter fullscreen modeExit fullscreen mode

Note: Only these are valid values for--revocation-reason: AFFILIATION_CHANGED, CESSATION_OF_OPERATION, A_A_COMPROMISE, PRIVILEGE_WITHDRAWN, SUPERSEDED, UNSPECIFIED, KEY_COMPROMISE, CERTIFICATE_AUTHORITY_COMPROMISE

It may take some time for the CRL file to appear.

Download AWS Private CA CRL file

You can then download the CRL from the S3 bucket configured for CRL in the AWS Private CA.

List CRL files in the Private CA S3 Bucket (private_ca_s3_bucket is the output from Terraform)

aws s3lss3://<private_ca_s3_bucket>/crl
Enter fullscreen modeExit fullscreen mode

Get the CRL file from the S3 bucket

aws s3cps3://<private_ca_s3_bucket>/crl/xxxxxxxxx.crl.
Enter fullscreen modeExit fullscreen mode

This file is in DER format, and it needs to be in PEM format for AWS Roles Anywhere to accept.

openssl crl-inform DER-in xxxxxxxx.crl-outform PEM-out privateca.crl
Enter fullscreen modeExit fullscreen mode

Import CRL to AWS Roles Anywhere

A CRL file in PEM format needs to be then uploaded/imported to the AWS Roles Anywhere for it to revoke the access to the certificate

aws rolesanywhere import-crl\--crl-data privateca.crl\--name <give some name>\--trust-anchor-arn <ARN of the Turst Anchor>--enabled
Enter fullscreen modeExit fullscreen mode

Note: You can only import 2 CRLs. Even with same names it doesn't overwrite them, so you need to manually remove them. Checkaws rolesanywhere list-crls andaws rolesanywhere delete-crl AWS CLI commands.

After some time, the access with that certificate should not work anymore. The error will be something like

botocore.exceptions.CredentialRetrievalError: Error when retrieving credentials from custom-process: 2024/02/16 11:11:34 AccessDeniedException: Certificate revoked
Enter fullscreen modeExit fullscreen mode

Conclusion

It is a pretty neat way of giving AWS access to applications and servers outside of AWS. It is more secure than creating normal, long-term user credentials and using them for applications. Compared to normal user credentials, if the session is hijacked in transit, then it is only valid for a short while instead of potentially being live for even months or years. And if the private key is compromised, then it can only access the services configured with policies to the role.

But revoking certificates is not all that straightforward. The CA keeps up a list called Certificate Revocation List (CRL). This needs to be imported to AWS Roles Anywhere seperately. AWS Roles Anywhere doesn’t have any automated update system of the CRL, even with AWS Private CA that can push the CRL to S3. It can only be imported through AWS CLI or API, but for example Terraform does not yet have that capability.

I feel that unless a company is already heavily invested in certificates and PKI systems, the AWS Roles Anywhere brings complications not needed on top of all other user management, especially as Terraform doesn't support import-crl now, and playing with AWS Private CA or OpenSSL requires more manual work than I think is necessary.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp