【问题标题】:Configuring Elastic Beanstalk for SSH access to private git repo using Amazon Linux 2 hooks使用 Amazon Linux 2 挂钩配置 Elastic Beanstalk 以通过 SSH 访问私有 git 存储库
【发布时间】:2021-11-30 05:14:58
【问题描述】:

假设我们在私有存储库中有一个名为shared_package 的自定义 Python 包,托管在 github 或 bitbucket 上。我们的私有存储库配置为通过 SSH 进行只读访问,如所述,例如here for githubhere for bitbucket

我们的另一个项目,恰当地命名为dependent_project,依赖于这个shared_package,并且需要部署到AWS Elastic Beanstalk (EB)。我们的环境使用最新的“Python on Amazon Linux 2”平台,我们使用pipenv 作为包管理器。

由于各种原因,我们直接从我们的在线 git 存储库安装shared_package 是最方便的,如here for pipenvhere for pip 所述。 我们的dependent_projectPipfile 如下所示:

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
shared_package = {git = "ssh://bitbucket.org/our_username/shared_package.git", editable = true, ref = "2021.0"}

[dev-packages]
awsebcli = "*"

[requires]
python_version = "3.8"

这在我们的本地开发系统上运行良好,但在将 dependent_project 部署到 Elastic Beanstalk 时,pipenv 安装失败并显示:Permission denied (publickey)

这就引出了一个问题:

如何使用 Amazon Linux 2 platform hooks 配置 Elastic Beanstalk 环境,以便 pipenv 可以通过 SSH 从私人在线 git 存储库成功安装包?

在以下讨论中可以找到一些难题,但这些不使用 Amazon Linux 2 平台挂钩:

【问题讨论】:

    标签: git ssh amazon-elastic-beanstalk pipenv amazon-linux-2


    【解决方案1】:

    总结

    假设我们定义了以下 Elastic Beanstalk 环境属性,并且 bitbucket 公钥文件和我们的私钥文件都已上传到指定的 S3 存储桶:

    S3_BUCKET_NAME="my_bucket"
    REPO_HOST_NAME="bitbucket.org"
    REPO_HOST_PUBLIC_KEY_NAME="bitbucket_public_key"
    REPO_PRIVATE_KEY_NAME="my_private_key"
    

    然后可以使用.platform/hooks/prebuild中的这个钩子来完成配置:

    #!/bin/bash
    
    # git is required to install our python packages directly from bitbucket
    yum -y install git
    
    # file paths (platform hooks are executed as root)
    SSH_KNOWN_HOSTS_FILE="/root/.ssh/known_hosts"
    SSH_CONFIG_FILE="/root/.ssh/config"
    PRIVATE_KEY_FILE="/root/.ssh/$REPO_PRIVATE_KEY_NAME"
    
    # remove any existing (stale) keys for our host from the known_hosts file
    [ -f $SSH_KNOWN_HOSTS_FILE ] && ssh-keygen -R $REPO_HOST_NAME
    
    # read the (fresh) host key from S3 file and append to known_hosts file
    aws s3 cp "s3://$S3_BUCKET_NAME/$REPO_HOST_PUBLIC_KEY_NAME" - >> $SSH_KNOWN_HOSTS_FILE
    
    # copy our private key from S3 to our instance
    aws s3 cp "s3://$S3_BUCKET_NAME/$REPO_PRIVATE_KEY_NAME" $PRIVATE_KEY_FILE
    
    # create an ssh config file to point to the private key file
    tee $SSH_CONFIG_FILE <<HERE
    Host $REPO_HOST_NAME
        User git
        Hostname $REPO_HOST_NAME
        IdentityFile $PRIVATE_KEY_FILE
    HERE
    
    # file permissions must be restricted
    chmod 600 $SSH_CONFIG_FILE
    chmod 600 $PRIVATE_KEY_FILE
    

    注意此文件需要执行权限 (chmod +x &lt;file path&gt;)。

    详解

    继续阅读以了解详细的理由。

    Git

    要访问 git 存储库,我们的 Elastic Beanstalk 环境需要安装 git。 这可以使用yum 在平台挂钩中完成(-y 对每个问题都假定“是”):

    yum -y install git
    

    SSH 密钥

    在我们的 Elastic Beanstalk (EB) 实例和例如 Elastic Beanstalk (EB) 实例之间建立 SSH 连接。一个 bitbucket 存储库,我们需要三个 SSH 密钥:

    • bitbucket.org 的 public 密钥,用于验证我们是否连接到受信任的主机。

      要获取bitbucket.org 的公钥,格式适合known_hosts,我们可以使用ssh-keyscan。 为了安全起见,我们should verify this key 使用“可信”来源。 在我们的例子中,我们能做的最好的就是将公钥指纹与bitbucket(或github)网站上发布的“官方”指纹进行比较。 指纹可以使用ssh-keygen从公钥计算出来,例如

      ssh-keyscan -t rsa bitbucket.org | ssh-keygen -lf -
      
    • 我们存储库的私有密钥和公共密钥。

      可以使用ssh-keygen 生成由私钥和公钥组成的密钥对。 私钥必须保密,公钥必须复制到 bitbucket 存储库的“访问密钥”列表中,如bitbucket docs 中所述。 请注意,创建密钥对没有密码是最方便的,否则我们的脚本也需要处理密码。

    在 AWS 上存储密钥

    在部署期间,公共 bitbucket 主机密钥和我们的私有 repo 密钥需要在 EB 环境中可用。 private 密钥是秘密的,因此它不应存储在源代码中,也不应以其他方式进行版本控制。

    最方便的选择是将键值存储为EB environment properties(即环境变量),因为这些在部署期间很容易获得。 原则上,这可以完成,例如使用base64 编码将多行私钥存储在单行环境属性中。 但是,所有 EB 环境属性键和值组合的总大小为limited to a mere 4096 bytes,这基本上排除了此选项。

    另一种方法是将密钥文件存储在 AWS S3 上的安全私有存储桶中。 documentation 描述了如何设置一个 IAM 角色来授予对 EC2 实例的 S3 存储桶的访问权限。文档确实提供了一个配置示例,但这使用了.ebextensions,不适用于.platform 钩子。

    简而言之,我们可以使用默认设置(启用“阻止公共访问”,无自定义权限)创建一个基本的 S3 存储桶,并将 SSH 密钥文件上传到该存储桶。 然后,使用 AWS IAM Web 控制台,选择 aws-elasticbeanstalk-ec2-role(或者,最好创建一个自定义角色),并附加 AmazonS3ReadOnlyAccess 策略。

    在部署到 Elastic Beanstalk 期间,我们可以使用 .platform 挂钩将密钥文件从 S3 存储桶下载到使用 aws cli 的 EC2 实例。

    要测试 EC2 和 S3 之间的连接,我们可以使用 eb ssh 连接到 EC2 实例,然后使用例如 aws s3 ls s3://&lt;bucket name&gt; 来列出存储桶内容。

    更新 known_hosts

    要表明 bitbucket.org 是受信任的主机,需要将其公钥添加到我们实例上的 known_hosts 文件中。 在我们的平台挂钩脚本中,我们删除主机的任何现有公钥,以防它们过时,并用我们在 S3 上的文件中的当前密钥替换它们:

    SSH_KNOWN_HOSTS_FILE="/root/.ssh/known_hosts"
    [ -f $SSH_KNOWN_HOSTS_FILE ] && ssh-keygen -R $REPO_HOST_NAME
    aws s3 cp "s3://$S3_BUCKET_NAME/$REPO_HOST_PUBLIC_KEY_NAME" - >> $SSH_KNOWN_HOSTS_FILE
    

    指定私钥

    可以从S3下载私钥如下,我们需要限制文件权限:

    PRIVATE_KEY_FILE="/root/.ssh/$REPO_PRIVATE_KEY_NAME"
    aws s3 cp "s3://$S3_BUCKET_NAME/$REPO_PRIVATE_KEY_NAME" $PRIVATE_KEY_FILE
    chmod 600 $PRIVATE_KEY_FILE
    

    还需要一个 SSH 配置文件来指向私钥:

    tee $SSH_CONFIG_FILE <<HERE
    Host $REPO_HOST_NAME
        User git
        Hostname $REPO_HOST_NAME
        IdentityFile $PRIVATE_KEY_FILE
    HERE
    chmod 600 $SSH_CONFIG_FILE
    

    再次,文件permissions must be restricted

    最终脚本显示在顶部的摘要中。 该脚本可以存储,例如在项目文件夹中作为.platform/hooks/prebuild/01_configure_bitbucket_ssh.sh

    钩子和配置钩子

    请注意,Amazon Linux 2 使用 .platform/hooks 进行正常部署,使用 .platform/confighooks 进行配置部署。 通常,在这两种情况下都需要使用相同的脚本。 为防止代码重复,我们的.platform/confighooks/prebuild/01_configure_bitbucket_ssh.sh 可能如下所示:

    #!/bin/bash
    source "/var/app/current/.platform/hooks/prebuild/01_configure_bitbucket_ssh.sh"
    

    请注意,应用程序代码在实例上以/var/app/current 结尾。

    【讨论】:

      猜你喜欢
      • 2020-09-22
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 2014-03-22
      • 1970-01-01
      • 2013-06-23
      相关资源
      最近更新 更多