AWS VPC Endpoints

- aws networking

This post is part of my note taking while studying for the AWS Certified Advanced Networking - Specialty certification.

VPC Endpoints (VPCEs) theoretically allow access to public AWS services (such as S3) within a VPC without crossing a VPC boundary. This is currently only available with S3. It’s important to note that VPC Endpoints are region specific and VPC specific. VPC Endpoints are not accessable across VPC boundaries, which means they cannot be accessed across a VPC peering, a VPN, nor an AWS Direct Connect connection. Official Amazon documentation is here.

Create a VPCE

You need three things to create a VPCE:

  1. VPC that it will be attached to
  2. Service it will connect to (e.g., S3)
  3. IAM Policy to permit or deny access to resources available via the endpoint

No public addressing is needed in the subnet. Once it’s created, a logical address object that can be reference in subnet routing tables will be created. To add a route, edit your routing table for the destination pl-id s3 and target of vpce-f23adc24 where the target is your VPCE ID. It will always start with vpce. The route table could look like this:

| Destination | Target | | VPC | local | | pl-id s3 | vpce-f23adc24 |
The list of IPs within pl-id s3 is competely managed by AWS and allows the VPCE to be contacted by objects in the subnet. It is important to note that DNS resolution must be enabled for the VPC. This allows a DNS name of a bucket to be resolved to an internal to the VPC IP address. Because VPCEs use internal to the VPC communication, no IGWs, NAT GWs, or NAT instances are needed for hosts in private subnets to contact S3. Here is how a host in a public subnet would connect to an S3 endpoint normally and how a host in a private subnet would connect with a VPCE.

Note: if the public subnet’s route table had a route to the VPCE for pl-s3, it use the VPCE as that’s a more specific route.

S3 access via VPCE

Multiple VPCEs in one VPC

Multiple VPCEs in one VPC are supported. You can differentiate which one hosts have access to via subnet routing tables. You can restrict which hosts have access to resources accessed via VPCEs using VPCE policies. With these two tools, fine grained policy control in a VPC to resources accessed via VPCEs is possible.

VPCE Policies

VPCEs use standard AWS IAM policies. By default, the VPCE policy unrestricted. However, like other AWS services, the resultant policy for access to a resource via the VPCE is a combination of the VPCE policy and the policy (e.g., an S3 bucket policy).

Here is an example policy, only allowing access to the S3 bucket for the Amazon Linux AMI respository:

{
  "Statement": [
    {
      "Sid": "AmazonLinuxAMIRepositoryAccess",
      "Principal": "*",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::packages.*.amazonaws.com/*",
        "arn:aws:s3:::repo.*.amazonaws.com/*"
      ]
    }
  ]
}

Controlling access to a VPCE via a NACL is problematic. NACLs only operate on CIDR ranges and cannot use logical network objects. Therefore, it’s best to use a security group when restricting network access to a VPCE.

n.b., VPCE endpoint policies cannot match aws:sourceIP conditions. This means using this in a permit policy, the IPs will never be permitted and in a deny policy, the IPs will not be denied, there won’t be a match. Use aws:sourceVpce instead.

Here is an example of an S3 bucket policy restricting access from a certain endpoint:

{
  "Version": "2012-10-17",
  "Id": "Policy1415115909152",
  "Statement": [
    {
      "Sid": "Access-to-specific-VPCE-only",
      "Principal": "*",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": ["arn:aws:s3:::my_secure_bucket",
                   "arn:aws:s3:::my_secure_bucket/*"],
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": "vpce-1a2b3c4d"
        }
      }
    }
  ]
}   

More information on VPC Endpoints for S3 and Endpoint Policies here.