How to Pass All Viewer Headers from CloudFront to API Gateway? - aws-api-gateway

I have a CloudFront distribution that forwards all requests to API Gateway. I want my CloudFront distribution to forward all viewer headers to API Gateway.
I tried adding the managed AllViewer Origin request policy, but when sending a request to the distribution, I get { "message": "Forbidden" }.
I found out from a different Stack Overflow question that the reason that happens is because of the Host header being the cloudfront domain that is forwarded to my API gateway.
I tried adding a custom Host header to the cloudfront distribution to fix the issue, but the Host header is one of the custom headers that CloudFront can’t add to origin requests.
How can I forward all request headers to the API Gateway without specifying each one individually in a custom origin request policy?

Related

Cloudfront and ALBs - Redirecting an HTTP request of a URL that is not on the SSL certificate. HTTP not HTTPS

I have a ALB set up behind a cloudfront distro. I have a rule to redirect an HTTP request to URL A to URL B which is not on AWS infrastructure.
When I query the ALB directly for URL A, the load balancer properly redirects to URL B. When I query a cloudfront endpoint for URL A, I get a 403 error back. Per the troubleshoot 403s aws doc, it seems the issue is that I don't have an alternate CNAME configured for URL B. However, since it's not on my SAN certificate that's associated with my CloudFront distro, I can't add it to the list of alternate CNAMES. is there a workaround to allow requests to URL A to properly travel through my cloudfront distro and get redirected? It doesn't make sense to me that I can't do this for an HTTP request.
verified that the ALB can be queried directly and redirect works
tried to add an alternate cname for http domain
removed wacl on alb to make sure that wasn't blocking it

Using Cloudfront as CDN for my custom server REST API

I have a REST API on a Hetzner server which uses Varnish. I am trying to set up Cloudfront to use as the CDN for it. After reading around, I currently have the following setup:
Hetzner / Varnish
A main API route api.mydomain.com.
Config in Varnish for cdn-api.mydomain.com to also act as a route to the same API.
In the DNS for the domain in Hetzner, for cdn-api.mydomain.com I have
added the name servers for Route 53.
Route 53
Hosted zone called cdn-api.mydomain.com.
An A record with name prod.cdn-api.mydomain.com which points to my Cloudfront distribution.
An A record with name cdn-api.mydomain.com which points to the IP address of the server.
Cloudfront Distribution
Has the alternate domain name prod.cdn-api.mydomain.com.
Has the origin domain of cdn-api.mydomain.com
Protocol for origin is HTTP only
What I think should happen
Make a request to prod.cdn-api.mydomain.com.
Route 53 forwards to the Cloudfront distribution.
CloudFront looks to origin cdn-api.mydomain.com.
Origin cdn-api.mydomain.com looks to IP address of Hetzner.
Hetzner receives request, Varnish allows the domain through, sends back data to Cloudfront.
What actually happens
If I make a request straight to cdn-api.mydomain.com from Postman, it works if I turn off SSL.
If I turn on SSL, I get the error SSL Error: Hostname/IP does not match certificate's altnames, saying that cdn-api.mydomain.com is not on the certificates of the server.
If I make a request to prod.cdn-api.mydomain.com, I get the error Error: Exceeded maxRedirects. Probably stuck in a redirect loop. Which may be due to the same certs error.
Cloudflare
As a comparison, we have Cloudflare set up as the CDN for a different domain on the same Hetzner server. It has:
A main API route api.myotherdomain.com
In Hetzner a CNAME for cdn-api.myotherdomain.com with value cdn-api.myotherdomain.com.cdn.cloudflare.net.
In Cloudflare, an A record for cdn-api.myotherdomain.com which points to the IP address of the server.
cdn-api.myotherdomain.com is set up in Varnish as an entry point, but is not on the list of certificates of the server.
This all works fine including with SSL enabled.
It would be good to understand what I'm doing wrong here.

Cloudfront not forwarding requests to API Gateway (403 Forbidden)

I have a custom Lambda function that I set up with API Gateway. When invoking the API gateway resource path with Postman the Lambda gets invoked and does what it should. I enabled CORS on the API Gateway and didn't forget to deploy.
On Cloudfront I set up API Gateway as origin. Also I set up a cache behavior that forwards the headers as you can see in the following screenshot.
The response when invoking the endpoint in Cloudfront is the following:
I also tried removing the Host header, which leads to the same error Code but "MissingAuthenticationToken" as error reason. Because I found in the internet, that CORS might be a reason for this, I also tried setting the CORS headers in the response of my Lambda function which also didn't help.
I'm out of ideas right now. Does anyone know how to help? I had nothing but trouble with Cloudfront so far.

How to block HTTP and allows only HTTPS for AWS API Gateway with custom domain name map

I've added certificate with custom domain name map in AWS API gateway but it allows HTTP automatically, how can I block normal HTTP and only allows HTTPS?
All API Gateway APIs are fronted with a CloudFront distribution. Each of these CloudFront distributions (whether it's a Custom Domain like yours or the default *.execute-api distribution) is configured to redirect all HTTP requests to HTTPS. Although CloudFront has the option to strictly require HTTPS and return 403 on HTTP requests we currently don't expose this option for simplicity.
If you feel you have valid use case for requiring HTTPS without a redirect please open a support ticket and the team can evaluate your request.

AWS API Gateway - Test works, deployed API errors. Why?

I'm trying to setup AWS Api Gateway as a reverse proxy for my actual deployed API.
My understanding is that I do this by creating a "Proxy" Resource and then specifying my http endpoint URL - as described here
Create and Test an API with HTTP Proxy Integration through a Proxy Resource
This works fine when I try to use the API through the "Test" function within the Resource Editor. I can make calls to any exposed resources using GET methods and see the successful responses.
However, when I deploy the API Gateway API I can no longer access anything using the "Invoke URL" it gives me - I simply get:
{
"Message": "No HTTP resource was found that matches the request URI 'http://<myuniqueid>.execute-api.eu-west-1.amazonaws.com/api/Sector/100'.",
"MessageDetail": "No type was found that matches the controller named 'Sector'."
}
If I remove the "Use HTTP Proxy integration" checkbox from the "Integration Request" I can get it working, but why doesn't it work as a proxy?
I suspect that this is caused by a known issue with the HTTP proxy integration. When you use an HTTP proxy integration, API Gateway passes all headers through to the integration endpoint, including the HOST header. Many existing http endpoint require the use of a HOST header which matches their DNS name and in such cases, passing through the HOST header of the API Gateway can confuse the endpoint.
UPDATE: We identified a work-around for this issue.
In your integration request, explicitly add a header named "Host" and give it the value of the integration endpoint DNS name. This will replace the Host header forwarded from the incoming client request with the Host header you specify. This should allow your backend endpoint to function correctly.