Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS S3 static site with HTTPS and VPN-only access

Currently we have a static site deployed to ECS (Elastic Container Service) and fronted by an ELB (Elastic Load Balancer). This model doesn't really make sense, since the container is just running NGINX to serve static assets.

However, what we do get from this model, is VPN-only access to the website (our VPN client forwards all 10.x traffic to our VPC), and an HTTPS listener on the ELB, which are both things that we want to keep.

What's the best way to migrate this static site currently accessible only through VPN to being served from S3/Cloudfront via HTTPS and accessible only through VPN?

We have the same VPN configuration as in this answer. That answer would work for us, but it doesn't address the question of S3 bucket IPs possibly changing (which would invalidate the proposed routing rule on the VPN client), and I'm not clear on how to get HTTPS to work with this (AFAIK, you would need to put CF in front of the S3 static site, but I'm not sure how to route traffic to Cloudfront through our VPN.)

like image 698
yangmillstheory Avatar asked Feb 16 '17 05:02

yangmillstheory


People also ask

How can I access my Amazon S3 bucket over VPN?

AWS PrivateLink for Amazon S3 enables on-premises applications to privately and securely access Amazon S3 over AWS Direct Connect private virtual interface or AWS Site to Site VPN.

Can you use HTTPS with S3?

If your Amazon S3 bucket is configured as a website endpoint, you can't configure CloudFront to use HTTPS to communicate with your origin because Amazon S3 doesn't support HTTPS connections in that configuration.


1 Answers

I decided to use VPC endpoints to control ingress. There's an internal load-balancer (private subnet) accessible only through VPC/VPN that routes traffic to a VPC endpoint.

Bucket policy looks like (Terraform template)

{
  "Version": "2012-10-17",
  "Id": "Policy1415115909152",
  "Statement": [
    {
      "Sid": "deny-get-if-not-from-vpce",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::${bucket}",
        "arn:aws:s3:::${bucket}/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": "${vpce_id}"
        }
      },
      "Principal": "*"
    },
    {
      "Sid": "allow-get-if-from-vpce",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::${bucket}",
        "arn:aws:s3:::${bucket}/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:sourceVpce": "${vpce_id}"
        }
      },
      "Principal": "*"
    }
  ]
}

And it works! We get an SSL connection, and the load balancer zero access outside the VPN (load balancer DNS won't resolve, and 403 on the S3 static site itself).

See http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies-vpc-endpoint.html.

like image 96
yangmillstheory Avatar answered Oct 14 '22 09:10

yangmillstheory