Skip to content

Commit

Permalink
fix(cloudfront): Set MinimumProtocolVersion and SslSupportMethod when…
Browse files Browse the repository at this point in the history
… specifying distribution certificate (aws#9200)

Per the CloudFormation documentation, if you specify an ACM certificate ARN, you must also specify values for
MinimumProtocolVersion and SslSupportMethod in AWS::CloudFront::Distribution ViewerCertificate. We are using
the recommended SslSupportMethod of "sni-only" and MinimumProtocolVersion of "TLSv1.2_2018."

Fixes: aws#9193

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
tneely authored and Chriscbr committed Jul 23, 2020
1 parent 7125a3d commit 70d25a5
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 36 deletions.
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ When you create a distribution, CloudFront assigns a domain name for the distrib
be retrieved from `distribution.distributionDomainName`. CloudFront distributions use a default certificate (`*.cloudfront.net`) to support HTTPS by
default. If you want to use your own domain name, such as `www.example.com`, you must associate a certificate with your distribution that contains
your domain name. The certificate must be present in the AWS Certificate Manager (ACM) service in the US East (N. Virginia) region; the certificate
may either be created by ACM, or created elsewhere and imported into ACM.
may either be created by ACM, or created elsewhere and imported into ACM. When a certificate is used, the distribution will support HTTPS connections
from SNI only and a minimum protocol version of TLSv1.2_2018.

```ts
const myCertificate = new acm.DnsValidatedCertificate(this, 'mySiteCert', {
Expand Down
43 changes: 42 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/lib/distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class Distribution extends Resource implements IDistribution {
origins: Lazy.anyValue({ produce: () => this.renderOrigins() }),
defaultCacheBehavior: this.defaultBehavior._renderBehavior(),
cacheBehaviors: Lazy.anyValue({ produce: () => this.renderCacheBehaviors() }),
viewerCertificate: this.certificate ? { acmCertificateArn: this.certificate.certificateArn } : undefined,
viewerCertificate: this.certificate ? this.renderViewerCertificate(this.certificate) : undefined,
customErrorResponses: this.renderErrorResponses(),
priceClass: props.priceClass ?? undefined,
} });
Expand Down Expand Up @@ -221,6 +221,14 @@ export class Distribution extends Resource implements IDistribution {
});
}

private renderViewerCertificate(certificate: acm.ICertificate): CfnDistribution.ViewerCertificateProperty {
return {
acmCertificateArn: certificate.certificateArn,
sslSupportMethod: SSLMethod.SNI,
minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2018,
};
}

}

/**
Expand Down Expand Up @@ -260,6 +268,39 @@ export enum OriginProtocolPolicy {
HTTPS_ONLY = 'https-only',
}

/**
* The SSL method CloudFront will use for your distribution.
*
* Server Name Indication (SNI) - is an extension to the TLS computer networking protocol by which a client indicates
* which hostname it is attempting to connect to at the start of the handshaking process. This allows a server to present
* multiple certificates on the same IP address and TCP port number and hence allows multiple secure (HTTPS) websites
* (or any other service over TLS) to be served by the same IP address without requiring all those sites to use the same certificate.
*
* CloudFront can use SNI to host multiple distributions on the same IP - which a large majority of clients will support.
*
* If your clients cannot support SNI however - CloudFront can use dedicated IPs for your distribution - but there is a prorated monthly charge for
* using this feature. By default, we use SNI - but you can optionally enable dedicated IPs (VIP).
*
* See the CloudFront SSL for more details about pricing : https://aws.amazon.com/cloudfront/custom-ssl-domains/
*
*/
export enum SSLMethod {
SNI = 'sni-only',
VIP = 'vip'
}

/**
* The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.
* CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify.
*/
export enum SecurityPolicyProtocol {
SSL_V3 = 'SSLv3',
TLS_V1 = 'TLSv1',
TLS_V1_2016 = 'TLSv1_2016',
TLS_V1_1_2016 = 'TLSv1.1_2016',
TLS_V1_2_2018 = 'TLSv1.2_2018'
}

/**
* The HTTP methods that the Behavior will accept requests on.
*/
Expand Down
35 changes: 1 addition & 34 deletions packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as lambda from '@aws-cdk/aws-lambda';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
import { CfnDistribution } from './cloudfront.generated';
import { IDistribution, OriginProtocolPolicy, PriceClass, ViewerProtocolPolicy } from './distribution';
import { IDistribution, OriginProtocolPolicy, PriceClass, ViewerProtocolPolicy, SSLMethod, SecurityPolicyProtocol } from './distribution';
import { IOriginAccessIdentity } from './origin_access_identity';

export enum HttpVersion {
Expand Down Expand Up @@ -89,39 +89,6 @@ export interface AliasConfiguration {
readonly securityPolicy?: SecurityPolicyProtocol;
}

/**
* The SSL method CloudFront will use for your distribution.
*
* Server Name Indication (SNI) - is an extension to the TLS computer networking protocol by which a client indicates
* which hostname it is attempting to connect to at the start of the handshaking process. This allows a server to present
* multiple certificates on the same IP address and TCP port number and hence allows multiple secure (HTTPS) websites
* (or any other service over TLS) to be served by the same IP address without requiring all those sites to use the same certificate.
*
* CloudFront can use SNI to host multiple distributions on the same IP - which a large majority of clients will support.
*
* If your clients cannot support SNI however - CloudFront can use dedicated IPs for your distribution - but there is a prorated monthly charge for
* using this feature. By default, we use SNI - but you can optionally enable dedicated IPs (VIP).
*
* See the CloudFront SSL for more details about pricing : https://aws.amazon.com/cloudfront/custom-ssl-domains/
*
*/
export enum SSLMethod {
SNI = 'sni-only',
VIP = 'vip'
}

/**
* The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.
* CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify.
*/
export enum SecurityPolicyProtocol {
SSL_V3 = 'SSLv3',
TLS_V1 = 'TLSv1',
TLS_V1_2016 = 'TLSv1_2016',
TLS_V1_1_2016 = 'TLSv1.1_2016',
TLS_V1_2_2018 = 'TLSv1.2_2018'
}

/**
* Logging configuration for incoming requests
*/
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ describe('certificates', () => {
DistributionConfig: {
ViewerCertificate: {
AcmCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012',
SslSupportMethod: 'sni-only',
MinimumProtocolVersion: 'TLSv1.2_2018',
},
},
});
Expand Down

0 comments on commit 70d25a5

Please sign in to comment.