Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant