【问题标题】:How to use gnupg in an AWS Lambda function如何在 AWS Lambda 函数中使用 gnupg
【发布时间】:2021-08-19 06:58:00
【问题描述】:

我有一个 GPG 加密文件的本地 python 代码。一旦将文件添加到触发此 lambda 的 AWS S3,我需要将其转换为 AWS Lambda。

我的本​​地代码

import os
import os.path
import time
import sys
gpg = gnupg.GPG(gnupghome='/home/ec2-user/.gnupg')

path = '/home/ec2-user/2021/05/28/'
ptfile = sys.argv[1]

with open(path + ptfile, 'rb')as f:
        status = gpg.encrypt_file(f, recipients=['user@email.com'], output=path + ptfile + ".gpg")

print(status.ok)
print(status.stderr)

当我将此文件作为 python3 encrypt.py file.csv 执行时,这非常有用,结果是 file.csv.gpg

我正在尝试将其移至 AWS Lambda 并在将 file.csv 上传到 S3 时调用。

import json
import urllib.parse
import boto3
import gnupg
import os
import os.path
import time

s3 = boto3.client('s3')

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    
    try:
        gpg = gnupg.GPG(gnupghome='/.gnupg')
        ind = key.rfind('/')
        ptfile = key[ind + 1:]
        with open(ptfile, 'rb')as f:
            status = gpg.encrypt_file(f, recipients=['email@company.com'], output= ptfile + ".gpg")
        print(status.ok)
        print(status.stderr)

我的 AWS Lambda 代码 zip 在 AWS 中创建了一个文件夹结构

我在运行时看到的错误是 [ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'gnupg' Traceback(最近一次通话最后一次):

【问题讨论】:

  • 首先,您需要 Deploy Python Lambda functions with .zip file archives - AWS Lambda 以包含 gnupg 库。进程所需的任何文件(例如私钥)都需要包含在 Zip 中或从 S3 下载。
  • @JohnRotenstein 我更新了我的代码结构并注意到运行时错误。
  • gnupg 库不是标准的 Python 库。它需要作为 部署包 包含在内,以便 Python 可以使用该库(而不仅仅是您的 .gnupg 目录)。这与尝试在没有安装gnupg 的新计算机上运行程序的情况相同——您需要使用pip 安装它。对于 Lambda 函数,您可以在虚拟环境中进行安装,然后按照我之前评论中链接的说明将结果打包到 zip 文件中。

标签: python amazon-s3 aws-lambda python-3.8 gnupg


【解决方案1】:

您可以从GnuPG 1.4 source 创建一个适合 AWS Lambda 上的 python-gnupg 使用的 gpg 二进制文件。你需要

  • GCC 和相关工具(Amazon Linux 2 上的sudo yum install -y gcc make glibc-static
  • 压缩包

下载 GnuPG 源包并验证其签名后,构建二进制文件

$ tar xjf gnupg-1.4.23.tar.bz2
$ cd gnupg-1.4.23
$ ./configure
$ make CFLAGS='-static'
$ cp g10/gpg /path/to/your/lambda/

您还需要 python-gnupg 中的 gnupg.py 模块,您可以使用 pip 获取它:

$ cd /path/to/your/lambda/
$ pip install -t . python-gnupg

您的 Lambda 的源结构现在看起来像这样:

.
├── gnupg.py
├── gpg
└── lambda_function.py

更新您的函数以将 gpg 二进制文件的位置传递给 python-gnupg 构造函数:

gpg = gnupg.GPG(gnupghome='/.gnupg', gpgbinary='./gpg')

使用zip打包Lambda函数:

$ chmod o+r gnupg.py lambda_function.py 
$ chmod o+rx gpg
$ zip lambda_function.zip gnupg.py gpg lambda_function.py 

【讨论】:

    【解决方案2】:

    由于在 python 中使用 gpg 需要一些系统依赖项,即 gnupg 本身,您需要使用容器运行时环境构建您的 lambda 代码:https://docs.aws.amazon.com/lambda/latest/dg/lambda-images.html

    使用 docker 将允许您安装底层系统依赖项,以及导入您的密钥。

    Dockerfile 看起来像这样:

    FROM public.ecr.aws/lambda/python:3.8
    
    RUN apt-get update && apt-get install gnupg
    
    # copy handler file
    COPY app.py <path-to-keys> ./
    
    # Add keys to gpg
    RUN gpg --import <path-to-private-key>
    RUN gpg --import <path-to-public-key>
    
    # Install dependencies and open port
    RUN pip3 install -r requirements.txt
    
    CMD ["app.lambda_handler"]  
    

    app.py 将是您的 lambda 代码。随意复制除主 lambda 处理程序之外的任何必要文件。

    一旦构建并上传了容器映像。 lambda 现在可以使用图像(包括它的所有依赖项)。 lambda 代码将在包含 gnupg 和您导入的密钥的容器化环境中运行。

    资源:

    https://docs.aws.amazon.com/lambda/latest/dg/python-image.html https://docs.aws.amazon.com/lambda/latest/dg/lambda-images.html https://medium.com/@julianespinel/how-to-use-python-gnupg-to-decrypt-a-file-into-a-docker-container-8c4fb05a0593

    【讨论】:

      【解决方案3】:

      gpg 现在已经安装在 public.ecr.aws/lambda/python:3.8.

      尽管如此,Lambda 似乎没有提供。 所以你仍然需要将 gpg 可执行文件放入 Lambda 环境中。

      我是使用 docker 镜像完成的。

      我的 Dockerfile 只是:

      FROM public.ecr.aws/lambda/python:3.8
      
      COPY .venv/lib/python3.8/site-packages/ ./
      COPY test_gpg.py .
      
      CMD ["test_gpg.lambda_handler"]
      

      .venv 是我的 python virtualenv 包含的目录 我需要的python包。

      【讨论】:

        【解决方案4】:

        最好的方法是在你的 python lambda 中添加一个lambda layer to

        您需要在其中创建pip install gnupg 的虚拟环境,然后将所有已安装的 python 包放在一个 zip 文件中,然后将其作为 lambda 层上传到 aws。然后可以在需要 gnupg 的所有 lambda 中使用这个 lambda 层。要创建 Lamba 层,您基本上是这样做的:

        python3.9 -m venv my_venv
         ./my_venv/bin/pip3.9 install gnupg
        cp -r ./my_venv/lib/python3.9/site-packages/ python
        zip -r lambda_layer.zip python
        

        上面的 python 版本必须与 lambda 中的 python 函数匹配。

        如果您不想使用图层,您还可以这样做:

        zip -r lambda_layer.zip ./.gnupg
        zip lambda_layer.zip lambda_funtion.py
        

        你会得到一个 zip 文件,可以用作 lambda deployment package

        【讨论】:

          【解决方案5】:

          python-gnupg 软件包要求您安装有效的gpg 可执行文件,如官方文档'Deployment Requirements 中所述;我还没有找到从 lambda 访问 gpg 可执行文件的方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-27
            • 2021-03-20
            • 2019-10-30
            • 2016-03-25
            • 1970-01-01
            • 2017-06-04
            相关资源
            最近更新 更多