Cloudfront as a reverse proxy
I run two services on AWS. One is a static website, the other is a serverless API.
The static website consists of the following setup:
flowchart TD
User --> Cloudfront
Cloudfront -- Default Behaviour --> S3
It's extremely simple, and handles global caching really easily.
The serverless API is a bit more complex, but it's still pretty simple.
flowchart LR
User --> APIGateway[API Gateway]
APIGateway -- GET /bar --> Lambda1[Lambda 1]
APIGateway -- GET /foo --> Lambda2[Lambda 2]
I've just setup Mastodon recently and need to update my
/.well-known/webfinger
to point to the mastodon instance.
This will let me use my root domain as my mastodon username URL. Issue
is - I'm already using the webfinger endpoint for OIDC...
So the solution is to set up a special API function that can handle this request. If It's meant for mastodon - send it there. Otherwise, return whatever else I want as JSON.
flowchart TD
User -- /.well-known/webfinger --> Cloudfront
Cloudfront -- Custom Behaviour --> APIGateway[API Gateway]
APIGateway --> Lambda[Lambda]
The issue I was running into was my cloudfront custom behaviour
wasn't working. This was due to CloudFront forwarding the
Host
header to the origin. API Gateway doesn't like
this & will always return a 403
{"message":"Forbidden"}
.
I fixed this by ensuring the OriginRequestPolicyId
was
set up to a policy that forwarded everything
except the Host
header. AWS
Incorrectly warn that this will break API Gateway, but it does not.
Here's my working truncated Cloudfront distribution config
CacheBehaviors
and Origins
are the primary
changes:
WebsiteCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: ${self:custom.s3Bucket}.s3.${opt:region}.amazonaws.com
Id: ${self:custom.s3Bucket}.s3.${opt:region}.amazonaws.com
OriginAccessControlId: !Ref WebsiteCloudfrontOriginAccessControl
S3OriginConfig:
OriginAccessIdentity: ""
- DomainName: api.pfy.ch
Id: api.pfy.ch
CustomOriginConfig:
OriginProtocolPolicy: https-only
DefaultRootObject: index.html
CacheBehaviors:
- PathPattern: /.well-known/*
TargetOriginId: api.pfy.ch
ViewerProtocolPolicy: redirect-to-https
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # Disable caching
OriginRequestPolicyId: 88de81a8-de41-4bfc-a73-d5de1f3cd023 # Custom policy to forward everything except host!
AllowedMethods:
- GET
- HEAD
- OPTIONS
- PUT
- POST
- PATCH
- DELETE
CachedMethods:
- HEAD
- GET
ForwardedValues:
QueryString: true
If forwarding to API Gateway ENSURE that
the Host
header is not forwarded.