Skip to content

Commit

Permalink
feat(elbv2): add desyncMitigationMode for elbv2 (#22730)
Browse files Browse the repository at this point in the history
Add `desyncMitigationMode` property for ALB so desync mitigation mode can be set easily.
see: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#desync-mitigation-mode

----

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
clueleaf authored Dec 1, 2022
1 parent 30602c1 commit 1a11938
Show file tree
Hide file tree
Showing 13 changed files with 2,137 additions and 1 deletion.
27 changes: 27 additions & 0 deletions packages/@aws-cdk/aws-elasticloadbalancingv2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,33 @@ If you do not provide any options for this method, it redirects HTTP port 80 to
By default all ingress traffic will be allowed on the source port. If you want to be more selective with your
ingress rules then set `open: false` and use the listener's `connections` object to selectively grant access to the listener.

### Load Balancer attributes

You can modify attributes of Application Load Balancers:

```ts
const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
vpc,
internetFacing: true,

// Whether HTTP/2 is enabled
http2Enabled: false,

// The idle timeout value, in seconds
idleTimeout: cdk.Duration.seconds(1000),

// Whether HTTP headers with header fields thatare not valid
// are removed by the load balancer (true), or routed to targets
dropInvalidHeaderFields: true,

// How the load balancer handles requests that might
// pose a security risk to your application
desyncMitigationMode: elbv2.DesyncMitigationMode.DEFENSIVE,
});
```

For more information, see [Load balancer attributes](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#load-balancer-attributes)

## Defining a Network Load Balancer

Network Load Balancers are defined in a similar way to Application Load
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as cxapi from '@aws-cdk/cx-api';
import { Construct } from 'constructs';
import { ApplicationELBMetrics } from '../elasticloadbalancingv2-canned-metrics.generated';
import { BaseLoadBalancer, BaseLoadBalancerLookupOptions, BaseLoadBalancerProps, ILoadBalancerV2 } from '../shared/base-load-balancer';
import { IpAddressType, ApplicationProtocol } from '../shared/enums';
import { IpAddressType, ApplicationProtocol, DesyncMitigationMode } from '../shared/enums';
import { ApplicationListener, BaseApplicationListenerProps } from './application-listener';
import { ListenerAction } from './application-listener-action';

Expand Down Expand Up @@ -51,6 +51,14 @@ export interface ApplicationLoadBalancerProps extends BaseLoadBalancerProps {
* @default false
*/
readonly dropInvalidHeaderFields?: boolean;

/**
* Determines how the load balancer handles requests that
* might pose a security risk to your application
*
* @default DesyncMitigationMode.DEFENSIVE
*/
readonly desyncMitigationMode?: DesyncMitigationMode;
}

/**
Expand Down Expand Up @@ -109,6 +117,7 @@ export class ApplicationLoadBalancer extends BaseLoadBalancer implements IApplic
if (props.http2Enabled === false) { this.setAttribute('routing.http2.enabled', 'false'); }
if (props.idleTimeout !== undefined) { this.setAttribute('idle_timeout.timeout_seconds', props.idleTimeout.toSeconds().toString()); }
if (props.dropInvalidHeaderFields) {this.setAttribute('routing.http.drop_invalid_header_fields.enabled', 'true'); }
if (props.desyncMitigationMode !== undefined) {this.setAttribute('routing.http.desync_mitigation_mode', props.desyncMitigationMode); }
}

/**
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-elasticloadbalancingv2/lib/shared/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,25 @@ export enum TargetGroupLoadBalancingAlgorithmType {
*/
LEAST_OUTSTANDING_REQUESTS = 'least_outstanding_requests',
}

/**
* How the load balancer handles requests that might pose a security risk to your application
*
* @see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#desync-mitigation-mode
*/
export enum DesyncMitigationMode {
/**
* Allows all traffic
*/
MONITOR = 'monitor',

/**
* Provides durable mitigation against HTTP desync while maintaining the availability of your application
*/
DEFENSIVE = 'defensive',

/**
* Receives only requests that comply with RFC 7230
*/
STRICTEST = 'strictest',
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,84 @@ describe('tests', () => {
});
});

describe('Desync mitigation mode', () => {
test('Defensive', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'Stack');

// WHEN
new elbv2.ApplicationLoadBalancer(stack, 'LB', {
vpc,
desyncMitigationMode: elbv2.DesyncMitigationMode.DEFENSIVE,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', {
LoadBalancerAttributes: [
{
Key: 'deletion_protection.enabled',
Value: 'false',
},
{
Key: 'routing.http.desync_mitigation_mode',
Value: 'defensive',
},
],
});
});
test('Monitor', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'Stack');

// WHEN
new elbv2.ApplicationLoadBalancer(stack, 'LB', {
vpc,
desyncMitigationMode: elbv2.DesyncMitigationMode.MONITOR,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', {
LoadBalancerAttributes: [
{
Key: 'deletion_protection.enabled',
Value: 'false',
},
{
Key: 'routing.http.desync_mitigation_mode',
Value: 'monitor',
},
],
});
});
test('Strictest', () => {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'Stack');

// WHEN
new elbv2.ApplicationLoadBalancer(stack, 'LB', {
vpc,
desyncMitigationMode: elbv2.DesyncMitigationMode.STRICTEST,
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', {
LoadBalancerAttributes: [
{
Key: 'deletion_protection.enabled',
Value: 'false',
},
{
Key: 'routing.http.desync_mitigation_mode',
Value: 'strictest',
},
],
});
});
});

test('Deletion protection false', () => {
// GIVEN
const stack = new cdk.Stack();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "Elbv2TestDefaultTestDeployAssert82DC2DEA.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"e0013d77550f4ad9d409277deba48d88a38a35f26ba1e36af47e988d8d2fc164": {
"source": {
"path": "aws-cdk-elbv2-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "e0013d77550f4ad9d409277deba48d88a38a35f26ba1e36af47e988d8d2fc164.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Loading

0 comments on commit 1a11938

Please sign in to comment.