0
votes

So I have My project running on server on ec2 instance, and it uses SES to send emails. I was able to send the emails when the SES was accessible by public, but when I tried to implement security, it started giving problems. I have attached the following identity policies to the SES email address, one blocks the access publicly and another one allows the ec2 to access the SES email address. But I'm always getting blocked with the error:

The email was not sent.Error message: User `arn_of_ec2_role' is not authorized to perform 
`ses:SendEmail' on resource `arn_of_email_address' (Service: AmazonSimpleEmailService; 
Status Code: 403; Error Code: AccessDenied; 
Request ID: b92h2a02-4502-32g8-8334-9504941fdefd4e35)

My policies are:

To allow ec2:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "stmt8473824324",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn_of_role_used_by_ec2"
            },
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn_of_email"
        }
    ]
}

To deny public:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
      "Resource": "arn_of_email"
    }
  ]
}

Edit 1: Turns out I just had to add the encasing {} to "AWS": "arn_of_role_used_by_ec2". But even then I'm not getting permissions. I'm still getting the same error. To verify, I even used an user policy and tried to access it using that user, but even then I get the same error, just with different arn being denied now. My policy is as follows:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "arn_of_role_used_by_ec2"
            },
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn_of_email"
        }
    ]
}

Edit2:

Sorry for the late reply, following is what I did to as per Your update:

    {
        "Version": "2008-10-17",
        "Statement": [
            {
                "Sid": "stmt1476011587135",
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                    "ses:SendEmail",
                    "ses:SendRawEmail"
                ],
                "Resource": "arn_of_email",
                "Condition": {
                    "StringEquals": {
                        "aws:SourceArn": "arn_of_ecs_instance"
                    }
                }
            }
        ]
    }

and

    {
        "Version": "2008-10-17",
        "Statement": [
            {
                "Sid": "stmt1476011639899",
                "Effect": "Deny",
                "Principal": "*",
                "Action": [
                    "ses:SendEmail",
                    "ses:SendRawEmail"
                ],
                "Resource": "arn_of_email",
                "Condition": {
                    "StringNotEquals": {
                        "aws:SourceArn": "arn_of_ecs_instance"
                    }
                }
            }
        ]
    }

Used arn_of_ecs_instance since I was just verifying with the IAM user and needed the access for only the ec2 instance. But still I'm able to send the email address via java API while sending mail with My IAM user credentials.

1
Try serting your resource in all policies to *.Matt Houser
@MattHouser I tried that, but I get the error Error while applying policy: Invalid ARN: ARNs must start with 'arn:': * (Request ID: 4b922926-83e8-11e6-8845-5946c19d3615) since I'm attaching the policy to the specific email address. I even tried "Resource": "arn:aws:ses:us-east-1:453679034254:identity/*" I get the error Error while applying policy: Expected the resource to be 'arn_of_email' but was 'arn:aws:ses:us-east-1:453679034254:identity/*'.Mirhawk

1 Answers

0
votes

A "Deny" rule will always overrule an "Allow" rule.

This is what is happening with your two policies: the Deny public rule is overriding the Allow rule for your IAM role because your EC2 role falls under both policies.

So you need the following:

  1. One "Allow" rule to allow who you want to allow, and
  2. One "Deny" rule to deny everyone but whom you want to allow.

The other catch is that using IAM roles with these types of policies are difficult because both the IAM role and the principal using the role need to be whitelisted.

Instead, you can use conditions in your statements to allow the IAM role's "userid".

First, you need to get your IAM role's unique ID. This is not displayed in the AWS Management Console. Using the AWS CLI, do the following:

aws iam get-role --role-name my-role

From this output, grab the value from the RoleId property. It's value will look something like this: "AROAID2GEXAMPLEROLEID".

Next, the a policy like the following to allow the role to use the email address:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "stmt1474900930602",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn_of_email",
            "Condition": {
                "StringLike": {
                    "aws:userid": "AROAID2GEXAMPLEROLEID:*"
                }
            }
        }
    ]
}

Note, replace the "AROAID2GEXAMPLEROLEID" with your actual RoleId value.

This will allow anyone assuming your role to send from your email address.

Finally, use the following policy to deny anyone not assuming your role:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "stmt1474900930602",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "arn:aws:ses:us-east-1:905741729283:identity/[email protected]",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": "AROAID2GEXAMPLEROLEID:*"
                }
            }
        }
    ]
}

Again, replace "AROAID2GEXAMPLEROLEID" with your actual RoleId value.

Once you have these in place, your desired EC2 instance will be permitted, and everyone else will be denied.