--- title: Cloudfront as a reverse proxy publishedAt: 1725206876000 updatedAt: 1742177576000 --- 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: ```mermaid 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. ```mermaid 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. ```mermaid 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: ```yaml 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.