99designs / aws-vault

A vault for securely storing and accessing AWS credentials in development environments
MIT License
8.45k stars 817 forks source link

login doesn't work using assumed role in China region cn-north-1 #258

Closed sprice-janrain closed 6 years ago

sprice-janrain commented 6 years ago

I've set up IAM users in non-China accounts that can assume roles in other non-China accounts, and aws-vault has been working great.

I've attempted to do the same thing in China, but I'm stuck troubleshooting login.

Running aws-vault exec against an account I'm accessing via an assumed role works fine:

❯ aws-vault exec cn -- aws ec2 describe-regions
{
    "Regions": [
        {
            "Endpoint": "ec2.cn-north-1.amazonaws.com.cn",
            "RegionName": "cn-north-1"
        },
        {
            "Endpoint": "ec2.cn-northwest-1.amazonaws.com.cn",
            "RegionName": "cn-northwest-1"
        }
    ]
}

Trying to run aws-vault login with the same account fails with 400 Bad Request. Debug output follows:

❯ aws-vault --debug login cn
2018/05/16 12:12:08 [keyring] Considering backends: [keychain file]
2018/05/16 12:12:08 Loading config file /Users/sprice/.aws/config
2018/05/16 12:12:08 Parsing config file /Users/sprice/.aws/config
2018/05/16 12:12:08 Skipping session token and using master credentials directly
2018/05/16 12:12:08 Looking up keyring for cn-id
2018/05/16 12:12:08 [keyring] Querying keychain for service="aws-vault", account="cn-id", keychain="aws-vault.keychain"
2018/05/16 12:12:08 [keyring] Found item "aws-vault (cn-id)"
2018/05/16 12:12:08 Using region "cn-north-1" from profile
Enter token for arn:aws-cn:iam::xxxxxxxxxxxx:mfa/xxxxxxxxxxxxxxx: xxxxxx
2018/05/16 12:12:14 Assuming role arn:aws-cn:iam::xxxxxxxxxxxxxxxx:role/xxxxxxxxxxxxxxxx with iam credentials
2018/05/16 12:12:16 Using role **********************, expires in 14m58.881983615s
2018/05/16 12:12:16 Creating login token, expires in 12h0m0s
2018/05/16 12:12:16 Response body was <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <link rel="icon" type="image/ico" href="https://images-na.ssl-images-amazon.com/images/G/01/awssignin/static/favicon.ico">
  <link rel="shortcut icon" type="image/ico" href="https://images-na.ssl-images-amazon.com/images/G/01/awssignin/static/favicon.ico">
  <meta name="description" content="Amazon Web Services (AWS) delivers a set of services that together form a reliable, scalable, and inexpensive computing platform 'in the cloud'. These pay-as-you-use cloud computing services include Amazon S3, Amazon EC2, Amazon SimpleDB, Amazon SQS, Amazon FPS, and others." />
<meta name="keywords" content="Amazon Web Services, AWS, S3, EC2, Amazon Simple Storage Service, Amazon Elastic Compute Cloud, Cloud Computing, Web Hosting, Grid Computing, Utility Computing, Amazon Mechanical Turk, Simple Queue Service, SimpleDB, Flexible Payments Service, Amazon Payments, DevPay, Alexa, Develop
er Forum, AWS User Group, Developer Tools, APIs, Web Application Development" />

  <title>Bad Request</title>

  <link rel="stylesheet" href="https://l0.awsstatic.com/css/screen_1.css" type="text/css" />
  <!--[if lt IE 7]>
    <link rel="stylesheet" href="https://l0.awsstatic.com/css/awsGlobalNav2IE6.css" type="text/css" />
    <link rel="stylesheet" href="https://l0.awsstatic.com/css/documentationIE6.css" type="text/css" />
  <![endif]-->

  <script src="https://l0.awsstatic.com/js/all_1.js" type="text/javascript"></script>

</head>

<body id="top" class="yui-skin-sam">

  <!-- layout _300_right -->
  <div id="doc4" class="yui-t6">
    <div id="hd">

<!-- header -->
<div id="mainNav" style="margin-top:30px; margin-bottom:40px;">
  <a href="/">

    <img src="https://images-na.ssl-images-amazon.com/images/G/01/awssignin/static/aws_logo_smile.png"
         id="awsHeaderLogo"
         width="84"
         height="50"
         alt="Amazon Web Services">
  </a>
</div>

<!-- /header -->

</div>
    <div id="bd"><div id="errorPage">
  <img src="https://images-na.ssl-images-amazon.com/images/G/01/webservices/console/400._V170950309_.gif" width="392" height="202" alt="400" />

  <h1>Bad Request</h1>

  <p>
    You may have typed the address incorrectly or you may have used
    an outdated link. <br />
    Please clear your cookies and try the request again.  If the problem persists, please contact <a href="http://aws.amazon.com/support" target="_blank">Support</a>.
    We apologize for the inconvenience.<br />
    <br/>
  </p>
</div>
</div>
    <div id="ft"><div style="border-top: 1px solid #ccc; margin-bottom: 12px; margin-top: 10px; padding-top: 2px;">

  <ul class="h_bar">
    <li class="first">
      <a href="http://aws.amazon.com/privacy/">Privacy Policy</a>
    </li>
    <li><a href="http://aws.amazon.com/terms/">Terms of Use</a></li>
  </ul>
  <div class="grey666">&#169;2017, Amazon Web Services <span class="caps">LLC</span> or its affiliates. All rights reserved.</div>

  <img src="https://media.amazonwebservices.com/awsmedia/logo_an_amazon_company.gif" width="160" height="21" vspace="8">
</div></div>
  </div>

</body>

</html>

aws-vault: error: Call to getSigninToken failed with 400 Bad Request
sprice-janrain commented 6 years ago

Hmm. Could it be this? https://github.com/99designs/aws-vault/blob/f62e3f49de476d9e9300cbe37ff7ea89619603d0/cli/login.go#L122

Looks like the URL is hardcoded to https://signin.aws.amazon.com/federation. That certainly won't work on China and GovCloud accounts.

lox commented 6 years ago

Yup, sounds like it needs to switch the url based on region. PR's welcomed!

sprice-janrain commented 6 years ago

Hrm. How would we figure out which region to login with? There's the option to configure a default region in ~/.aws/config for a specific profile. Should it just look something like:

if region defined in config and region == `cn-north-1` {
  federation_url := "https://signin.amazonaws.cn/federation"
} else {
  federation_url := "https://signin.aws.amazon.com/federation"
}

Please don't consider that actual Go code, just pseudocode. I need to wrap my head around Go before I can dive into this one.

Looking elsewhere in login.go, looks like I'd have to modify the console url based on region too. I see examples of using profile.Region there, so I guess it shouldn't be too hard to come up with a working example.

sprice-janrain commented 6 years ago

How about this for a PR? https://github.com/99designs/aws-vault/pull/259