如何找出AWS会话何时过期?

14

先决条件

我有一个可以使用AWS的脚本,但不明确处理凭据。 它只调用AWS API,并期望根据默认凭证提供程序链存在凭据。实际上,调用此脚本的包装器会获取临时凭据并将它们传递到环境变量中(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN)。

问题

包装器通常重用现有的凭据,并仅在凭据即将过期时显式要求重新认证。因此,有可能它会传递剩余时间仅为几分钟的凭据,这可能是不够的,因为脚本执行通常需要很长时间。不幸的是,我无法控制包装器,因此我想让脚本在做出决定前检查剩余时间,以确定是否启动或提前中止以防止失败。

AWS似乎没有提供标准方法来查询“当前会话过期前还有多少时间?” 如果我能控制包装器,我会让它也将到期日期传递到环境变量中。我曾希望AWS_SESSION_TOKEN是一种JWT令牌,但不幸的是它不是,并且似乎不包含其中的任何时间戳。

有人可以建议解决给定问题的其他方法吗?


您是在 EC2 实例上使用它吗? - Marko E
不,它在AWS架构之外。 - Vlad Nikiforov
有一种简单的方法可以从EC2实例获取数据,但在您的情况下不起作用。我在寻找您提到的问题时发现了这个文档https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html。那可能有帮助吗? - Marko E
有人成功解决了其中的任何一个答案吗?对我来说,这些都不起作用。我正在进行一项过度优化以改善我的日常工作流程,如果会话有效,则无需登录,并且需要过期时间。 - Raaka
3个回答

3

一行代码/ Bash 函数适用于 BSD date(在 macOS 中测试)。

需要 jq

aws-expiry () {
  aws configure get x_security_token_expires --profile ${AWS_PROFILE} | xargs -I {} sh -c 'TZ="UTC" date -j -f "%Y-%m-%dT%H:%M:%S" "+%s" $1 2>/dev/null' -- {} | xargs date -j -f "%s"
}

获取 AWS SSO 会话缓存文件 的到期时间。

假设 AWS CLI 未配置 cli_timestamp_format

aws-sso-expiry () {
  aws configure get sso_start_url --profile ${AWS_PROFILE} | xargs -I {} grep -h {} ~/.aws/sso/cache/*.json | jq .expiresAt | xargs -I {} sh -c 'TZ="UTC" date -j -f "%Y-%m-%dT%H:%M:%S" "+%s" $1 2>/dev/null' -- {} | xargs date -j -f "%s"
}

我不知道第一个答案是从哪里得到“AWS_SESSION_EXPIRATION”的。但是我正在使用AWS SSO,第二行绝对可以解决问题!谢谢@Efren - David Velarde
1
我只收到这些命令的空白回复。 - undefined
@Drew 哪个命令具体是指什么?上面的函数只是定义了一个bash函数,要运行它们需要调用它们。这些是你可以在bashrc中设置为辅助功能的示例。 - undefined
aws configure get sso_start_url --profile ${AWS_PROFILE} 是空白的。我使用 SSO 登录,所以我期望这个命令会有输出。 - undefined
1
只有在您定义了与您所提到的SSO登录的配置文件名称匹配的AWS_PROFILE变量时,它才能正常工作,例如: [profile myssoprof]然后,在运行命令之前执行export AWS_PROFILE="myssoprof" - undefined

1
重要更新:现在$AWS_CREDENTIAL_EXPIRATION取代了$AWS_SESSION_EXPIRATION。
待办事项:根据上述重要更新修改下面的答案!
你可能需要检查$AWS_SESSION_EXPIRATION的值。
echo $AWS_SESSION_EXPIRATION

应该使用协调世界时(Zulu时间)来提供到期日期,如下所示。
2022-05-17T20:20:40Z

然后需要将您系统上的日期与其进行比较。

下面的说明适用于 macOS,在 Linux 上,您可能需要修改 date 函数的参数

让我们检查当前的系统时间以 Zulu 时间为准:

date -u +'%Y-%m-%dT%H:%M:%SZ'

这应该给出类似的示例:

2022-05-17T20:21:14Z

要自动化事情,您可以创建一个bash函数添加到您的~/.bashrc或喜欢的终端主题中。
aws_session_time_left() {
  zulu_time_now=$1

  aws_session_expiration_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $AWS_SESSION_EXPIRATION '+%s'`"
  zulu_time_now_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $zulu_time_now '+%s'`"

  if [[ $zulu_time_now < $AWS_SESSION_EXPIRATION ]]; then
    secs="`expr $aws_session_expiration_epoch - $zulu_time_now_epoch`"
    echo "+`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  else
    secs="`expr $zulu_time_now_epoch - $aws_session_expiration_epoch`"
    echo "-`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  fi
}

要查看您的函数结果,您可以运行以下命令:
aws_session_time_left "`date -u +'%Y-%m-%dT%H:%M:%SZ'`"

当您的会话仍然活跃时,可能会给您带来以下类似的内容:
+0h:56m:35s

或者(当会话已过期时)可以告诉您它过期后的时间长度:

-28h:13m:42s

注意时间可以超过24小时

奖励:简化的独立脚本版本,无需参数如下所示

例如,您还可以将其作为独立文件命名为get-aws-session-time-left.sh

#!/bin/bash

# Use to find out IF "aws session expiration" exist AND compare the current system time to IT
# These are the expected result types we want to have:
# - "no aws session found" (NOTE: this does not mean there is no aws session open in another terminal)
# - how long until the session expires (for example +0h:59m:45s)
# - how long since the session expired (for example -49h:41m:12s)
# NOTE: the hours do not reset at every 24 hours, we do not require to display the days
# IMPORTANT: the date function arguments work on macOS, for other OS types may need adapting

if [[ $AWS_SESSION_EXPIRATION != '' ]]; then
  zulu_time_now="`date -u +'%Y-%m-%dT%H:%M:%SZ'`" # TODO: see important note above

  aws_session_expiration_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $AWS_SESSION_EXPIRATION '+%s'`" # TODO: see important note above
  zulu_time_now_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $zulu_time_now '+%s'`"                   # TODO: see important note above

  if [[ $zulu_time_now < $AWS_SESSION_EXPIRATION ]]; then
    secs="`expr $aws_session_expiration_epoch - $zulu_time_now_epoch`"
    echo "+`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  else
    secs="`expr $zulu_time_now_epoch - $aws_session_expiration_epoch`"
    echo "-`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  fi
else
  echo "no aws session found"
fi

然后要查询AWS会话过期时间,你只需要运行以下命令:
bash get-aws-session-time-left.sh

---编辑---

重要提示: 关于AWS_SESSION_EXPIRATION的一些信息可以在这里找到。

注意:似乎aws sso login不会设置此环境变量,如果有人能够澄清只有在使用aws-vault时才会出现AWS_SESSION_EXPIRATION,那将很好奇。


12
整个答案似乎取决于 AWS_SESSION_EXPIRATION 变量,但这个变量是从哪里来的呢? - puravidaso
4
aws sso login 似乎没有设置这个环境变量。 - shadowtalker

0

您可以使用aws configure get命令获取到过期时间:

AWS_SESSION_EXPIRATION=$(aws configure get ${AWS_PROFILE}.x_security_token_expires)

(显然,将MYPROFILE替换为您的个人资料名称。)


3
即使我立即运行了 aws sso login${AWS_PROFILE}.x_security_token_expires 对我来说仍然是空的。 - shadowtalker
如果您使用source_profile,则命令会稍有变化:aws configure get "$(aws configure get ${AWS_PROFILE}.source_profile)".x_security_token_expires - khanh nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接