如何以安全的方式从S3提供HLS流(授权和验证)

mko*_*zun 10 restful-authentication amazon-s3 video-streaming http-live-streaming

问题:

我在S3中存储了具有给定文件结构的HLS流的数量:

Video1
  ???hls3
      ???hlsv3-master.m3u8
      ???media-1
      ???media-2
      ???media-3
      ???media-4
      ???media-5
  ???hls4
      ???hlsv4-master.m3u8
      ???media-1
      ???media-2
      ???media-3
      ???media-4
      ???media-5
Run Code Online (Sandbox Code Playgroud)

在我的用户API中,我知道哪个用户可以访问哪些视频内容,但我还需要确保视频链接不可共享且只有具有正确权限的用户才能访问.

解决方案:

1)使用signed/temp S3 URL来获取私有S3内容.每当客户想要播放某些特定视频时,它就会向我的API发送请求.如果用户具有正确的权限,则API正在生成签名的URL并将其返回给客户端,客户端将其传递给播放器.

我在这里看到的问题是真实的视频内容存储在media-*目录中的十几个段文件中,我真的不知道如何保护所有这些 - 我是否需要分别对每个段文件URL进行签名?

2)S3内容是私有的.玩家提出的视频流请求通过我的API或单独的反向代理.因此,每当客户决定播放特定视频时,API/反向代理就会收到请求,进行身份验证和授权并传递正确的内容(主播放列表文件和段).

在这种情况下,我仍然需要将S3内容设为私有,并且只能通过我的API/反向代理访问.这里推荐的方式应该是什么? S3通过令牌进行休息认证

3)使用受保护密钥加密.在这种情况下,所有视频片段都是加密的并且是公开的.密钥也存储在S3中, 但不公开.玩家发出的每个关键请求都经过我的API/反向代理的认证和授权.

这些是我现在想到的3个解决方案.不相信所有这些.我正在寻找一些简单且防弹安全的东西.有什么建议/意见吗?

二手技术:

  • ffmpeg用于将视频编码为不同的比特率

  • bento4用于视频分割

Mic*_*bot 17

我是否需要单独签署每个段文件URL?

如果玩家直接从S3请求,那么是.所以这可能不是理想的方法.

一个选项是在存储桶前面的CloudFront.CloudFront可以配置Origin Access Identity,允许它签署请求并将它们发送到S3,以便它可以代表授权用户获取私有S3对象,CloudFront支持两个签名URL(使用与S3不同的算法,我将在下面解释两个重要的差异)或使用签名的cookie.CloudFront中签名的请求和cookie的工作方式非常相似,重要的区别在于cookie可以设置一次,然后由浏览器自动用于每个后续请求,从而无需签署单个URL.(啊哈)

对于CloudFront中的签名URL和签名cookie,如果您使用自定义策略,则可以获得使用S3无法轻松完成的两项附加功能:

  • 与CloudFront签名关联的策略可以允许路径中通配符,因此您可以授权访问任何文件,例如,/media/Video1/*直到签名到期为止.S3签名URL不支持任何形式的通配符 - S3 URL只能对单个对象有效.

  • 只要CloudFront分配仅配置为IPv4,您就可以将签名绑定到特定的客户端IP地址,只允许从单个IP地址访问该签名(CloudFront现在支持IPv6作为可选功能,但它不是目前与此选项兼容).这有点侵略性和可能不是与移动用户的基础上,其将切换源地址,因为它们从提供商网络向无线网络连接和切换回期望的.

仍然必须为所有内容链接生成签名的URL,但是您只能生成并签署一次URL,然后重复使用签名,只需对每个文件进行字符串重写,从而使该选项的计算成本更低......但仍然繁琐.另一方面,签名的cookie应该"适用于"任何匹配的对象.

当然,添加CloudFront还应该通过缓存和Internet路径缩短来提高性能,因为请求会跳到更接近浏览器的托管AWS网络,而不是通常直接发送到S3的请求.使用CloudFront时,来自浏览器的请求将被发送到60多个全局"边缘位置"中的任何一个被认为是最接近发出请求的浏览器.CloudFront的可以提供相同的缓存对象不同的用户提供不同的URL或者Cookie,只要SIGS或cookies是合法的,当然.

要使用CloudFront签名的cookie,至少应用程序的一部分 - 设置cookie的部分 - 需要"指向"指向存储桶的同一CloudFront分配.这是通过将您的应用程序声明为分发的附加Origin,并为特定路径模式创建缓存行为来完成的,该模式在请求时由CloudFront转发到您的应用程序,然后应用程序可以使用相应的Set-Cookie:标头进行响应.

我不隶属于AWS,因此不要将以下内容误认为是"推销" - 只是期待您的下一个问题:CloudFront + S3的定价使得与单独使用S3相比的成本差异通常可以忽略不计 - S3不会在通过CloudFront请求对象时向您收取带宽,而CloudFront的带宽费用在某些情况下略低于直接使用S3的费用.虽然这似乎违反直觉,但有意义的是,AWS会以鼓励在其网络中分发请求的方式构建定价,而不是将它们全部集中在单个S3区域.


请注意,上述或下面的机制完全不受未经授权的"共享"的影响,因为根据用户的专业知识,浏览器和用户必须可以使用身份验证信息......但两种方法都是如此似乎绰绰有余地保持诚实的用户诚实,这是你所希望做的一切.由于签名URL和cookie上的签名具有到期时间,因此共享能力的持续时间有限,您可以通过CloudFront日志分析识别此类模式,并做出相应的反应.无论采取何种方法,都不要忘记保持日志的重要性.


反向代理也是一个好主意,可能很容易实现,并且如果运行代理的EC2机器与存储桶位于同一AWS区域并且代理基于,则应该执行非常可接受而不会产生额外的数据传输费用或吞吐量问题在像Nginx或HAProxy中找到的可靠,高效的代码上.

您无需在此环境中对任何内容进行签名,因为您可以配置存储桶以允许反向代理访问私有对象,因为它具有固定的IP地址.

在存储桶策略中,只有当 "匿名"用户的源IPv4地址与其中一个代理的IP地址匹配时s3:getObject,才会授予"匿名"用户权限.代理服务器代表授权用户匿名请求对象(无需签名).这要求您不使用S3 VPC端点,而是为代理提供弹性IP地址或将其置于NAT网关或NAT实例之后,让S3信任NAT设备的源IP.如果您确实使用了S3 VPC端点,那么应该可以让S3信任该请求只是因为它遍历了S3 VPC端点,尽管我没有对此进行测试.(S3 VPC端点是可选的;如果您没有明确配置一个,那么您没有一个,可能不需要一个).


如果我理解正确,你的第三个选项似乎最弱.授权但恶意的用户获得可以全天共享密钥的密钥.