AWS default Access Policy SNS topics and SQS q's - amazon-web-services

In an attempt to further tighten the security of our solution we are now looking at the used SNS topics and SQS queues. All our components live in the same AWS account.
For starters we want to restrict the access to the SQS queues based on IP. So only requests coming from our NAT Gateway IP will be allowed. We don't allow anonymous access to our SQS queues.
But there seems no way to achieve this as the creator of the SQS queues - the AWS account id - has access per default. So you can't create an effective permission for another user in the same AWS account id. As this newly created user, user2, will fall under the same AWS account id, with the same set of permissions.
Am I correct in my understanding that all users in the same AWS account id have access per default to all created SQS queues as long as their IAM policy permits it? And is my assumption right that the same behavior goes for the SNS topics?
Below is the policy I would like the implement. Beside this policy I have no other policies active for this SQS q. But it is not honoring the source IP condition. I still can connect from everywhere when I use a correct AWS access key/secret combination. Only when I set the AWS principal to * - everyone - the policy seems effective.
{
"Version": "2012-10-17",
"Id": "arn:aws:sqs:eu-west-1:4564645646464564:madcowtestqueue/SQSDefaultPolicy",
"Statement": [
{
"Sid": "Sid1589365989662",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::4564645646464564:user/user2"
},
"Action": [
"SQS:DeleteMessage",
"SQS:SendMessage",
"SQS:ReceiveMessage"
],
"Resource": "arn:aws:sqs:eu-west-1:143631359317:madcowtestqueue",
"Condition": {
"IpAddress": {
"aws:SourceIp": "1.1.1.1"
}
}
}
]
}
Reference:
Using identity-based policies with Amazon SQS - Amazon Simple Queue Service
Using identity-based policies with Amazon SNS - Amazon Simple Notification Service

Amazon SQS
Amazon SQS has the ability to define Amazon SQS policies. These policies can be used in addition to IAM policies to grant access to a queue.
For example, a policy can be added that permits anonymous access to a queue, which is useful for external applications to send messages to the queue.
Interestingly, these policies can also be used to control access to the queue by IP address.
To test this, I did the following:
Created an Amazon SQS queue
Used an Amazon EC2 instance to send a message to the queue -- Successful
Added the following policy to the SQS queue:
{
"Version": "2012-10-17",
"Id": "Queue1_Policy_UUID",
"Statement": [
{
"Sid": "Queue1_AnonymousAccess_AllActions_IPLimit_Deny",
"Effect": "Deny",
"Principal": "*",
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:ap-southeast-2:xxx:queue",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "54.1.2.3/32"
}
}
}
]
}
The IP address is that of my Amazon EC2 instance.
I then tried send a message to the queue again from the EC2 instance -- Successful
I then ran the identical command from my own computer -- Not successful
Therefore, it would appear that the SQS policy can override the permissions granted via IAM.
(Be careful... I added a policy that Denied sqs:* on the queue, and I wasn't able to edit the policy or delete the queue! I had to use the root account to delete it.)
Amazon SNS
I managed to achieve the same result with Amazon SNS using this access policy:
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:ap-southeast-2:xxx:topic",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": "54.1.2.3/32"
}
}
}
]
}

Related

Why do some AWS services require the requestor to have IAM policies?

Like connecting Lambda to SNS, for example.
I tried setting up a SNS TopicPolicy that allows publishing to SNS from my VPC cidr group. This didn't work and required me to make a SNS Publish action role and attach that to the Lambda instead.
I would have guessed that the action denial was on the service, and not the requestor, but that doesn't seem to be the case.
It looks like this behavior just depends on the service.
In the case of SNS, the default permission is to allow access to the topic from all services in your account: Example cases for Amazon SNS access control. I agree with you that this important point should be a bit more obviously stated..
Amazon SNS grants a default policy to all newly created topics. The default policy grants access to your topic to all other AWS services. This default policy uses an aws:SourceArn condition to ensure that AWS services access your topic only on behalf of AWS resources you own.
Here's what the default policy looks like if you're curious. Notice that the Principal is *.
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "arn:aws:sns:XXX:XXXX:testTopic",
"Condition": {
"StringEquals": {
"AWS:SourceOwner": "XXXX"
}
}
}
]
}
With Lambda, however, you need to explicitly grant access permissions when working with other services.

Restrict access to S3 static website that uses API Gateway as a proxy

I have an S3 bucket that acts as a static website and I am using API Gateway to distribute traffic to it. I understand CloudFront is a better option here, but please do not suggest it. It is not an option, due to reasons I won't go into.
I am accomplishing my solution by configuring a {proxy+} resource. Image below:
I would like to only allow access to the S3 website from the API Gateway proxy resource. Is there a way I can provide an execution role to the proxy resource, similarly to how you can provide an execution role to a resource to runs a lambda function? Lambda execution role example below:
The integration request portion of the proxy resource doesn't seem to have an execution role:
Or is there a way I can assign a role to the entire API Gateway to provide it the right to access the S3 bucket?
Other things I have tried:
Editing the bucket policy to only allow traffic from the API gateway service:
{
"Version": "2012-10-17",
"Id": "apiGatewayOnly",
"Statement": [
{
"Sid": "apiGW",
"Effect": "Allow",
"Principal": {
"Service": ["api-gateway-amazonaws.com"]
},
"Action": "s3:GetObject",
"Resource": "http://test-proxy-bucket-01.s3-website.us-east-2.amazonaws.com/*"
}
]
}
Editing the bucket policy to only allow traffic from API Gateway's URL:
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "",
"Action": "s3:GetObject",
"Resource": "http://test-proxy-bucket-01.s3-website.us-east-2.amazonaws.com/",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://xxxxxxx.execute-api.us-east-2.amazonaws.com/prod/",
"http://xxxxxxxx.execute-api.us-east-2.amazonaws.com/prod"
]
}
}
}
]
}
Create a private S3 bucket
Create an IAM role that can access the bucket. Set the trusted entity/principal who can assume this role to apigateway.amazonaws.com
Use AWS service integration type and select s3. Set the execution role to the role created in 2
Refer to docs for more details.

How to create an IAM Policy for SQS queues for a specific Cognito Identity

I am trying to create a IAM policy to be applied to a SQS queue. The policy should restrict access to the queue to a single Cognito federated identity.
I found this reference from amazon on how to achieve this but am having trouble applying the policy to the SQS queue.
Here is the policy I am trying to apply.
{
"Version": "2012-10-17",
"Id": "arn:aws:sqs:us-west-2:604080725100:Test2.fifo/SQSDefaultPolicy",
"Statement": [
{
"Sid": "Sid1528133390193",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "SQS:*",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:ff1b33f4-7f66-47a5-b7ff-9696b0e1fb52",
"cognito-identity.amazonaws.com:sub": ["us-east-1:4a6d7e43-4522-41fb-9248-b5b79933b8e9"]
}
}
}
]
}
The online UI for editing the policy shows in the review screen:
Allow None
All SQS Actions (SQS:*)
StringEquals
cognito-identity.amazonaws.com:aud: "us-east-1:ff1b33f4-7f66-47a5-b7ff-9696b0e1fb52"
cognito-identity.amazonaws.com:sub: "us-east-1:4a6d7e43-4522-41fb-9248-b5b79933b8e9"
Once I press apply the following error is given:
Failed to save changes to the policy document. Reason: com.amazonaws.services.sqs.model.AmazonSQSException: We encountered an internal error. Please try again.
I am not sure what is wrong with the policy. I am looking for any help fixing the policy or a different policy that achieve limiting the SQS queue to a single Cognito identity.
Unfortunately SQS only supports a subset of the condition keys and the cognito user id is not one of them. I have read an article which solved this problem by creating random queue names which are readable by all users, but practically unguessable.

AWS security group rules deployment (lambda->SQS)

On AWS we've implemented functionality that AWS lambda pushes message to AWS queue;
However during this implementation I had to manuall grant permissions to AWS lambda to add message to particular queue. And this apporach with manual clicks not so good for prod deployment.
Any suggestions how to automate process of adding permissions between AWS services (mainly lambda and SQS) and cretate "good" deployment package for prod env ?
Each Lambda function has an attached role, which you can specify permissions for in the IAM dashboard. If you give the Lambda functions' role the permission to push to an SQS queue, you're good to go. For example, attach this JSON as a custom role (see http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/SQSExamples.html):
{
"Version": "2012-10-17",
"Id": "Queue1_Policy_UUID",
"Statement":
{
"Sid":"Queue1_SendMessage",
"Effect": "Allow",
"Principal": {
"AWS": "111122223333"
},
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:444455556666:queue1"
}
}
You can use asterisks to give permission to multiple queues, like:
"Resource": "arn:aws:sqs:us-east-1:444455556666:production-*"
To give sendMessage permission to all queues that start with production-.

Accessing AWS SQS running under different AWS root account

Background:
My application reads from a AWS SQS queue. I have all my AWS Resources under one AWS account [not IAM user accounts but main AWS root account].
Question:
I have to access the SQS queue which is created under an AWS account that is different from account for all my AWS resources. My question is will this work.
I only have one account to experiment with and cannot test the scenario my self.
Any help is appreciated.
Cheers.
Yes, permission can be granted to allow a different AWS account to push messages to your SQS queues.
See: Amazon SQS Policy Examples
It is simple to create another AWS account if you wish to test this process. You can even link your accounts via Consolidated Billing. There is no charge for an additional account.
Yes its possible:
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-creating-custom-policies-access-policy-examples.html
You just specify correct policy!
For example:
{
"Version": "2012-10-17",
"Id": "UseCase2",
"Statement" : [{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"111122223333",
"444455556666"
]
},
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:us-east-2:444455556666:queue2",
"Condition": {
"DateLessThan": {
"AWS:CurrentTime": "2009-06-30T12:00Z"
}
}
}]
}
Enjoy!