aws / ec2-macos-init

EC2 macOS Init is the launch daemon used to initialize Mac instances within EC2.
https://aws.amazon.com/ec2/instance-types/mac/
Apache License 2.0
148 stars 19 forks source link

set ec2-user password to a known password #14

Closed mieliespoor closed 2 years ago

mieliespoor commented 2 years ago

This module has a function to set the password for the ec2-user to a random password. To help with instance automation, would it be possible to allow users to set the password for the ec2-user to a predefined value?

This will then enable interaction with the keychain etc during the process of building AMI's for use within our organisation.

mattcataws commented 2 years ago

Hey @mieliespoor, the short answer to your question is that ec2-macos-init does not support setting pre-defined user passwords.

That being said, you would be able to have ec2-macos-init run a shell command to change the password. This can be done either in userdata or by creating a new module in the config.

The command that ec2-macos-init uses to set the random password is the following:

dscl . -passwd /Users/ec2-user <random password>

However, I’m not comfortable with this type of solution as it would mean storing the password in plain-text. Please refer to the first warning in the EC2 metadata and userdata docs with regards to storing sensitive data.

Although you can only access instance metadata and user data from within the instance itself, the data is not protected by authentication or cryptographic methods. Anyone who has direct access to the instance, and potentially any software running on the instance, can view its metadata. Therefore, you should not store sensitive data, such as passwords or long-lived encryption keys, as user data.

FrankAllotta commented 2 years ago

What if you could script this to retrieve a pre-defined encrypted password from Secrets Manager? This assuming you have access to the key and Secrets Manager of course. Could you assign that value to a variable and use that to set the password? It wouldn't be plan text then right?

sebsto commented 2 years ago

The command to do so would be

/opt/homebrew/bin/aws --region <name_of_your_region> secretsmanager get-secret-value --secret-id <name_of_your_secret> --query SecretString --output text

The EC2 instance must have permission to make this call. This is done by attaching a role to the EC2 instance. The minimum set of permission to authorize the above is

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SecretsManagerAccess",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": [
                "arn:aws:secretsmanager:YOUR_REGION:YOUR_ACCOUNT_ID:secret:name_of_your_secret"
            ]
        }
    ]
}
FrankAllotta commented 2 years ago

Given the two commands above. This could set the password.

#!/bin/bash
PASSWORD=$(aws --region us-east-1 secretsmanager get-secret-value \
    --secret-id test/ec2-user/password | jq --raw-output .SecureString \
    | jq -r ."password")

dscl . -passwd /Users/ec2-user $PASSWORD
mieliespoor commented 2 years ago

Hi guys, Yes thanks. I forgot to update this thread, but I opted to do that because the risks with having a password known because of an instance build is too big - as Matt also alluded. Matt's response then helped us consider secrets manager, so we will be using the aws cli to pull a password from secrets manager and set that during the instance provisioning. We will then also make use of the rotation capabilities of secrets manager to rotate the password regularly.

What I should however add is that we are also making changes to our cicd pipelines to not rely on the default login keychain anymore but rather create a keychain specifically for the cicd pipeline. This will greatly reduce the need to know the user password during instance provisioning.