avatarTeri Radichel

Summarize

A CloudFormation Template to Enforce a Secure SSH Encryption Algorithm for EC2 Key Pairs

ACM.383 Security problems and workarounds if you choose to do this

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

⚙️ Check out my series on Automating Cybersecurity Metrics | Code.

🔒 Related Stories: AWS | EC2 OS Security | AWS Security | Encryption

💻 Free Content on Jobs in Cybersecurity | ✉️ Sign up for the Email List

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the last post I wrote about a new SSH vulnerability and how to protect your systems accessed via SSH.

In this post, I’m going to create a CloudFormation template to deploy an SSH key that enforces the encryption algorithm that we want to use in a particular environment.

This again demonstrates the power of automation to aid with governance and secure deployments if you only allow deployments through your secure deployment pipeline. In addition, it will be easier to make updates like this if you use micro-templates.

But hold that thought because when I got to the end of this post, I realized there are security challenges with the implementation.

Creating an SSH Key with CloudFormation

When I first wrote this code, it was not possible to use CloudFormation for this purpose and now it is.

Head over to the AWS Resources documentation:

Click EC2 in the left menu:

Click on KeyPair:

Here’s the resource for an SSH key:

Especially of interest in this case is the KeyType since we have discovered that RSA keys are vulnerable to attacks when used for SSH. We can hard code this value to ec25519. Note the warning below which causes the keytype to be ignored.

I am not going to add a parameter to pass in PublicKeyMaterial to avoid this problem. If you have a specific need for that, be aware of that risk.

Are Windows hosts vulnerable when using RDP? The particular report only addressed SSH. I didn’t get into the details as to whether the specific version of RSA used with RDP is vulnerable. I’ll leave that to the cryptography experts, but I recommend you do not leave hosts exposed to the public Internet. I’ve explained over and over how to lock down your network on this blog. New vulnerabilities appear all the time and the network saves you in that case. Also, is the key on AWS created to encrypt the credentials only or also used with the RDP algorithm? I would think it is only the former but I’ll leave that to the Windows users to explore further.

I’m going to create the template in my new directory structure I created in prior posts that aligns with the above documentation so:

/awsdeploy/resources/ec2/keypair/keypair.yaml

Here’s my template:

Next I’m going to create a keypair_functions.sh file which is going to leverage my common code for deploying CloudFormation stacks as always. I’m not going to source the file here because that will happen in the outer deployment script in my deploy folder.

[Read my prior posts to see how I am doing all of this.]

I added the function to deploy an EC2 SSH key pair and I’m going to try to be as consistent as possible by naming it deploy_keypair.

Now I head over to my deploy scripts folder.

Who is going to deploy SSH keys?

In the past iteration I had the IAM administrator create the initial SSH key for a user, but really I want to let users rotate their own keys as needed (with appropriate policies in place as I’ll show you in future posts.) I’m going to create a new folder called user.

I create a file named deploy_keypair.sh.

I source the required files and call my function.

Recall that this codebase is designed to always call the scripts from within the folder where the deploy and resources folders exist, so the paths are always relative to that folder. The code above finds the function we just created in the sourced keypair_functions.sh file.

From that folder, I change the permissions of the file I need to execute:

chmod 700 deploy/user/deploy_keypair.sh 

Then I execute the code.

Where does the key go? I wish AWS had been reading my blog posts before implementing this. There are reasons why I ended up using AWS Secrets Manager.

The key is stored to AWS Systems Manager, unfortunately, with a generic AWS encryption Key. There’s no way to specify your own customer managed KMS key at the time of this writing. I hope that will change.

When you create a new key pair, the private key is saved to AWS Systems Manager Parameter Store, using a parameter with the following name: /ec2/keypair/{key_pair_id}.

Let’s take a look. Yes, there’s my key:

There’s not currently an option to specify a resource policy on AWS SSM Parameter Store parameters like you can in AWS Secrets Manager, nor can you leverage the rotation functionality of AWS Secrets Manager.

You will need to ensure you have appropriate IAM policies and SCPs to ensure users can only view their own SSH keys. However that is really challenging to do since the key pair was not created with the name I specified.

What if we want to create policies as I’ve been showing you with ${aws::user} to restrict users to viewing their own SSH keys? Not going to work, unfortunately.

Alternatively, I showed how I created SSH keys for users and stored them in a secret only the user can access here:

The one good thing about AWS SSM Parameter store is that the parameter is restricted to the current account, but still you need to be able to restrict users to only seeing their own SSH key.

Only one person should ever see their own SSH private key. It is a credential, like a username and password, and identifies who took what actions in the case of a security event.

You can add multiple SSH public keys to an EC2 instance:

I really want to use CloudFormation for this so I was thinking of possible workarounds.

You could possibly disallow all access to parameters starting with that prefix and then modify each individual user’s policies to allow them to access their own key based on the username that the user specified when running the script. That’s kind of messy and error prone. Every time you change a policy there’s a chance you mess something up so I don’t like that solution but it is a workaround potentially.

The other option would be to take the key from SSM, visible only to an automated process, and transfer it to Secrets Manager using my templates and policies above, and then delete the key in SSM Parameter Store. Even with that automated option, there’s a risk of the key being exposed during the transfer from one service to another and the risk of exposure during that window if the AWS key is compromised somehow.

In my prior solution I was exploring the creation of the key in a trusted enclave and handling the appropriate deletion of the key upon exit and based on this solution as is, I wonder how all that is handled and who could possibly access the key at any point. Recall that a type of key was recently exposed at Microsoft due to a race condition and someone troubleshooting the error. Hopefully AWS has addressed all of that appropriately and those who have greater security needs than me will want to ask those questions.

I think I would use that over changing policies and it seems like an unnecessary work around if AWS adds the following:

  • The option to use Secrets Manager instead of parameter store.
  • The option to specify the Secret name so you can leverage a secret that uses your own customer managed key and policy of your choosing, among other things.
  • Explains how they protect the key as it is created and stored, hopefully with an enclave.

Anyway, I gave you some options. The other would be to use the solution I showed you before and figure out how to best protect that key upon creation yourself when submitting it to Secrets Manager — or let users create their own keys with certain restrictions. I’m going to attempt to solve this problem in another way in the next post.

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2023

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
⭐️ Author: Cybersecurity Books
⭐️ Presentations: Presentations by Teri Radichel
⭐️ Recognition: SANS Award, AWS Security Hero, IANS Faculty
⭐️ Certifications: SANS ~ GSE 240
⭐️ Education: BA Business, Master of Software Engineering, Master of Infosec
⭐️ Company: Penetration Tests, Assessments, Phone Consulting ~ 2nd Sight Lab
Need Help With Cybersecurity, Cloud, or Application Security?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
🔒 Request a penetration test or security assessment
🔒 Schedule a consulting call
🔒 Cybersecurity Speaker for Presentation
Follow for more stories like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
❤️ Sign Up my Medium Email List
❤️ Twitter: @teriradichel
❤️ LinkedIn: https://www.linkedin.com/in/teriradichel
❤️ Mastodon: @teriradichel@infosec.exchange
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
AWS
Ssh
Rsa
Ecc
Encryption
Recommended from ReadMedium