Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit b49d2fe

Browse files
ari-luokkalaari.luokkala
andauthored
fix(domain): add domain input domainMinimumProtocolVersion (#1916)
Co-authored-by: ari.luokkala <[email protected]>
1 parent 3edd8fa commit b49d2fe

File tree

4 files changed

+29
-8
lines changed

4 files changed

+29
-8
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ myNextApplication:
151151
component: "@sls-next/serverless-component@{version_here}"
152152
inputs:
153153
domain: "example.com" # sub-domain defaults to www
154+
domainMinimumProtocolVersion: "TLSv1.2_2018" # can be omitted, defaults to "TLSv1.2_2018"
154155
```
155156

156157
You can also configure a `subdomain`:
@@ -540,7 +541,8 @@ The fourth cache behaviour handles next API requests `api/*`.
540541
| build.useV2Handler | `boolean` | `false` | **Experimental** Set this to true to use V2 handlers which starts to use genericized handlers. Note: this has the functionality of `separateApiLambda` and `disableOriginResponseHandler` so it should not be used together. Also, it is not completely optimized yet in terms of code size, but should still be performant. In the future, we will likely use this mode by default.
541542
| cloudfront | `object` | `{}` | Inputs to be passed to [aws-cloudfront](https://github.com/serverless-components/aws-cloudfront) |
542543
| certificateArn | `string` | `` | Specific certificate ARN to use for CloudFront distribution. Helpful if you have a wildcard SSL cert you wish to use. This currently works only in tandem with the`domain`input. Please check [custom CloudFront configuration](https://github.com/serverless-nextjs/serverless-next.js#custom-cloudfront-configuration) for how to specify`certificate`without needing to use the`domain`input (note that doing so will override any certificate due to the domain input). |
543-
| domainType |`string` |`"both"` | Can be one of:`"apex"`- apex domain only, don't create a www subdomain.`"www"` - www domain only, don't create an apex subdomain.`"both"`- create both www and apex domains when either one is provided. |
544+
| domainType |`string` |`"both"` | Can be one of:`"apex"`- apex domain only, don't create a www subdomain.`"www"` - www domain only, don't create an apex subdomain.`"both"`- create both www and apex domains when either one is provided. |
545+
| domainMinimumProtocolVersion |`string` |`"TLSv1.2_2018"` | Can be one of: `"SSLv3", "TLSv1", "TLSv1.1_2016", "TLSv1.2_2018", "TLSv1.2_2019", "TLSv1.2_2021" or "TLSv1_2016"`. See [reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html). |
544546
| publicDirectoryCache |`boolean\|object`|`true` | Customize the`public`/`static`folder asset caching policy. Assigning an object with`value`and/or`test`lets you customize the caching policy and the types of files being cached. Assigning false disables caching |
545547
| useServerlessTraceTarget |`boolean` |`false` | Use the experimental-serverless-trace target to build your next app. This is the same build target that Vercel Now uses. See this [RFC](https://github.com/vercel/next.js/pull/8246) for details. Note: while using this, you may need to set`NODE*ENV`variable to`production`. | | logLambdaExecutionTimes | `boolean` |`false` | Logs to CloudWatch the default handler performance metrics. |
546548
| minifyHandlers |`boolean` |`false` | Use pre-built minified handlers to reduce code size. Does not minify custom handlers. | | deploy |`boolean` |`true` | Whether to deploy resources to AWS (available in the latest alpha). Useful if you just need the build outputs (Lambdas and assets) but want to deploy them yourself. Build outputs will be created in the`.serverless_nextjs`directory. You are then responsible to configure AWS yourself: setting CloudFront behaviors with Lambda function associations, uploading assets to S3 with the proper`Cache-Control`headers, etc. |

packages/serverless-components/domain/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ domain:
1717
www: ${websiteComponentInstance}
1818
api: ${backendComponentInstance}
1919
admin: ${anotherWebsiteComponentInstance}
20+
domainMinimumProtocolVersion: "TLSv1.2_2018"
2021
```
2122
2223
### Set-Up

packages/serverless-components/domain/serverless.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const {
1010
configureDnsForCloudFrontDistribution,
1111
removeCloudFrontDomainDnsRecords,
1212
addDomainToCloudfrontDistribution,
13-
removeDomainFromCloudFrontDistribution
13+
removeDomainFromCloudFrontDistribution,
14+
isMinimumProtocolVersionValid
1415
} = require("./utils");
1516

1617
class Domain extends Component {
@@ -26,11 +27,16 @@ class Domain extends Component {
2627
inputs.domainType = inputs.domainType || "both";
2728
inputs.defaultCloudfrontInputs = inputs.defaultCloudfrontInputs || {};
2829
inputs.certificateArn = inputs.certificateArn || "";
30+
inputs.domainMinimumProtocolVersion = inputs.domainMinimumProtocolVersion || 'TLSv1.2_2018'
2931

3032
if (!inputs.domain) {
3133
throw Error(`"domain" is a required input.`);
3234
}
3335

36+
if (!isMinimumProtocolVersionValid(inputs.domainMinimumProtocolVersion)) {
37+
throw Error(`"minimumProtocolVersion" has in invalid value.`);
38+
}
39+
3440
// TODO: Check if domain has changed.
3541
// On domain change, call remove for all previous state.
3642

@@ -45,6 +51,7 @@ class Domain extends Component {
4551
this.state.privateZone = JSON.parse(inputs.privateZone);
4652
this.state.domain = inputs.domain;
4753
this.state.subdomains = subdomains;
54+
this.state.domainMinimumProtocolVersion = inputs.domainMinimumProtocolVersion
4855

4956
await this.save();
5057

@@ -126,12 +133,13 @@ class Domain extends Component {
126133
throw new Error(`Unsupported subdomain type ${awsS3Website}`);
127134
} else if (subdomain.type === "awsCloudFront") {
128135
this.context.debug(
129-
`Adding ${subdomain.domain} domain to CloudFront distribution with URL "${subdomain.url}"`
136+
`Adding ${subdomain.domain} domain to CloudFront distribution with URL "${subdomain.url}.\nTLS minimum protocol version: ${inputs.domainMinimumProtocolVersion}`
130137
);
131138
await addDomainToCloudfrontDistribution(
132139
clients.cf,
133140
subdomain,
134141
certificate.CertificateArn,
142+
inputs.domainMinimumProtocolVersion,
135143
inputs.domainType,
136144
inputs.defaultCloudfrontInputs,
137145
this.context
@@ -209,6 +217,7 @@ class Domain extends Component {
209217
await removeDomainFromCloudFrontDistribution(
210218
clients.cf,
211219
domainState,
220+
this.state.domainMinimumProtocolVersion,
212221
this.context
213222
);
214223

packages/serverless-components/domain/utils.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const aws = require("aws-sdk");
22
const { utils } = require("@serverless/core");
33

4-
const DEFAULT_MINIMUM_PROTOCOL_VERSION = "TLSv1.2_2018";
54
const HOSTED_ZONE_ID = "Z2FDTNDATAQYW2"; // this is a constant that you can get from here https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
65

76
/**
@@ -393,6 +392,7 @@ const addDomainToCloudfrontDistribution = async (
393392
cf,
394393
subdomain,
395394
certificateArn,
395+
domainMinimumProtocolVersion,
396396
domainType,
397397
defaultCloudfrontInputs,
398398
context
@@ -438,7 +438,7 @@ const addDomainToCloudfrontDistribution = async (
438438
params.DistributionConfig.ViewerCertificate = {
439439
ACMCertificateArn: certificateArn,
440440
SSLSupportMethod: "sni-only",
441-
MinimumProtocolVersion: DEFAULT_MINIMUM_PROTOCOL_VERSION,
441+
MinimumProtocolVersion: domainMinimumProtocolVersion,
442442
Certificate: certificateArn,
443443
CertificateSource: "acm",
444444
...defaultCloudfrontInputs.viewerCertificate
@@ -462,6 +462,7 @@ const addDomainToCloudfrontDistribution = async (
462462
const removeDomainFromCloudFrontDistribution = async (
463463
cf,
464464
subdomain,
465+
domainMinimumProtocolVersion,
465466
context
466467
) => {
467468
const params = await cf
@@ -481,7 +482,7 @@ const removeDomainFromCloudFrontDistribution = async (
481482

482483
params.DistributionConfig.ViewerCertificate = {
483484
SSLSupportMethod: "sni-only",
484-
MinimumProtocolVersion: DEFAULT_MINIMUM_PROTOCOL_VERSION
485+
MinimumProtocolVersion: domainMinimumProtocolVersion
485486
};
486487

487488
context.debug(
@@ -498,6 +499,13 @@ const removeDomainFromCloudFrontDistribution = async (
498499
};
499500
};
500501

502+
const isMinimumProtocolVersionValid = (minimumProtocolVersion) => {
503+
// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html
504+
const validMinimumProtocolVersions = /(^SSLv3$|^TLSv1$|^TLSv1.1_2016$|^TLSv1.2_2018$|^TLSv1.2_2019$|^TLSv1.2_2021$|^TLSv1_2016$)/g;
505+
const isVersionValid = minimumProtocolVersion.match(validMinimumProtocolVersions)?.length === 1
506+
return isVersionValid
507+
}
508+
501509
module.exports = {
502510
getClients,
503511
prepareSubdomains,
@@ -510,5 +518,6 @@ module.exports = {
510518
configureDnsForCloudFrontDistribution,
511519
removeCloudFrontDomainDnsRecords,
512520
addDomainToCloudfrontDistribution,
513-
removeDomainFromCloudFrontDistribution
514-
};
521+
removeDomainFromCloudFrontDistribution,
522+
isMinimumProtocolVersionValid
523+
};

0 commit comments

Comments
 (0)