您的位置:首页 > 新闻 > 资讯 > 高防手表网站_ks免费刷粉网站推广低价_seo算法_关于进一步优化 广州

高防手表网站_ks免费刷粉网站推广低价_seo算法_关于进一步优化 广州

2025/5/21 22:21:37 来源:https://blog.csdn.net/xiaoyi52/article/details/146917863  浏览:    关键词:高防手表网站_ks免费刷粉网站推广低价_seo算法_关于进一步优化 广州
高防手表网站_ks免费刷粉网站推广低价_seo算法_关于进一步优化 广州

目录:
AWS概述
EMR Serverless
AWS VPC及其网络
关于AWS网络架构的思考
AWS S3 和 Lambda 使用

本文将通过一个实例来说明如何使用 AWS S3 和 Lambda。


使用场景:通过代码将文件上传到S3,该文件需要是公开访问的,并对上传的文件进行安全检测。

文件上传到S3

S3 bucket 设置

首先创建一个S3的bucket,例如 my-test-cn-north-1-bucket。为了公开访问,该bucket必须关闭"Block public access (bucket settings)",除了bucket级别之外,账号级别也需要关闭。这个设置是 public read 的前提。

Bucket policy 必须设置Principal和Action,Principal可以设置为当前账户下的用户或角色。如果允许当前账户下的所有的用户/角色,可以这样设置:

{"Effect": "Allow","Principal": { "AWS": "arn:aws:iam::123456789012:root" },"Action": ["s3:GetObject","s3:GetObjectAcl","s3:PutObject","s3:PutObjectAcl"],"Resource": "arn:aws:s3:::my-test-cn-north-1-bucket/*"
}

由于Bucket policy限制,此时bucket中的文件只有当前账户下的用户或角色才能读写。因此需要在上传文件时将文件的权限设置为public read的,也就是说要修改文件的ACL。编辑 Object Ownership,开启 “ACLs enabled”,至于对象拥有关系,选择 “Bucket owner preferred” 即可。

上传文件,并在文件的权限设置中将ACL修改为"public access"。这样设置完成之后,即可以保证bucket的put操作是受限的,同时read操作是公开的。

S3 API 文件上传

本地通过代码进行文件上传:

private static S3AsyncClient getAsyncClient() {AssumeRoleRequest assumeRoleRequest = AssumeRoleRequest.builder().roleArn("arn:aws-cn:iam:: 123456789012:role/product/operation").roleSessionName("AssumeRoleSession").build();StsClient stsClient = StsClient.builder().credentialsProvider(ProfileCredentialsProvider.builder().profileName("your-profile") // replace with your profile.build()).build();StsAssumeRoleCredentialsProvider creProvider =StsAssumeRoleCredentialsProvider.builder().stsClient(stsClient).refreshRequest(assumeRoleRequest).build();return S3AsyncClient.crtBuilder().credentialsProvider(creProvider).build();
}

而在生产环境中,当然是不能将角色ARNaws profile写到代码中的。因此需要用过 IRSA(IAM Roles for Service Accounts) 来实现 AWS API 调用。

创建一个ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:name: my-s3-accessnamespace: your-nsannotations:eks.amazonaws.com/role-arn: arn:aws-cn:iam:: 123456789012:role/my-test-cn-north-1-eks-access-s3

在角色my-test-cn-north-1-eks-access-s3policies中,需要设置bucket的访问策略:

{"Effect": "Allow","Action": "s3:*","Resource": ["arn:aws-cn:s3:::my-test-cn-north-1-bucket/*"]
}

然后在deployment中指定serviceAccount:

apiVersion: apps/v1
kind: Deployment
metadata:name: ms-test
spec:template:metadata:labels:...spec:serviceAccountName: my-s3-access

如此 EKS 的 workloads 即可以 ServiceAccount 绑定的角色身份来执行 S3 的 API 调用。

文件上传代码如下:

private static void putObjectToS3(InputStream is, String key, String bucketName, boolean publicRead) {try (S3TransferManager transferManager = S3TransferManager.builder().s3Client(S3AsyncClient.crtCreate()).build()) {UploadRequest uploadRequest = UploadRequest.builder().putObjectRequest(req -> {req.bucket(bucketName).key(key);if (publicRead) {req.acl("public-read"); // set public read acl}}).addTransferListener(LoggingTransferListener.create()).requestBody(AsyncRequestBody.fromInputStream(config -> config.inputStream(is).executor(newFixedThreadPool(8)))).build();transferManager.upload(uploadRequest).completionFuture().join();}
}

某些类型的文件如果不指定contentType,通过url访问时需要下载。如果指定了contentType,则可以在浏览器中打开。

文件安全扫描

创建lambda函数

文件上传到 S3之后,可以通过 lambda 来进行安全扫描。

首先创建一个 AWS lambda,选择最简单的 Author from scratch 模板,同时选择需要的运行时环境和系统架构,这里选择arm64架构。对于权限,如果需要复用role,就选择已有的role,否则就默认创建角色。

创建好 lambda 之后,需要在 Diagram 界面添加触发器,选择需要监听的 S3 bucket。

在 lambda 的配置页面,选择 Permissions 可以看到执行lambda的角色,也是创建lambda时默认创建的角色。查看该角色的权限 policies,可以发现与lambda日志相关的权限已经有了,但是还需要以下权限:

{"Effect": "Allow","Action": ["s3:GetObject","sns:Publish"],"Resource": ["arn:aws-cn:s3:::my-test-cn-north-1-bucket/*"]
}

创建 lambda layer

对文件进行安全扫描需要用到Clamav。正常情况下需要下载 Clamav 的源码然后编译成二进制文件。但是从官方下载的source包中没有configure文件,无法编译和安装。因此可以用第二种方式,直接在容器中安装 Clamav,然后将必要的文件拷贝出来制作 lambda layer。

使用docker run -it --name lambda-clamav amazonlinux:2 bash 来创建一个docker容器。

容器使用 amazonlinux:2 镜像是为了保持与 AWS Lambda的环境保持一致。

在容器中执行以下命令:

# 安装 ClamAV 和必要工具
yum install -y clamav clamav-update tar gzip# 确认版本
clamscan --version# 更新病毒库
freshclam# 创建打包目录
mkdir -p /opt/clamav-layer/bin
mkdir -p /opt/clamav-layer/lib# 复制 ClamAV 主程序
cp /usr/bin/clamscan /opt/clamav-layer/bin/
cp /usr/bin/freshclam /opt/clamav-layer/bin/# 复制动态链接库
ldd /usr/bin/clamscan | awk '{print $3}' | xargs -I {} cp {} /opt/clamav-layer/lib/
ldd /usr/bin/freshclam | awk '{print $3}' | xargs -I {} cp {} /opt/clamav-layer/lib/# 复制病毒库配置文件(可选)
mkdir -p /opt/clamav-layer/etc
cp /etc/freshclam.conf /opt/clamav-layer/etc/

将文件从容器复制到本地:

docker cp lambda-clamav:/opt/clamav-layer ./clamav-layer# 进入目录并打包
cd clamav-layer
zip -r ../clamav-layer.zip .

注意,只有更新病毒库后才能使用clamscan test.txt来扫描文件,否则没有基础的病毒库文件无法扫描。下载的病毒库文件默认放在/var/lib/clamav 目录下,总共有四个文件:

bytecode.cvd  daily.cvd  freshclam.dat  main.cvd

这里打包clamav-layer时并没有将病毒库一起打包进来,原因是 AWS Layer 限制了大小,压缩包不能超过50MB,解压后不能超过250MB。

layer 制作完成后,在 Lambda 的控制台的layer仓库中上传。上传时需要注意 layer的系统架构,可以在生成layer文件的容器中查看:

file /opt/clamav-layer/bin/clamscan# 以下结果表明为 ARM 架构
opt/clamav-layer/bin/clamscan: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.7.0, BuildID[sha1]=ac6484d18dd79864db6d56599e020f8a968f652c, stripped

上传完成后我们回到 lambda 函数,在code tab页的最下面上传 layer。layer的架构和运行时必须与lambda函数的架构和运行时是兼容的。如果lambda 函数是 x86_64的,就无法使用 arm 架构的layer。

layer的压缩包会直接解压到 lambda 实例的 /opt 目录下,其结构会变成: /opt/bin/clamscan, /opt/lib/…

lambda 函数实现

由于受到layer的大小限制导致病毒库无法打包到layer中,因此考虑实时下载或从S3下载。

将病毒库文件打包成clamav_db.tar.gz并上传到S3,然后实现 lambda 函数:

import os
import subprocess
import boto3
import tarfile
from botocore.exceptions import ClientErrors3 = boto3.client('s3')
S3_BUCKET = "ms-test-cn-north-1-bucket"
CLAMSCAN_PATH = "/opt/bin/clamscan"
FRESHCLAM_PATH = "/opt/bin/freshclam"
LIB_DIR = "/opt/lib"
DB_KEY = "clamav_db.tar.gz"
TMP_DB_PATH = "/tmp/clamav_db.tar.gz"
DB_DIR = "/tmp/clamav_db"def download_and_extract_db():try:s3.download_file(S3_BUCKET, DB_KEY, TMP_DB_PATH)os.makedirs(DB_DIR, exist_ok=True)with tarfile.open(TMP_DB_PATH, "r:gz") as tar:tar.extractall(DB_DIR)os.remove(TMP_DB_PATH)except ClientError as e:print(f"S3 下载失败: {e}")raisedef lambda_handler(event, context):os.environ["LD_LIBRARY_PATH"] = LIB_DIRif not os.path.exists(f"{DB_DIR}/main.cvd"):print(f"start download clamav db")download_and_extract_db()bucket = event['Records'][0]['s3']['bucket']['name']key = event['Records'][0]['s3']['object']['key']tmp_path = f"/tmp/{os.path.basename(key)}"try:s3.download_file(bucket, key, tmp_path)print(f"the file need to be checked: ", tmp_path)scan_cmd = [CLAMSCAN_PATH, "-d", DB_DIR, tmp_path]try:result = subprocess.run(scan_cmd, env={"LD_LIBRARY_PATH": LIB_DIR}, capture_output=True, text=True, timeout=180)print("stdout:", result.stdout)print("stderr:", result.stderr) if "Infected files: 0" not in result.stdout:print(f"感染文件: {key} - 结果: {result.stdout}")return {"status": "INFECTED"}else:print(f"安全文件: {key}")return {"status": "CLEAN"}except subprocess.TimeoutExpired:print("timeout!")except ClientError as e:print(f"S3 错误: {e}")return {"status": "ERROR"}finally:if os.path.exists(tmp_path):os.remove(tmp_path)

对于lambda来说,只有 /tmp目录是可写的,且最大为512MB。当 Lambda 服务复用同一个执行环境即热启动时,该目录是保留的。这种复用通常发生在短时间内连续多次调用同一个函数时。

当Lambda服务创建一个新的执行环境时,/tmp 目录会被清空并重新初始化。

如果想持久化病毒库,而不是每次重新下载,可以考虑挂载EFS。

测试

在 lambda 函数的 code 页面可以创建test event用来模拟S3 trigger,并可以保存下来复用。注意,测试事件中bucketName和文件需要是真实存在的。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com