了解服务器架构:使用 Nginx reverse-proxy 或 Apache 服务器从 AWS S3 传送内容
Understanding server architecture: Delivering content from AWS S3 using Nginx reverse-proxy or Apache server
本题的目的是理解服务端架构设计时的策略。
用例:
我想为允许用户上传和下载多媒体内容(图像、视频等)的应用程序构建一个 http 服务器。预计会有大量并发用户(例如,大约 50k)upload/download 内容。
所有内容都将存储在 AWS S3 存储桶中。有关 S3 存储桶的信息,即存储桶 name/authentication headers 应该对用户隐藏。由于 S3 存储桶有多个访问控制选项 (AWS-ACL),因此最好不要让存储桶对 All_Users(经过身份验证的用户和匿名用户)可用。我不想公开 public 域中的内容。
查询
因为我想对用户屏蔽 AWS S3,所以我需要
使用 web-server 或反向代理。我经历过多次
比较 Apache 与 Nginx 的资源。由于服务器需要
从 S3 向大量并发用户提供静态内容,
Nginx 似乎是一个更好的选择。不是吗??
是否将 S3 存储桶的访问控制级别设置为 ALL_USERS(到
经过身份验证的用户和匿名用户)对数据隐私的妥协?如果我
使用反向代理,用户无法确定 S3 bucket
url秒。数据安全私密吗?
但是,如果 S3 存储桶仅供经过身份验证的用户使用,
nginx 反向代理会工作吗?我经历了 Nginx 逆向
S3 的代理。为了让 Nginx 作为反向代理工作,一个
Pre-signed URL需要准备。 pre-signed的到期时间
url 又是一个棘手的决定。是否设置一个巨大的到期时间
pre-signedurl有意义吗?它是否会损害安全性或
数据隐私(类似于 ALL_USERS 的 s3 访问控制)?如是,
有没有办法反向代理动态生成的请求
pre-signed url(过期时间短)仅通过 nginx?
任何有助于巩固我理解的信息和资源都将非常有帮助。
Does setting Access Control Level to S3 bucket to ALL_USERS ( to authenticated and anonymous users) compromise on data privacy?
当然可以。别这样。
If I use reverse proxy, there is no way for the user to determine S3 bucket urls. Is the data safe and private?
理论上,他们无法确定,但如果错误消息或错误配置泄露了信息怎么办?这就是 security through obscurity,它只会给您一种虚假的安全感。总有更好的方法。
Information regarding S3 bucket i.e. bucket name/authentication headers should be masked from the user.
带有签名 URLs 的 S3 的身份验证机制是设计的,因此将其暴露给用户没有任何危害。唯一的秘密是您的 AWS 密钥,您会注意到它没有在签名 URL 中公开。它也不能合理地 reverse-engineered,并且签名的 URL 仅适用于签名允许的资源和操作。
签署 URL 并将其呈现给用户不会造成安全风险,但诚然,您可能出于其他原因不想这样做。我经常这样做——在呈现页面时签署 URL,过期时间相对较长,或者签署 URL 并在用户单击时将其重定向到已签署的 URL在 link 返回到我的应用程序服务器(验证他们访问资源的授权,然后 returns 签名的 URL 具有非常短的到期时间,例如 5 到 10 秒;过期可以在下载过程中发生而不会导致问题——签名只需要在接受对 S3 的请求之前避免过期。
然而,如果你想走代理路线(除了上述之外,我在我的系统中也是这样做的),有一个比你想象的更简单的方法:bucket policy 可以配置为允许根据您的服务器的源 IP 地址...授予特定权限。
这是直接从我的一个存储桶中提取的(经过净化的)策略。 IP 地址来自 RFC-5737,以避免本示例中的私有 IP 地址造成混淆。
这些 IP 地址是 public IP 地址...它们将是附加到您的网络服务器的弹性 IP 地址,或者最好是附加到网络服务器用于其传出请求的 NAT 实例。
{
"Version": "2008-10-17",
"Id": "Policy123456789101112",
"Statement": [
{
"Sid": "Stmt123456789101112",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"203.0.113.173/32",
"203.0.113.102/32",
"203.0.113.52/32",
"203.0.113.19/32"
]
}
}
}
]
}
这是做什么的?如果请求从列出的 IP 地址之一到达 S3,则会向请求者授予 GetObject
权限。使用代理,您的代理的 IP 地址将是 S3 看到的 IP 地址,如果它符合存储桶策略,请求将被授予,允许您的代理从 S3 获取 objects 而不允许互联网的其余部分到,除非提供备用凭据,例如带有签名的 URL。此策略不会直接“拒绝”任何内容,因为拒绝是隐含的。重要的是,不要使用 public-read
ACL 上传您的 objects,因为那样会允许任何人下载反对的内容。默认 private
ACL 非常适合此应用程序。
S3 可以根据其他条件授予这样的权限,例如 Referer:
header,您可能会在网上找到这样的示例,但 不要那样做。相信浏览器报告的引用页面是一种极其薄弱和原始的安全机制,几乎不提供真正的保护——headers 非常容易被欺骗。这种过滤实际上只对 hot-linking 喜欢您的内容的讨厌的懒人有用。源 IP 地址完全是另一回事,因为它不在第 7 层 header 中传输,并且不容易被欺骗。
因为 S3 仅通过 TCP 协议与 Internet 交互,所以您的源地址——即使知道您如何启用存储桶以信任这些地址——无法以任何实际方式进行欺骗,因为要做到这意味着破坏 AWS 核心 IP 网络基础设施的安全性——TCP 要求原始机器可以通过它使用的源 IP 地址跨子网边界访问,并且 AWS 网络只会将这些响应路由回您的 legitimately-allocated IP 地址,除了重置或放弃连接外别无选择,因为它们不是由您发起的。
请注意,此解决方案不能与 S3 VPC endpoints which Amazon recently announced 结合使用,因为对于 S3 VPC 端点,您的源 IP 地址(S3 看到的)将是私有地址,这不是您的唯一地址VPC...但这应该不是问题。我只是为了彻底考虑才提到这个警告。 S3 VPC 端点不是必需的,默认情况下不启用,如果启用,可以在 per-subnet 的基础上配置。
本题的目的是理解服务端架构设计时的策略。
用例: 我想为允许用户上传和下载多媒体内容(图像、视频等)的应用程序构建一个 http 服务器。预计会有大量并发用户(例如,大约 50k)upload/download 内容。
所有内容都将存储在 AWS S3 存储桶中。有关 S3 存储桶的信息,即存储桶 name/authentication headers 应该对用户隐藏。由于 S3 存储桶有多个访问控制选项 (AWS-ACL),因此最好不要让存储桶对 All_Users(经过身份验证的用户和匿名用户)可用。我不想公开 public 域中的内容。
查询
因为我想对用户屏蔽 AWS S3,所以我需要 使用 web-server 或反向代理。我经历过多次 比较 Apache 与 Nginx 的资源。由于服务器需要 从 S3 向大量并发用户提供静态内容, Nginx 似乎是一个更好的选择。不是吗??
是否将 S3 存储桶的访问控制级别设置为 ALL_USERS(到 经过身份验证的用户和匿名用户)对数据隐私的妥协?如果我 使用反向代理,用户无法确定 S3 bucket url秒。数据安全私密吗?
但是,如果 S3 存储桶仅供经过身份验证的用户使用, nginx 反向代理会工作吗?我经历了 Nginx 逆向 S3 的代理。为了让 Nginx 作为反向代理工作,一个 Pre-signed URL需要准备。 pre-signed的到期时间 url 又是一个棘手的决定。是否设置一个巨大的到期时间 pre-signedurl有意义吗?它是否会损害安全性或 数据隐私(类似于 ALL_USERS 的 s3 访问控制)?如是, 有没有办法反向代理动态生成的请求 pre-signed url(过期时间短)仅通过 nginx?
任何有助于巩固我理解的信息和资源都将非常有帮助。
Does setting Access Control Level to S3 bucket to ALL_USERS ( to authenticated and anonymous users) compromise on data privacy?
当然可以。别这样。
If I use reverse proxy, there is no way for the user to determine S3 bucket urls. Is the data safe and private?
理论上,他们无法确定,但如果错误消息或错误配置泄露了信息怎么办?这就是 security through obscurity,它只会给您一种虚假的安全感。总有更好的方法。
Information regarding S3 bucket i.e. bucket name/authentication headers should be masked from the user.
带有签名 URLs 的 S3 的身份验证机制是设计的,因此将其暴露给用户没有任何危害。唯一的秘密是您的 AWS 密钥,您会注意到它没有在签名 URL 中公开。它也不能合理地 reverse-engineered,并且签名的 URL 仅适用于签名允许的资源和操作。
签署 URL 并将其呈现给用户不会造成安全风险,但诚然,您可能出于其他原因不想这样做。我经常这样做——在呈现页面时签署 URL,过期时间相对较长,或者签署 URL 并在用户单击时将其重定向到已签署的 URL在 link 返回到我的应用程序服务器(验证他们访问资源的授权,然后 returns 签名的 URL 具有非常短的到期时间,例如 5 到 10 秒;过期可以在下载过程中发生而不会导致问题——签名只需要在接受对 S3 的请求之前避免过期。
然而,如果你想走代理路线(除了上述之外,我在我的系统中也是这样做的),有一个比你想象的更简单的方法:bucket policy 可以配置为允许根据您的服务器的源 IP 地址...授予特定权限。
这是直接从我的一个存储桶中提取的(经过净化的)策略。 IP 地址来自 RFC-5737,以避免本示例中的私有 IP 地址造成混淆。
这些 IP 地址是 public IP 地址...它们将是附加到您的网络服务器的弹性 IP 地址,或者最好是附加到网络服务器用于其传出请求的 NAT 实例。
{
"Version": "2008-10-17",
"Id": "Policy123456789101112",
"Statement": [
{
"Sid": "Stmt123456789101112",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"203.0.113.173/32",
"203.0.113.102/32",
"203.0.113.52/32",
"203.0.113.19/32"
]
}
}
}
]
}
这是做什么的?如果请求从列出的 IP 地址之一到达 S3,则会向请求者授予 GetObject
权限。使用代理,您的代理的 IP 地址将是 S3 看到的 IP 地址,如果它符合存储桶策略,请求将被授予,允许您的代理从 S3 获取 objects 而不允许互联网的其余部分到,除非提供备用凭据,例如带有签名的 URL。此策略不会直接“拒绝”任何内容,因为拒绝是隐含的。重要的是,不要使用 public-read
ACL 上传您的 objects,因为那样会允许任何人下载反对的内容。默认 private
ACL 非常适合此应用程序。
S3 可以根据其他条件授予这样的权限,例如 Referer:
header,您可能会在网上找到这样的示例,但 不要那样做。相信浏览器报告的引用页面是一种极其薄弱和原始的安全机制,几乎不提供真正的保护——headers 非常容易被欺骗。这种过滤实际上只对 hot-linking 喜欢您的内容的讨厌的懒人有用。源 IP 地址完全是另一回事,因为它不在第 7 层 header 中传输,并且不容易被欺骗。
因为 S3 仅通过 TCP 协议与 Internet 交互,所以您的源地址——即使知道您如何启用存储桶以信任这些地址——无法以任何实际方式进行欺骗,因为要做到这意味着破坏 AWS 核心 IP 网络基础设施的安全性——TCP 要求原始机器可以通过它使用的源 IP 地址跨子网边界访问,并且 AWS 网络只会将这些响应路由回您的 legitimately-allocated IP 地址,除了重置或放弃连接外别无选择,因为它们不是由您发起的。
请注意,此解决方案不能与 S3 VPC endpoints which Amazon recently announced 结合使用,因为对于 S3 VPC 端点,您的源 IP 地址(S3 看到的)将是私有地址,这不是您的唯一地址VPC...但这应该不是问题。我只是为了彻底考虑才提到这个警告。 S3 VPC 端点不是必需的,默认情况下不启用,如果启用,可以在 per-subnet 的基础上配置。