Prerequisites
I have configured a custom domain for an API Gateway. The endpoint type is edge, as the API Gateway (RestApi) is edge.
I also issued a certificate through cdk. This is some of the code used:
const zone = route53.HostedZone.fromLookup(stack, 'Z0557019************', {
domainName: 'sub.example.com' // changed for SO post
})
const certificate = new DnsValidatedCertificate(stack, 'lws-api-certificate', {
domainName: 'mysub.sub.example.com', // changed for SO post
region: 'us-east-1',
hostedZone: zone
})
const api = new apigateway.RestApi(stack, 'legacy-wrapper-api', {
restApiName: 'My API',
domainName: {
domainName: 'mysub.sub.example.com',
certificate: certificate,
endpointType: EndpointType.EDGE
},
policy: apiResourcePolicy
})
new route53.ARecord(stack, 'ApiGatewayAliasRecord', {
zone: zone,
recordName: 'mysub',
target: route53.RecordTarget.fromAlias(new targets.ApiGateway(api))
})
So, I understand that a Cloudfront distribution is created. However, it is not listed in CloudFront.
In ApiGateway console:
What works
The custom domain was successfully created and applied and I am able to access my API gateway through mysub.sub.example.com
.
What is not working
My issue is the following. I have clients which send a wrong Host
Header. We can call our api fine when Host Header is mysub.sub.example.com
. However, one client sends erroneously sub.another-example.com
.
I know that this is a wrong header. But there is nothing we can do about this client sending the wrong header. Unfortunately!
What are my options?
- switch to http
- add foreign Host to allowed Hosts (certificate)?
- Create some sort of proxy instance which allows incoming traffic from
sub.another-example.com
and redirect to
Regarding 1.
How can I allow http? I am seeing an option to set a minimum security level, but the minimum is TSL1.0. Can I even create a CloudFront distribution that accepts http? Again, in console I cannot see the distribution so I have to do it via CDK.
Regarding 2.
How can I do that, specifically in CDK?
Regarding 3.
Any creative ideas?
Help is much appreciated.
Additional resource: A curl call to the custom domain with wrong header brings this:
$ curl --header "Authorization: Bearer 9c904d3##########################" --header "Host: sub.another-example.com" -v https://mysub.sub.example.com/v2.2/api/posts/list
* TCP_NODELAY set
* Connected to mysub.sub.example.com (18.66.###########) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=mysub.sub.example.com
* start date: May 27 00:00:00 2022 GMT
* expire date: Jun 25 23:59:59 2023 GMT
* subjectAltName: host "mysub.sub.example.com" matched cert's "mysub.sub.example.com"
* issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5627934cd8c0)
> GET /v2.2/api/posts/list HTTP/2
> Host: sub.another-example.com <----------------- This is the problematic value
> user-agent: curl/7.68.0
> accept: */*
> authorization: Bearer 9c904d3##########################
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 403
< server: CloudFront
< date: Mon, 30 May 2022 11:21:50 GMT
< content-type: text/html
< content-length: 915
< x-cache: Error from cloudfront
< via: 1.1 f7d063##########################.cloudfront.net (CloudFront)
< x-amz-cf-pop: FRA56-P5
< x-amz-cf-id: _KTRiNK8z74PB4qCwS##################################################==
<
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: _KTRiNK8z74PB4qCwS##################################################==
</PRE>
<ADDRESS>
</ADDRESS>
* Connection #0 to host mysub.sub.example.com left intact
</BODY></HTML>
As often when the questions are so specific I found a solution myself.
It is option 2! All with CDK.
Those are the steps:
Cloudfront distribution with alternate domain and cert
This is the final code.