首页 > 解决方案 > 从 bash 脚本读取 ssh 后的退出状态

问题描述

我正在开发一个简单的脚本/cli,它允许用户 ssh 到 docker 容器。它与处理一些安全性的 API 结合使用 - 但我想确保我也遵循一些好的做法。

我将附上下面的代码 - 但这是它的工作原理。

首先,用户请求 ssh 访问。我只是调用这个平台的 API,它会发回一个主机和一个秘密(密码)。这些会在 30 分钟后自动过期。我用地址调用 ssh 并显示用户的临时密码。

我的脚本按预期工作了一半。如果用户输入密码,连接,然后退出,我调用最后一个函数 - expire_ssh_tokens。这成功地使令牌/密码过期。

尽管如果用户在提交密码之前取消了 ssh 提示,expire_ssh_tokens则永远不会调用该函数。

expire_ssh_tokens如果用户随时退出,我希望能够打电话。感谢您的指导和帮助!

这是我当前的代码。具体来说,看看身体的 elif 部分。

ssh_into(){
  echo Accessing this container...
  if [ -n "$project_to_ssh_into" ]; then
    echo Going into specific project
    list_instances
  elif [ -z "$project_to_ssh_into" ]; then
    instance_id=$(list_instances | jq '.data' | jq '.[0]' | jq -r '.id')
    ssh_credentials=$(fetch_ssh_credentials "$container_id" "$instance_id" | jq '.data')
    ssh_address_port=$(echo "$ssh_credentials" | jq -r '.address')
    ssh_address="${ssh_address_port%:22}"
    ssh_secret=$(echo "$ssh_credentials" | jq -r '.secret')
    echo Temporary Password: "$ssh_secret"
    ssh "$ssh_address"
    expire_ssh_tokens
  fi
} 

这个功能expire_ssh_tokens没什么特别的,一个简单的卷曲。

expire_ssh_tokens() {
  echo Token count expired:
  curl https://api.cycle.io/v1/containers/"$container_id"/instances/"$instance_id"/ssh \
    -H 'Authorization: Bearer '"$cycle_api_key" \
    -H 'X-Hub-Id: '"$cycle_hub_id" \
    -X DELETE \
    --silent
  echo
  echo Alert: ssh token expired.
}

标签: bash

解决方案


我找到了另一种方法。

通常,使用 sshpass 不是一个好主意,因为密码将存在于命令行中(来自我读过的其他文章)。话虽如此,我相信由于我对expire_ssh_tokens.

ssh_action() {
    sshpass -p "$ssh_secret" ssh "$ssh_address"
    expire_ssh_tokens
}

由于直到调用 pass 之前才获取凭据ssh,并且它们在 ssh 会话之后直接过期,这似乎是我的项目的一个很好的解决方案。

除了在任何退出情况下有效地使 ssh 令牌过期外,sshpass还会自动登录用户。我不再需要向用户回显密码,调用标准ssh函数,并复制和粘贴密码以进行访问。

这是我的最终代码!

ssh_into() {
  #Check to make sure container id exists
  if [ -z "$container_id" ]; then
    echo No container id found. Please provide a container id or make sure the init file exists.
    echo
    echo Usage: bicycle ssh [container_id]
    printf "${fmt_help}" \
      "From Project Directory:" "bicycle ssh" \
      "With Custom Container Id:" "bicycle ssh [container_id]"
    exit 
  fi

  #Get all instances and number of instances
  instances=$(list_instances "$container_id" | jq '.data' )
  instance_length=$(echo "$instances" | jq length )
  
  #Prompt user to choose the instance to ssh into.
  echo Instances available: "$instance_length"
  echo Choose which instance to ssh into. 
  read instance_choice

  #Subtract 1 from their choice to match the array index.
  choice=$(( $instance_choice - 1 ))
  if [ "$instance_choice" -lt "$instance_length" ]; then
    instance_id=$(echo "$instances" | jq '.['"$choice"']' | jq -r '.id')
  fi

  #Fetch the ssh credentials using the id of the choice.
  ssh_credentials=$(fetch_ssh_credentials "$container_id" "$instance_id" | jq '.data')
  ssh_address_port=$(echo "$ssh_credentials" | jq -r '.address')
  ssh_address="${ssh_address_port%:22}"
  ssh_secret=$(echo "$ssh_credentials" | jq -r '.secret')

  #Init ssh session
  sshpass -p "$ssh_secret" ssh "$ssh_address"

  #Expire tokens upon exit
  expire_ssh_tokens

} 

推荐阅读