0

In our environment, all IAM user accounts are assigned a customer-managed policy that grants read-only access to a lot of AWS services. Here's what I want to do:

  • Migrate a sql server 2012 express database from on-prem to a RDS instance
  • Limit access to the S3 bucket containing the database files

Here's the requirements according to AWS:

  • A S3 bucket to store the .bak database file
  • A role with access to the bucket
  • SQLSERVER_BACKUP_RESTORE option attached to RDS instance

So far, I've done the following:

  • Created a bucket under the name "test-bucket" (and uploaded the .bak file here)
  • Created a role under the name "rds-s3-role"
  • Created a policy under the name "rds-s3-policy" with these settings:

    {
        "Version": "2012-10-17",
        "Statement": [
         {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": "arn:aws:s3:::test-bucket/"
         },
         {
            "Effect": "Allow",
            "Action": [
                "s3:GetObjectMetaData",
                "s3:GetObject",
                "s3:PutObject",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": "arn:aws:s3:::test-bucket/*"
         }
        ]
    }
    
  • Assigned the policy to the role

  • Gave the AssumeRole permissions to the RDS service to assume the role created above
  • Created a new option group in RDS with the SQLSERVER_BACKUP_RESTORE option and linked it to my RDS instance

With no restrictions on my S3 bucket, I can perform the restore just fine; however, I can't find a solid way of restricting access to the bucket without hindering the RDS service from doing the restore.

In terms of my attempts to restrict access to the S3 bucket, I found a few posts online recommending using an explicit Deny statement to deny access to all types of principals and grant access based on some conditional statements.

Here's the contents of my bucket policy:

    {
        "Version": "2012-10-17",
        "Id": "Policy1486769843194",
        "Statement": [
            {
                 "Sid": "Stmt1486769841856",
                 "Effect": "Deny",
                 "Principal": "*",
                 "Action": "s3:*",
                 "Resource": [
                     "arn:aws:s3:::test-bucket",
                     "arn:aws:s3:::test-bucket/*"
                 ],
                 "Condition": {
                     "StringNotLike": {
                         "aws:userid": [
                             "<root_id>",
                             "<user1_userid>",
                             "<user2_userid>",
                             "<user3_userid>",
                             "<role_roleid>:*"
                         ]
                     }
                 }
             }
         ]
     }

I can confirm the bucket policy does restrict access to only the IAM users that I specified, but I am not sure how it treats IAM roles. I used the :* syntax above per a document I found on the aws forums where the author stated the ":*" is a catch-all for every principal that assumes the specified role.

The only thing I'm having a problem with is, with this bucket policy in place, when I attempt to do the database restore, I get an access denied error. Has anyone ever done something like this? I've been going at it all day and haven't been able to find a working solution.

Niag Ntawv
  • 197
  • 1
  • 4
  • 16
  • This might help: [Granting access to S3 resources based on role name](http://stackoverflow.com/questions/35711816/granting-access-to-s3-resources-based-on-role-name) – John Rotenstein Feb 12 '17 at 02:41
  • i think that's consistent with what i tried above already....im wondering if the problem is something with the RDS service trying to assume the role that i created.. – Niag Ntawv Feb 12 '17 at 07:01

1 Answers1

0

The following, admittedly, is guesswork... but reading between the lines of the somewhat difficult to navigate IAM documentation and elsewhere, and taking into account the way I originally interpreted it (incorrectly), I suspect that you are using the role's name rather than the role's ID in the policy.

Role IDs look similar to AWSAccessKeyIds except that they begin with AROA....

For the given role, find RoleId in the output from this:

$ aws iam get-role --role-name ROLE-NAME

https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/

Use caution when creating a broad Deny policy. You can end up denying s3:PutBucketPolicy to yourself, which leaves you in a situation where your policy prevents you from changing the policy... in which case, your only recourse is presumably to persuade AWS support to remove the bucket policy. A safer configuration would be to use this to deny only the object-level permissions.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • I am using the RoleID that i retrieve from using the aws command you listed above. In fact, i think that document you linked is the one i was following. I may try the object level permissions method and see how that works. – Niag Ntawv Feb 11 '17 at 21:40
  • D'oh. Sorry about that, @NiagNtawv. I thought about asking the question as a comment and then, since I really don't see what the problem, otherwise, I decided that this might be the most likely explanation. You might enable the bucket logs to ensure that what gets logged and denied is the action you intended, if you haven't tried that. – Michael - sqlbot Feb 11 '17 at 21:44