amazon aws bucket policy to let my ec2 server get files programmatically - amazon-s3

It seems like I should be able to make a rule to allow access from my ec2's elastic ip. Here is the code I have:
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::big18v1/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "12.123.12.123"
}
}
}
]
}
but.. it doesn't work. I get 'access denied'
any thoughts? I've read over and over about creating iam roles and things like that, but I don't really want to manipulate the bucket files... I just want to use the bucket like a server and get image files from it.
Am I thinking about this right? How should I let only my ec2 instance have access to my s3 bucket?

You should create an IAM role with access to the bucket, then use instance profiles to make the credentials available to the instances
http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html

Related

ECS task accessing S3 bucket website with Block Public Access enabled: "Access Denied"

I have an ECS task configured to run an nginx container that I want to use as a reverse proxy to a S3 bucket website.
For security purposes, Block public access is turned on for the bucket so I am looking for a way to give Read access only to the ECS task.
I want my ECS task running an nginx reverse proxy to have S3:GetObjects access to my website bucket. The bucket cannot be public so I want to restrict it to the ecs task using the ecs task IAM role as Principal.
IAM role:
arn:aws:iam:::role/ was configured with an attached policy that allows all S3 actions in the bucket and its objects:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "S3:*",
"Resource": [
"arn:aws:s3:::<BUCKET>",
"arn:aws:s3:::<BUCKET>/*"
]
}
]
}
In Trusted Entities, I added permission to assume the ECS Task role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
The issue is that the EC2 target group health check is always returning Access Denied to the bucket and its objects.
[08/Jun/2020:20:33:19 +0000] “GET / HTTP/1.1” 403 303 “-“ “ELB-HealthChecker/2.0”
I also tried to give it permission to by adding the bucket policy below, but I believe it is not needed as the IAM role already have access to it…
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "allowNginxProxy",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::<BUCKET>/*",
"arn:aws:s3:::<BUCKET>"
]
}
]
}
I have also tried using ”AWS": "arn:aws:iam::<ACCOUNT_NUMBER>:role/<ECS_TASK_ROLE>" as Principal.
Any suggestions?
Another possibility here:
Check if your S3 Objects are encrypted? If yes, your ECS Task Role should also have the permission to perform decryption. Otherwise, you would also get permission denied exception. One example can be found here.

Amazon S3: Grant anonymous access from IP (via bucket policy)

I have a Amazon S3 bucket and would like to make it available to scripts on a certain machine, whithout the need to deploy login credentials. So my plan was to allow anonymous access only from the IP of that machine. I'm quite new to the Amazon cloud and bucket policies look like the way to go. I added the following policy to my bucket:
{
"Version": "2008-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::name_of_my_bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"my_ip_1/24",
"my_ip_2/24"
]
}
}
}
]
}
But anonymous access still does not work. For testing, I granted access to "Everyone" in the S3 management console. That works fine, but is obviously not what I want to do. ;-) Any hint what I'm doing wrong and how to get this working?
My use case is some data processing using EC2 and S3, so access control by IP would be much simpler than fiddling around with user accounts. If there's a simpler solution, I'm open for suggestions.
But anonymous access still does not work.
What operation still does not work exactly, do you by chance just try to list the objects in the bucket?
Quite often a use case implicitly involves Amazon S3 API calls also addressing different resource types besides the Resource explicitly targeted by the policy already. Specifically, you'll need to be aware of the difference between Operations on the Service (e.g. ListAllMyBuckets), Operations on Buckets (e.g. ListBucket) and Operations on Objects (e.g. GetObject).
In particular, the Resource specification of your policy currently addresses the objects within the bucket only (arn:aws:s3:::name_of_my_bucket/*), which implies that you cannot list objects in the bucket (you should be able to put/get/delete objects though in case) - in order to also allow listing of the objects in the bucket via ListBucket you would need to amend your policy as follows accordingly:
{
"Version": "2008-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
// ... your existing statement for objects here ...
},
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::name_of_my_bucket",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"my_ip_1/24",
"my_ip_2/24"
]
}
}
}
]
}

Amazon S3 Bucket Policy For Protected Download

I would like to write an S3 bucket policy that would restrict public access to all items in the buckets and only allow downloads done using the AWS REST interface with which the Key and Shared Secret is passed. Any examples or help in writing such a policy would be greatly appreciated.
How about this?
{
"Id": "Policy1365979145718",
"Statement": [
{
"Sid": "Stmt1365979068994",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mybucket",
"Principal": {
"AWS": [
"CanonicalUser: 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be"
]
}
}
]
}
Make a user for just this purpose (give out that user's key) and replace the CanonicalUser ID with the ID of that user. Of course you'll always have full access using the AWS account's root key.
Amazon has a Policy Generator if you want to use it.

amazon s3 video files accessible only from my domain/server?

Now, I know that I cannot stop someone from downloading my videos and sharing, however I would prefer to have it to so that people do not copy paste links directly to my bucket. Thus, is there a way to make my bucket accessible only from my server/domain making the request?
If it helps, I'm using jwplayer which loads from a xml playlist that has all the links. This playlist definitely can be opened and viewed from anywhere and is where I expect the easy copy and paste comes from.
I don't want to mask the urls because that means my bucket is readable to everyone. There is probably some chance that someone will find the url of my bucket and the name of the files and connect everything together...
This is possible by Using Bucket Policies, which allows you to define access rights for Amazon S3 resources - there are a couple of Example Cases for Amazon S3 Bucket Policies illustrating the functionality, and amongst these you'll find an example for Restricting Access to Specific IP Addresses as well:
This statement grants permissions to any user to perform any S3 action
on objects in the specified bucket. However, the request must
originate from the range of IP addresses specified in the condition.
Depending on the specifics of your use case, a bucket policy for this might look like so:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/*",
"Condition" : {
"IpAddress" : {
"aws:SourceIp": "192.168.143.0/24"
},
"NotIpAddress" : {
"aws:SourceIp": "192.168.143.188/32"
}
}
}
]
}
As shown the aws:sourceIp value for parameters IPAddress and NotIpAddress is expressed in CIDR notation, enabling respective flexibility for composing the desired scope.
Finally, you might want to check out the recommended AWS Policy Generator, select type S3 Bucket Policy and explore the available Actions and Conditions to compose more targeted policies for your use case eventually - the documentation for Conditions explains this in detail.
The Ip address will help if your server going to access your bucket. But JWPlayer is from client side. So the request is directly goes from jwplayer(browser) to s3 bucket url, Not via your server. In this case "referrer bucket policy" will help you in this.
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::yourbucketname/*",
"Condition": {
"StringNotLike": {
"aws:Referer": [
"http://yoursitename.com/*",
"http://*.yoursitename.com/*"
]
}
}
}
]
}
So now s3 will allow if that request come from your site only.
You can have your bucket protected, which is by default the way it is. (meaning you only have access to objects in it) Then you can request files from Amazon S3 from your website and give it a time limit to which the user can see it.
//set time so that users can see file for 1 minute. then it is protected again.
$response = $s3->get_object_url(YOUR_A3_BUCKET, PATH/TO/FILE, '1 minutes');
This will automatically give you a url that has parameters associated with it which only is accessible for 1 minute. You can use that as your source within your website and then they could not copy and paste it into the browser after that 1 minute.
You can read more about this at the Amazon SDK for PHP
Restricting Access to a Specific HTTP Referrer
Suppose you have a website with domain name (www.example.com or example.com) with links to photos and videos stored in your Amazon S3 bucket, examplebucket. By default, all the Amazon S3 resources are private, so only the AWS account that created the resources can access them. To allow read access to these objects from your website, you can add a bucket policy that allows s3:GetObject permission with a condition, using the aws:referer key, that the get request must originate from specific webpages. The following policy specifies the StringLike condition with the aws:Referer condition key.
http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html
For everyone who is stumbling upon this now, please take note that Amazon has changed the JSON format for the bucket policies and now requires each allowed / denied IP or domain to be listed separately. See below for an example.
Either way, I strongly recommend to use the AWS Policy Generator to make sure your formatting is correct.
AWS S3 Bucket Policy - Allow Access only from multiple IPs
{
"Id": "Policy1618636210012",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1618635877058",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/folder/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "333.444.555.666"
}
},
"Principal": "*"
},
{
"Sid": "Stmt1618636151833",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/folder/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "222.333.444.555"
}
},
"Principal": "*"
},
{
"Sid": "Stmt1618636203591",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/folder/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "111.222.333.444"
}
},
"Principal": "*"
}
]
}

How to allow aws s3 bucket contents only to publicly serve a certain domain?

I am using aws s3 to store my website pictures and video contents. File links from s3 are directly output to html/php.
The problem is that some other sites linked my picture/video, which heavily increased s3 traffic usage, and off course increased the pay bill.
I know in some case people use referer header to prohibit external sites linking. But in this case, picture/video go out directly from s3, not my domain.
Can some one help to achieve this? Thanks.
You can use Amazon bucket policy like :
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originated from www.example.com and example.com",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.example.com/*",
"http://example.com/*"
]
}
}
}
]
}
which is explained in detail at : http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html