Book Image

AWS Security Cookbook

By : Heartin Kanikathottu
Book Image

AWS Security Cookbook

By: Heartin Kanikathottu

Overview of this book

As a security consultant, securing your infrastructure by implementing policies and following best practices is critical. This cookbook discusses practical solutions to the most common problems related to safeguarding infrastructure, covering services and features within AWS that can help you implement security models such as the CIA triad (confidentiality, integrity, and availability), and the AAA triad (authentication, authorization, and availability), along with non-repudiation. The book begins with IAM and S3 policies and later gets you up to speed with data security, application security, monitoring, and compliance. This includes everything from using firewalls and load balancers to secure endpoints, to leveraging Cognito for managing users and authentication. Over the course of this book, you'll learn to use AWS security services such as Config for monitoring, as well as maintain compliance with GuardDuty, Macie, and Inspector. Finally, the book covers cloud security best practices and demonstrates how you can integrate additional security services such as Glacier Vault Lock and Security Hub to further strengthen your infrastructure. By the end of this book, you'll be well versed in the techniques required for securing AWS deployments, along with having the knowledge to prepare for the AWS Certified Security – Specialty certification.
Table of Contents (12 chapters)

Creating S3 access control lists

In this recipe, we will learn to grant permissions to the public (everyone) using ACLs from a console, using predefined groups from the CLI, and using canned ACLs from the CLI. ACLs can be used to grant basic read/write permissions to buckets, objects, and their ACLs. ACL grantees can be either an AWS account or a predefined group.

Getting ready

We need a working AWS account with the following resources configured:

  1. A bucket with a file: I will be using a bucket name awsseccookbook with a file named image-heartin-k.png. Replace these with your own bucket name and filename.
  2. A user with no permission and a user with administrator permission: Configure CLI profiles for these users. I will name users and their profiles testuser and awssecadmin, respectively.
It is good practice to add users to groups and give permissions to these groups instead of directly assigning permissions to users.
    1. Uncheck the two Block all public access settings related to ACLs. Leave the other settings checked and click Save:

    We can manage block public access settings for a bucket by going to Block public access under the bucket's Permissions tab. We can also manage these settings at account level from the S3 dashboard sidebar.

    How to do it...

    We will discuss various usages of S3 ACLs in this section.

    Granting READ ACLs for a bucket to everyone from the console

    Perform the following steps to allow everyone to list the bucket's contents:

    1. Go to the S3 service in the console.
    2. Go to the Access Control List tab under the bucket's Permissions tab of the bucket, click on Everyone, select List objects, and then click Save.
    1. Access the bucket from the browser and we should be able to list the contents of the bucket:

    Next, we will learn to grant READ for AWS users using predefined groups.

    Granting READ for AWS users using predefined groups from the CLI

    We can grant READ for any AWS user using the AuthenticatedUser predefined group by performing the following steps:

    1. If you followed along with the previous section, remove the List objects permission for the bucket that was granted to Everyone.
    2. Create a policy that grants access to the AuthenticatedUsers group and save it as acl-grant-authenticated-users.json:
    {
    "Owner": {
    "DisplayName": "awsseccookbook",
    "ID": "5df5b6014ae606808dcb64208aa09e4f19931b3123456e152c4dfa52d38bf8fd"
    },
    "Grants": [
    {
    "Grantee": {
    "Type": "Group",
    "URI": "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"
    },
    "Permission": "READ"
    }
    ]
    }

    Here, the Owner element has the current account's display name and canonical ID. The Grants element grants the READ permission to the AuthenticatedUsers group.

    1. Execute the put-bucket-acl command by providing the preceding policy document:
    aws s3api put-bucket-acl \
    --bucket awsseccookbook \
    --access-control-policy file://resources/acl-grant-authenticated-users.json \
    --profile awssecadmin
    1. The testuser user should now be able to list the contents of the S3 bucket. However, we won't be able to list the bucket contents from the browser.

    Granting public READ for an object with canned ACLs from the CLI

    We can upload an object and grant public read access using a canned ACL as follows:

    1. Download the image file using the admin user profile. On this occasion, downloading should be successful:
    1. Upload the same file as an administrator, providing the canned ACL for public-read:
    aws s3 cp image-heartin-k.png s3://awsseccookbook/image-heartin-new.png \
    --acl public-read \
    --profile awssecadmin
    1. Download the new file using the testuser profile:

    We should now be able to download the file successfully.

    How it works...

    In this recipe, we learned about ACLs.

    In the Granting READ ACLs for a bucket to everyone from the console section, we granted the READ permission to everyone through ACLs. In the Granting READ for AWS users using predefined groups from the CLI section, we granted the READ permission using a predefined group: AuthenticatedUsers.

    The policy document for granting access through ACLs has the following structure:

    {
      "Grants": [
        {
          "Grantee": {
            "DisplayName": "string",
            "EmailAddress": "string",
            "ID": "string",
            "Type": "CanonicalUser"|"AmazonCustomerByEmail"|"Group",
            "URI": "string"
          },
          "Permission": "FULL_CONTROL"|"WRITE"|"WRITE_ACP"|"READ"|"READ_ACP"
        }
        ...
      ],
      "Owner": {
        "DisplayName": "string",
        "ID": "string"
      }
    }

    The grantee can be specified in one of the following ways:

    • With Type as AmazonCustomerByEmail, along with the canonical ID of the account in the EmailAddress field
    • With Type as CanonicalUser, along with the email for the account in the ID field
    • With Type as Group, along with the URI for a predefined group in the URI field

    The account can be specified using an email address or the canonical ID of the account. We can get the canonical ID of an account from the Security Credentials page of our account.

    The following are globally the URIs for predefined groups and should be used in the JSON policy:

    • AuthenticatedUser: http://acs.amazonaws.com/groups/global/AuthenticatedUsers
    • AllUsers: http://acs.amazonaws.com/groups/global/AllUsers
    • LogDelivery: http://acs.amazonaws.com/groups/s3/LogDelivery

    ACLs can be used to grant the following permissions to buckets/objects:

    • READ: List objects for a bucket. Read an object and its metadata.
    • WRITE: Create, overwrite, or delete objects for a bucket. Not applicable for an object.
    • READ_ACP: Read the ACL of a bucket or object.
    • WRITE_ACP: Write the ACL for a bucket or object.
    • FULL_CONTROL: All the previous permissions.

    In the Granting public READ for an object with canned ACLs from the CLI section, we used a canned policy, pubic-read, which allows everyone to read that object. Canned ACLs are short-hand ACL permissions that can be used to provide permission for a resource from the command line. Currently, the following canned ACLs are supported: private, public-read, public-read-write, aws-exec-read, authenticated-read, bucket-owner-read, bucket-owner-full-control, and log-delivery-write.

    In the case of cross-account access, if a user from account A uploads an object to a bucket in account B (owned by account B), account B will have no access to that object even if it is the bucket owner. Account A can, however, grant permission to the bucket owner while uploading the document using the bucket-owner-read or bucket-owner-full-control canned ACL.

    We used the put-bucket-acl sub-command of the aws s3api command in this recipe to set permissions on a bucket using ACLs. Similarly, put-object-acl sets permission for an object. If we forget the policy structure for a put policy, we can execute a get policy to get the structure and modify it for our purpose. The get-bucket-acl sub-command of the aws s3api command gets the bucket's ACL policy, and get-object-policy gets an object's ACL policy.

    There's more...

    S3 is considered to be secure by default. A new object will have no access except for the account owner. An account owner of an S3 resource is the account that created that resource.

    Let's go through some important concepts related to ACLs:

    • ACLs provide basic read/write permission to buckets, objects, and their ACLs.
    • ACLs can only grant access to AWS accounts and predefined groups.
    • ACLs, by default, allow full control to the owner of the resource and nothing to everyone else.
    • ACLs can only grant permission; they cannot deny access.
    • ACLs are represented internally as XML documents.
    • ACLs are generally considered legacy and, wherever possible, it is preferable to use either an IAM policy or a bucket policy. However, there are some scenarios where ACLs are the best, or the only, choice:
      • ACLs can be used to grant access to objects not owned by the bucket owner. For example, when a user in one account uploads an object to another accounts' bucket, canned ACLs can be used to provide access to the bucket owner.
      • ACLs are used to grant permission to an S3 log delivery group for a bucket.
      • ACLs can be used to grant individual permissions to many objects. Even though this can be done with a bucket policy, it is easier to achieve this with ACLs.
    • While ACLs are specified per resource, bucket policies are specified per bucket and prefixes. IAM policies have resources specified in a similar way to bucket policies, but are applied to IAM users.

    Let's quickly go through some more important concepts related to canned ACLs:

    • The bucket-owner-read and bucket-owner-full-control canned ACLs are only applicable to objects and are ignored if specified while creating a bucket.
    • The log-delivery-write canned ACL only applies to a bucket.
    • With the aws-exec-read canned ACL, the owner gets the FULL_CONTROL permission and Amazon EC2 gets READ access to an Amazon Machine Image (AMI) from S3.
    • With the log-delivery-write canned ACL, the LogDelivery group gets WRITE and READ_ACP permissions for the bucket. This is used for S3 access logging.
    • When making an API call, we can specify a canned ACL in our request using the x-amz-acl request header.

    Comparing ACLs, bucket policies, and IAM policies

    ACLs differ from IAM policies and bucket policies in the following ways:

    • ACLs provide only basic read/write permission to buckets, objects, and their ACLs. IAM policies and bucket policies provide more fine-grained permissions than ACLs.
    • ACLs can only grant access to AWS accounts and predefined groups. ACLs cannot grant permissions to IAM users. IAM policies and bucket policies can be used to grant access to IAM users.
    • ACLs, by default, allow full control to the owner of the resource and nothing to everyone else. Bucket policies and IAM policies are not attached to a resource by default.
    • ACLs can only grant permissions. Bucket policies and IAM policies can explicitly deny access.
    • ACLs cannot conditionally allow or deny access. Bucket policies and IAM policies can conditionally allow or deny access.
    • ACLs are represented internally as XML documents. Bucket policies and IAM policies are represented as JSON documents, and the maximum size of such a JSON document is 20 KB.

    IAM policies differ from ACLs and bucket policies in the following ways:

    • IAM policies are user-based and are applied to users. ACLs and bucket policies are resource-based policies and are applied to resources.
    • IAM policies can be inline (embedded directly into a user, group, or role) or standalone (can be attached to any IAM user, group, or role). ACLs and bucket policies are sub-resources of a bucket.
    • IAM policies can only give access to an IAM user. Bucket policies and ACLs can be used to provide anonymous access as well as access to a root user.
    We can mix ACLs, bucket policies, and IAM policies. All policies are evaluated at the same time if the bucket and user are within the same account.

    See also

    • You can read about IAM policies in the Creating IAM policies recipe in Chapter 1, Managing AWS Accounts with IAM and Organizations.