Greetings,

My how time flys. Jorrit & Heshan have been busy! Glad to see so much progress being made.

Question- Should the S3 CNAME / CDN field pass the new prefix to the player so that the media is called from CloudFront instead of directly from the bucket? Or did we skip over some more player integrations? We have seen the JW Player CloudFront integration for Streaming, and see that we may need to provide an extra VAR for RTMP, but should not for standard non-dynamic downloads.

We have Video, Zencoder & AWS SDK (with signed URLS) working swimmingly, but have noticed a lag with some of the larger videos, so we thought we would take advantage of the CloudFront CDN option i the AWS SDK, and it would re-form the links passed to the Video module to have the CloudFront distribution as the reference. We created a download distribution (we want to stay iOS firendly till we can figure out how to trick JW Player for D7 to player RTMP in flash & download for iOS) and set the domain name in the CDN area of the S3 settings, as well as configured the distribution to pull from the S3 bucket and use all the right credentials, as well as sign URLs.

Check with you folks first, as you know best how the media URL is stored and passed to the player. We will bounce this over to the S3 / AWS SDK side depending on your response.

Cheers, and thanks again for the amazing work.

- Josh

Comments

Jorrit’s picture

I think the streaming mode of CloudFront is not supported by the Video module, but I only tried with HTML5 based players and RTMP is not supported by the <video> tag. Maybe if you use JW Player with Flash, it works. I don't know of a way to have download for one device and streaming for the other. Maybe you can create two CloudFront distributions and use a custom tpl.php to choose between them. It is just a matter of changing the hostname part of the URL, so it should be possible with some string replacements.

jhrizz’s picture

Thank you Jorrit!

We are perfectly happy sticking with download only w/ HTML5 players... We have entered the distribution domain in the CNAME / CDN field- What else do you feel would we need to do to get the Video module to use CloudFront?

Thank you!

- Josh

jhrizz’s picture

Update-

We have set nearly everything we can find between AWS and Drupal to push things toward using CloudFront for content access. We have only one distribution, and it is download style. We have added CNAMEs, removed CNAMES, done everything we could, but alas, Video pulls direct from the S3 bucket.

Additionally- While the bucket ACLs only allow Zencoder and my AWS API Identity, all of the media is being transferred from Zendcoder and set to public read / EVERYONE has Open/Download permissions- this is a bit of an issue when the intention is to use signed URLs. The signed URLs work, but one can just delete the signature and the video plays. Doh!

I attempted switching the AWS ACL variable from PUBLIC to PRIVATE, but it does not seem to matter. Perhaps Zencoder is setting the ACL on the file when it uploads it?

BTW- Everything works perfectly if we go through and modify the ACLs on every file manually, but life it too short for that.

Ideas?

Jorrit’s picture

CNAMEs and signed URLs do not work together, as I recall. The URL signature is interpreted by S3, not by CloudFront.

Also, please change the "version" property of this issue to the one you are using.

jhrizz’s picture

Version: master » 7.x-2.8
jhrizz’s picture

This is a workaround to what seems like Zencoder posting with wrong ACLs... A bucket policy to prevent hotlinking. Uploads and transcodes work fine as long as Zencoder is granted at the ACL level (not in a policy).

{
 "Version":"2008-10-17",
 "Id":"",
 "Statement":[{
   "Sid":"Allow my domains",
   "Effect":"Allow",
   "Principal":{
    "AWS":"*"
   },
   "Action":"s3:GetObject",
   "Resource":"arn:aws:s3:::YOUR-BUCKET-NAME/*",
   "Condition":{
    "StringLike":{
     "aws:Referer":["http://your-domain-name/*",
      "http://www.your-domain-name/*"
     ]
    }
   }
  },
  {
   "Sid":"Disallow other domains",
   "Effect":"Deny",
   "Principal":{
    "AWS":"*"
   },
   "Action":"s3:GetObject",
   "Resource":"arn:aws:s3:::YOUR-BUCKET-NAME/*",
   "Condition":{
    "StringNotLike":{
     "aws:Referer":["http://your-domain-name/*",
      "http://www.your-domain-name/*"
     ]
    }
   }
  }
 ]
}
jhrizz’s picture

Title: Cloudfront with Amazon S3 & AWS SDK? » Amazon S3, AWS SDK, Zencoder & Private URLS
Category: support » bug

Update! - Renamed the thread to better identify the issue and turned it in to a bug as there it presents a content security issue (see below).

First, the bucket policy above only works with Flash based players (that send a referrer). HTML5 based players don't send the referrer (in all browsers?), so the policy results denies access. Use with caution.

But- Here is where the "bug" part comes in.

If site admins wish to use the Video module in combination with Zencoder and Amazon S3, and also wish to use signed URLs, this is implies that they wish to secure the content, protecting it from public access. By default, all files placed in an S3 bucket will be private, accessible only via API calls (which the S3 & AWS SDK does on behalf of Drupal in the case of signed URLs).

Currently, the TranscoderAbstractionFactoryZencoder.inc file sends a hard coded "Public" as the permission of all Zencoder results published to S3. If one wishes to use signed URLs via S3 (wanting privacy), Zencoder will write the files back as public (readable without signed URLs) which negates the site admins intention when they chose signed URLs.

Without exposing the public / private option to the site admin, videos transcoded via Zencoder and placed in directories that the admin defined as secure will be publicly available via the direct URL, with no signature.

Pretty sure this is left over from before the Video module was able to support signed URLs, where everything had to be "public" in order for Drupal to access it. Now that Drupal + S3 can create the signed URL to pass to Drupal + Video upon request, we can keep things private and let Drupal + S3 do its job.

To fix as a hack, change line 126 of TranscoderAbstractionFactoryZencoder.inc from this:

$this->options['output']['public'] = 1;

To This:

$this->options['output']['public'] = 0;

A simple fix could be to expose the public private switch on the Zencoder profile settings page. A potential issue could be if users wish to pick and choose which directory to protect with signed URLs to protect, (60|mydir/*) and they do not keep a close eye on which directories they are putting videos created with the Zencoder profile with the private setting, or they will have files set to private, with Drupal + S3 not creating the signed URLs to allow access, this resulting in an error. A risk that can be addressed in a warning under the Signed URLs notice in the S3 module, and under the switch in the Zencoder profile.

Jorrit’s picture

Status: Active » Postponed (maintainer needs more info)

I have added an option to use private S3 files to the Advanced Zencoder options. Within 12 hours there will be a new 7.x-2.x-dev release. Could you test it and let me know your experience?

jhrizz’s picture

Will do. Thanks!

jhrizz’s picture

The fix works great! Private permissions were respected. Thank you!

Jorrit’s picture

Status: Postponed (maintainer needs more info) » Fixed

Thanks for checking.

fugazi’s picture

I do not understand on what folder I want to access? Presigned URLs Drupal or amazon. how hot it was?
Sorry for my bad English

regards

(60|????/*)

I get it out of the folder to s3 "video". Thank you

Tsubo’s picture

Been reading the latest developments on this and had opened a new issue at http://drupal.org/node/1844624 - but will cross post here because it seems relevant.

Should the public/private control not be at the file field (as per Core handling of file fields) rather than at a global transcoder level?

Ideally we are looking for a system that would allow file access permissions to reflect node access permissions, or at very least have different file fields for public/private content - or the ability to change these permissions ad-hoc i.e. if a video attached to a publicly accessible node, the video would also be accessible. If the node required authentication for access, then the file would also require authentication.

Anyone have any ideas?

Thanks in advance.

Jorrit’s picture

Drupal can't control access on S3 because it is not inbetween the browser and S3. If a node would be only visible for a certain group of users, there is no way of limiting access to S3 to these users because S3 doesn't know about the users. The only option is to use private files, which adds to every file URL a time-limited token. When this token is generated by Drupal, S3 assumes access is allowed. It is no problem to make all files private when the files are only accessed via Drupal, because for every page view, a valid token will be generated. I understand from you that you want some fields to have public files, such that they can also be accessed from outside Drupal?

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.