我创建了一个S3存储桶,上传了视频,并在CloudFront中创建了一个流分发。使用静态HTML播放器对其进行了测试,并且可以正常工作。我已经通过帐户设置创建了密钥对。目前,我的桌面上有私钥文件。那就是我
我的目标是使Django /
Python网站创建安全的URL,除非这些视频来自我的其中一个页面,否则其他人将无法访问这些视频。问题是我对亚马逊布置事物的方式过敏,而我却变得越来越困惑。
我意识到这将不是StackOverflow上的最佳问题,但我敢肯定,我不能成为唯一无法在如何设置安全的CloudFront /
S3情况下大跌眼镜的傻瓜。非常感谢您的帮助,并愿意(一旦过了两天)就最佳答案给出500磅的奖金。
我有几个问题,一旦回答,就应该成为一种关于如何实现我所追求的目标的解释:
在文档中(接下来是一个示例),周围有很多XML告诉我我需要POST
到各个地方处理事情。是否有一个在线控制台可以做到这一点?还是我真的必须通过cURL强制这样做(等等)?
如何为CloudFront创建原始访问身份并将其绑定到我的发行版?我已经阅读了这份文档,但是,从第一点来看,我不知道该怎么做。我的密钥对如何适应呢?
完成后,如何限制S3存储桶仅允许人们通过该身份下载内容?如果这是另一项XML工作,而不是在Web UI上单击,请告诉我应该在何处以及如何将其输入我的帐户。
在Python中,为文件生成过期URL的最简单方法是什么。我已经boto
安装了,但看不到如何从流分发中获取文件。
是否有任何应用程序或脚本可能会难以设置此服装?我使用Ubuntu(Linux),但如果仅Windows,则可以在VM中使用XP。我已经看过CloudBerry S3 Explorer Pro,但是它和在线UI一样有意义。
没错,建立此程序需要大量API工作。希望他们尽快在AWS控制台中获得它!
更新:我已将此代码提交给boto-从boto v2.1(2011年10月27日发布)开始,这变得容易得多。 对于boto
<2.1,请使用此处的说明。对于boto
2.1或更高版本,请在我的博客上获取更新的说明:http : //www.secretmike.com/2011/10/aws-
cloudfront-secure-streaming.html 一旦boto v2.1被更多发行版打包,我将在此处更新答案。
要完成您想要的操作,您需要执行以下步骤,以下将详细介绍:
1-创建存储桶并上传对象
最简单的方法是通过AWS控制台,但是为了完整起见,我将展示如何使用boto。Boto代码如下所示:
import boto
#credentials stored in environment AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
s3 = boto.connect_s3()
#bucket name MUST follow dns guidelines
new_bucket_name = "stream.example.com"
bucket = s3.create_bucket(new_bucket_name)
object_name = "video.mp4"
key = bucket.new_key(object_name)
key.set_contents_from_filename(object_name)
2-创建一个Cloudfront“原始访问身份”
目前,只能使用API执行此步骤。Boto代码在这里:
import boto
#credentials stored in environment AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
cf = boto.connect_cloudfront()
oai = cf.create_origin_access_identity(comment='New identity for secure videos')
#We need the following two values for later steps:
print("Origin Access Identity ID: %s" % oai.id)
print("Origin Access Identity S3CanonicalUserId: %s" % oai.s3_user_id)
3-修改对象上的ACL
现在,我们已经拥有了特殊的S3用户帐户(我们在上面创建的S3CanonicalUserId),我们需要授予它访问s3对象的权限。通过打开对象的(而不是存储桶的!)权限标签,单击“添加更多权限”按钮,然后将上面获得的很长的S3CanonicalUserId粘贴到新的“
Grantee”字段中,我们可以轻松地使用AWS控制台执行此操作。确保您授予新的权限“打开/下载”权限。
您也可以使用以下boto脚本在代码中执行此操作:
import boto
#credentials stored in environment AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
s3 = boto.connect_s3()
bucket_name = "stream.example.com"
bucket = s3.get_bucket(bucket_name)
object_name = "video.mp4"
key = bucket.get_key(object_name)
#Now add read permission to our new s3 account
s3_canonical_user_id = "<your S3CanonicalUserID from above>"
key.add_user_grant("READ", s3_canonical_user_id)
4-创建一个Cloudfront发行版
请注意,直到2.0版(在撰写本文时尚未正式发布)之前,boto才完全不支持自定义来源和私有发行版。下面的代码从boto
2.0分支中提取了一些代码,并将它们砍在一起以使其正常运行,但这并不是很漂亮。2.0分支处理起来更加优雅-如果可能的话,一定要使用它!
import boto
from boto.cloudfront.distribution import DistributionConfig
from boto.cloudfront.exception import CloudFrontServerError
import re
def get_domain_from_xml(xml):
results = re.findall("<DomainName>([^<]+)</DomainName>", xml)
return results[0]
#custom class to hack this until boto v2.0 is released
class HackedStreamingDistributionConfig(DistributionConfig):
def __init__(self, connection=None, origin='', enabled=False,
caller_reference='', cnames=None, comment='',
trusted_signers=None):
DistributionConfig.__init__(self, connection=connection,
origin=origin, enabled=enabled,
caller_reference=caller_reference,
cnames=cnames, comment=comment,
trusted_signers=trusted_signers)
#override the to_xml() function
def to_xml(self):
s = '<?xml version="1.0" encoding="UTF-8"?>\n'
s += '<StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-07-15/">\n'
s += ' <S3Origin>\n'
s += ' <DNSName>%s</DNSName>\n' % self.origin
if self.origin_access_identity:
val = self.origin_access_identity
s += ' <OriginAccessIdentity>origin-access-identity/cloudfront/%s</OriginAccessIdentity>\n' % val
s += ' </S3Origin>\n'
s += ' <CallerReference>%s</CallerReference>\n' % self.caller_reference
for cname in self.cnames:
s += ' <CNAME>%s</CNAME>\n' % cname
if self.comment:
s += ' <Comment>%s</Comment>\n' % self.comment
s += ' <Enabled>'
if self.enabled:
s += 'true'
else:
s += 'false'
s += '</Enabled>\n'
if self.trusted_signers:
s += '<TrustedSigners>\n'
for signer in self.trusted_signers:
if signer == 'Self':
s += ' <Self/>\n'
else:
s += ' <AwsAccountNumber>%s</AwsAccountNumber>\n' % signer
s += '</TrustedSigners>\n'
if self.logging:
s += '<Logging>\n'
s += ' <Bucket>%s</Bucket>\n' % self.logging.bucket
s += ' <Prefix>%s</Prefix>\n' % self.logging.prefix
s += '</Logging>\n'
s += '</StreamingDistributionConfig>\n'
return s
def create(self):
response = self.connection.make_request('POST',
'/%s/%s' % ("2010-11-01", "streaming-distribution"),
{'Content-Type' : 'text/xml'},
data=self.to_xml())
body = response.read()
if response.status == 201:
return body
else:
raise CloudFrontServerError(response.status, response.reason, body)
cf = boto.connect_cloudfront()
s3_dns_name = "stream.example.com.s3.amazonaws.com"
comment = "example streaming distribution"
oai = "<OAI ID from step 2 above like E23KRHS6GDUF5L>"
#Create a distribution that does NOT need signed URLS
hsd = HackedStreamingDistributionConfig(connection=cf, origin=s3_dns_name, comment=comment, enabled=True)
hsd.origin_access_identity = oai
basic_dist = hsd.create()
print("Distribution with basic URLs: %s" % get_domain_from_xml(basic_dist))
#Create a distribution that DOES need signed URLS
hsd = HackedStreamingDistributionConfig(connection=cf, origin=s3_dns_name, comment=comment, enabled=True)
hsd.origin_access_identity = oai
#Add some required signers (Self means your own account)
hsd.trusted_signers = ['Self']
signed_dist = hsd.create()
print("Distribution with signed URLs: %s" % get_domain_from_xml(signed_dist))
5-测试您可以从Cloudfront下载对象,但不能从s3下载对象
您现在应该可以验证:
必须对测试进行调整才能与您的流播放器一起使用,但是基本思想是只有基本的Cloudfront URL应该可以使用。
6-为CloudFront创建密钥对
我认为唯一的方法就是通过亚马逊的网站。进入您的AWS“账户”页面,然后单击“安全凭证”链接。单击“密钥对”选项卡,然后单击“创建新的密钥对”。这将为您生成一个新的密钥对,并自动下载一个私钥文件(pk-
xxxxxxxxx.pem)。确保密钥文件安全和私密。还要记下亚马逊的“密钥对ID”,因为下一步将需要它。
7-在Python中生成一些URL
从boto 2.0版开始,似乎不支持生成签名的CloudFront
URL。Python在标准库中不包含RSA加密例程,因此我们将不得不使用其他库。在此示例中,我使用了M2Crypto。
对于非流媒体分发,您必须使用完整的Cloudfront
URL作为资源,但是对于流媒体,我们仅使用视频文件的对象名称。有关生成仅持续5分钟的URL的完整示例,请参见下面的代码。
此代码大致基于Amazon在CloudFront文档中提供的PHP示例代码。
from M2Crypto import EVP
import base64
import time
def aws_url_base64_encode(msg):
msg_base64 = base64.b64encode(msg)
msg_base64 = msg_base64.replace('+', '-')
msg_base64 = msg_base64.replace('=', '_')
msg_base64 = msg_base64.replace('/', '~')
return msg_base64
def sign_string(message, priv_key_string):
key = EVP.load_key_string(priv_key_string)
key.reset_context(md='sha1')
key.sign_init()
key.sign_update(str(message))
signature = key.sign_final()
return signature
def create_url(url, encoded_signature, key_pair_id, expires):
signed_url = "%(url)s?Expires=%(expires)s&Signature=%(encoded_signature)s&Key-Pair-Id=%(key_pair_id)s" % {
'url':url,
'expires':expires,
'encoded_signature':encoded_signature,
'key_pair_id':key_pair_id,
}
return signed_url
def get_canned_policy_url(url, priv_key_string, key_pair_id, expires):
#we manually construct this policy string to ensure formatting matches signature
canned_policy = '{"Statement":[{"Resource":"%(url)s","Condition":{"DateLessThan":{"AWS:EpochTime":%(expires)s}}}]}' % {'url':url, 'expires':expires}
#now base64 encode it (must be URL safe)
encoded_policy = aws_url_base64_encode(canned_policy)
#sign the non-encoded policy
signature = sign_string(canned_policy, priv_key_string)
#now base64 encode the signature (URL safe as well)
encoded_signature = aws_url_base64_encode(signature)
#combine these into a full url
signed_url = create_url(url, encoded_signature, key_pair_id, expires);
return signed_url
def encode_query_param(resource):
enc = resource
enc = enc.replace('?', '%3F')
enc = enc.replace('=', '%3D')
enc = enc.replace('&', '%26')
return enc
#Set parameters for URL
key_pair_id = "APKAIAZCZRKVIO4BQ" #from the AWS accounts page
priv_key_file = "cloudfront-pk.pem" #your private keypair file
resource = 'video.mp4' #your resource (just object name for streaming videos)
expires = int(time.time()) + 300 #5 min
#Create the signed URL
priv_key_string = open(priv_key_file).read()
signed_url = get_canned_policy_url(resource, priv_key_string, key_pair_id, expires)
#Flash player doesn't like query params so encode them
enc_url = encode_query_param(signed_url)
print(enc_url)
8-试用网址
希望您现在应该拥有一个类似于以下内容的有效网址:
video.mp4%3FExpires%3D1309979985%26Signature%3DMUNF7pw1689FhMeSN6JzQmWNVxcaIE9mk1x~KOudJky7anTuX0oAgL~1GW-ON6Zh5NFLBoocX3fUhmC9FusAHtJUzWyJVZLzYT9iLyoyfWMsm2ylCDBqpy5IynFbi8CUajd~CjYdxZBWpxTsPO3yIFNJI~R2AFpWx8qp3fs38Yw_%26Key-Pair-Id%3DAPKAIAZRKVIO4BQ
将其放入您的js中,您应该具有类似以下内容的内容(来自Amazon CloudFront文档中的PHP示例):
var so_canned = new SWFObject('http://location.domname.com/~jvngkhow/player.swf','mpl','640','360','9');
so_canned.addParam('allowfullscreen','true');
so_canned.addParam('allowscriptaccess','always');
so_canned.addParam('wmode','opaque');
so_canned.addVariable('file','video.mp4%3FExpires%3D1309979985%26Signature%3DMUNF7pw1689FhMeSN6JzQmWNVxcaIE9mk1x~KOudJky7anTuX0oAgL~1GW-ON6Zh5NFLBoocX3fUhmC9FusAHtJUzWyJVZLzYT9iLyoyfWMsm2ylCDBqpy5IynFbi8CUajd~CjYdxZBWpxTsPO3yIFNJI~R2AFpWx8qp3fs38Yw_%26Key-Pair-Id%3DAPKAIAZRKVIO4BQ');
so_canned.addVariable('streamer','rtmp://s3nzpoyjpct.cloudfront.net/cfx/st');
so_canned.write('canned');
概要
如您所见,不是很容易!boto v2将有助于大量设置发行版。我将找出是否有可能在其中获得一些URL生成代码来改进这个很棒的库!
问题内容: 我的用例如下: 我有一个仅地图的mapreduce作业,该作业需要一个输入文件,进行了大量的解析和调整,然后再写回。但是,某些行的格式可能正确也可能不正确,如果是这样,我想将原始行写入单独的文件中。 看来,执行此操作的一种方法是将文件名添加到我正在打印的行的前面,并使用multipleOutputFormat参数。例如,如果我最初有: 我可以改为: 此解决方案唯一的问题是我不希望fil
问题内容: 是否有使用Java直播视频的良好库?理想情况下,管道的两端都应使用Java编写,但我最关心的是视频播放器。您会推荐什么软件? 更新 :似乎VLC引入了1-2秒的延迟。我需要真正的实时视频流。记录到播放的延迟必须小于300ms。 问题答案: 我见过的最好的视频播放/编码库是ffmpeg。它播放您扔给它的所有内容。(它是MPlayer使用的。)它是用C编写的,但是我发现了一些Java包装器
问题内容: 目前,我正在使用NumPy从NumPy数组生成WAV文件。我想知道是否有可能在实际将NumPy数组写入硬盘之前实时播放它。我发现使用PyAudio的所有示例都依赖于首先将NumPy数组写入WAV文件,但是我想拥有一个预览功能,该功能只是将NumPy数组吐出到音频输出。 也应该跨平台。我正在使用Python 3(Anaconda发行版)。 问题答案: 这已经奏效了!感谢帮助! 现在看来是
问题内容: 我正在尝试设置一个网络服务器,该服务器将使用node.js将视频流传输到HTML5视频标签。到目前为止,这是我的代码: 其中“ request”代表http请求,类型是“ application / ogg”或“ video / ogg”(我都尝试过),而“ file”是已从文件系统读取的.ogv文件。这是响应头: 我已经检查了响应头,并且此代码似乎运行良好,但是存在两个问题: 该
稳定性: 2 - 稳定的 tls 模块是对安全传输层(TLS)及安全套接层(SSL)协议的实现,建立在OpenSSL的基础上。 按如下方式引用此模块: const tls = require('tls'); TLS/SSL 概念 TLS/SSL 是 public/private key infrastructure (PKI),大部分情况下,每个服务器和客户端都应该有一个私钥。 私钥能有多种生成
新手提问: 前后端只使用http协议,一般用户登录注册账号和密码该如何进行安全传输?一般使用的方法有哪些呀?