如何通过可信服务器安全传输S3文件至无AWS credentials的不可信服务器?
当然有更高效的方案!不用再折腾「下载到可信服务器再转发」的中转流程,我们可以让不可信服务器直接安全访问S3,同时完全不会泄露你的长期AWS凭证。下面是几个经过实践验证的靠谱方案,你可以根据自己的场景选择:
方案1:预签名URL(Presigned URLs)—— 适合单次/少量文件传输
这是最常用的轻量方案:由可信服务器生成一个带有效期、限定权限的临时URL,传给不可信服务器后,对方就能直接用这个URL下载(或上传)指定的S3文件,全程不需要持有任何AWS凭证。
示例代码/命令
用Python的boto3生成下载URL:
import boto3 from botocore.config import Config s3_client = boto3.client('s3', config=Config(signature_version='s3v4')) # 生成有效期1小时的下载预签名URL presigned_url = s3_client.generate_presigned_url( 'get_object', Params={'Bucket': 'your-bucket-name', 'Key': 'target-file.txt'}, ExpiresIn=3600 # 单位秒,可根据需求调整 )
用AWS CLI生成:
aws s3 presign s3://your-bucket-name/target-file.txt --expires-in 3600
优缺点
- ✅ 完全不用给不可信服务器任何AWS凭证,URL过期自动失效,风险极低
- ❌ 适合单次或少量文件,大量文件需要批量生成URL,操作略繁琐
方案2:STS临时凭证(AssumeRole)—— 适合多次/批量访问
如果不可信服务器需要频繁访问S3,或者需要操作多个文件/资源,可以用AWS STS的AssumeRole接口生成临时凭证:由可信服务器申请一批有时间限制、权限严格限定的临时AK/SK/SessionToken,传给不可信服务器后,对方就能用这些临时凭证直接调用S3 API。
操作步骤&示例
- 先在IAM创建一个角色,仅赋予S3的必要权限(比如只允许
s3:GetObject访问指定bucket的特定前缀) - 可信服务器调用STS接口获取临时凭证:
import boto3 sts_client = boto3.client('sts') response = sts_client.assume_role( RoleArn='arn:aws:iam::123456789012:role/UnTrustedServerS3Access', RoleSessionName='UnTrustedServerSession', DurationSeconds=3600 # 有效期1小时,最长可设12小时(需角色配置支持) ) # 提取临时凭证,传给不可信服务器 temp_credentials = { 'aws_access_key_id': response['Credentials']['AccessKeyId'], 'aws_secret_access_key': response['Credentials']['SecretAccessKey'], 'aws_session_token': response['Credentials']['SessionToken'] }
- 不可信服务器用临时凭证访问S3(以AWS CLI为例):
export AWS_ACCESS_KEY_ID=临时AK值 export AWS_SECRET_ACCESS_KEY=临时SK值 export AWS_SESSION_TOKEN=临时SessionToken值 aws s3 cp s3://your-bucket-name/target-file.txt ./
优缺点
- ✅ 支持多次访问,权限可以精细控制,适合批量操作
- ❌ 需要提前配置IAM角色,临时凭证需通过加密链路传输(你已有的加密链路正好能用)
方案3:S3访问点(Access Points)+ VPC网络控制—— 适合AWS内部不可信资源
如果你的不可信服务器是AWS EC2(在VPC内),可以用S3访问点配合VPC端点,给EC2实例赋予最小权限的IAM角色:实例会自动通过AWS内部网络获取角色权限,直接访问指定的S3资源,同时通过VPC安全组限制只有该实例能访问访问点。
这个方案不需要手动传递任何凭证,适合长期运行的AWS内部不可信服务。
通用安全注意事项
- 遵循最小权限原则:比如预签名URL只给单个文件的下载权限,临时角色仅允许访问指定的bucket前缀,避免过度授权
- 有效期设尽可能短:预签名URL和临时凭证的有效期建议控制在1小时以内,降低泄露风险
- 加密传输:传递预签名URL或临时凭证时,务必使用你现有的加密通信链路,防止中间人拦截
内容的提问来源于stack exchange,提问作者cemersoz




