Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Feature: Add an option to supply the MFA code as a command-line parameter #64

Open
mohag opened this issue Nov 22, 2024 · 0 comments
Open

Comments

@mohag
Copy link

mohag commented Nov 22, 2024

I have an alias aws_otp that uses oathtool to get an MFA code. It would be useful to be able to use that instead of manually typing the code.

Adding a command-line parameter to supply the code would help.

(I currently use a shell function to set the env vars, assume-role does seem like a nice alternative though....)

I tried this with sshpass, which did not work (I see that stdin might work though) (I use a similar sshpass for the AWS CLI to get it pre-populate its credential cache.

sshpass -v -P "MFA" -p $(aws_otp) assume-role profile_here

My session caching loop (demonstrating sshpass with the AWS CLI):

aws_sessions ()
{
    aws_clear_vars;
    for profile in $(awk '/^\[/ { a=$NF; gsub(/[\[\]]/,"",a); print a; }' ~/.aws/config);
    do
        function regions ()
        {
            AWS_PROFILE=$profile sshpass -p $(aws_otp) -P "Enter MFA code" aws ec2 describe-regions --region eu-west-1 --filters Name=opt-in-status,Values=opt-in-not-required,opted-in | jq -r '.[][].RegionName'
        };
        regions=$(regions);
        if [ "$regions" = "" ]; then
            echo waiting for new MFA code for profile=$profile;
            sleep 30;
            regions=$(regions);
        fi;
    done
}

My current MFA function: (It takes MFA code as a parameter) (since this project seems potentially abandoned)

aws_clear_vars ()
{
    unset AWS_SESSION_TOKEN AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_EXPIRY AWS_EC2_METADATA_DISABLED aws_response
}

aws_2fa ()
{
    aws_clear_vars;
    export AWS_EC2_METADATA_DISABLED=true;
    mfacode="$1";
    if [ -z "$mfacode" ]; then
        echo "Error: Please pass MFA code as parameter" 1>&2;
        return 1;
    fi;
    profile=${AWS_PROFILE:-default};
    role=$(aws configure get role_arn);
    mfa_serial=$(aws configure get mfa_serial);
    duration_seconds=$(aws configure get duration_seconds);
    if [ -n "$duration_seconds" ]; then
        extra_params=(--duration-seconds $duration_seconds);
    fi;
    if [ -n "$mfa_serial" ]; then
        if [ -n "$role" ]; then
            aws_response=$(env -u AWS_PROFILE aws sts assume-role --role-arn "$role" "${extra_params[@]}" --role-session-name aws-cli --serial-number "$mfa_serial" --token-code "$mfacode");
        else
            aws_response="$(aws sts get-session-token "${extra_params[@]}" --token-code "$mfacode" --serial-number "$mfa_serial")";
        fi;
        if [ $? -eq 0 ]; then
            export AWS_ACCESS_KEY_ID="$(echo "$aws_response" | jq .Credentials.AccessKeyId -r)";
            export AWS_SECRET_ACCESS_KEY="$(echo "$aws_response" | jq .Credentials.SecretAccessKey -r)";
            export AWS_SESSION_TOKEN="$(echo "$aws_response" | jq .Credentials.SessionToken -r)";
            export AWS_SESSION_EXPIRY="$(echo "$aws_response" | jq .Credentials.Expiration -r)";
            echo "Got a session. Valid until $AWS_SESSION_EXPIRY";
        else
            echo "Error getting session!" 1>&2;
            echo "$aws_response" 1>&2;
            return 2;
        fi;
    else
        echo "Error: Please ensure that mfa_serial is present in your ~/.aws/config for the relevant profile" 1>&2;
        return 1;
    fi
}

To use:

$ aws_2fa 233535 # Gets a MFA AWS session in the default profile
$ AWS_PROFILE=test aws_2fa 134551 # Gets a MFA AWS session using the "test" profile
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant