Skip to content

Commit

Permalink
feat(ec2): client vpn endpoint (aws#12234)
Browse files Browse the repository at this point in the history
Add support for client VPN endpoints with the following L2s: `ClientVpnEndpoint`,
`ClientVpnAuthorizationRule` and `ClientVpnRoute`.

Client VPN endpoints can be added to VPCs with the `addClientVpnEndpoint()`
method.

Both mutual and user-based authentication are supported.

The `ClientVpnEndpoint` class implements `IConnectable`.

Use a custom resource to import server and client certificates in ACM
for the integration test.

Close aws#4206

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored and hollanddd committed Aug 26, 2021
1 parent 19d5a8d commit 1c88783
Show file tree
Hide file tree
Showing 19 changed files with 1,964 additions and 2 deletions.
65 changes: 65 additions & 0 deletions packages/@aws-cdk/aws-ec2/README.md
Expand Up @@ -678,6 +678,71 @@ Note: The domain name must be owned (registered through Route53) by the account
The VpcEndpointServiceDomainName will handle the AWS side of domain verification, the process for which can be found
[here](https://docs.aws.amazon.com/vpc/latest/userguide/endpoint-services-dns-validation.html)

### Client VPN endpoint

AWS Client VPN is a managed client-based VPN service that enables you to securely access your AWS
resources and resources in your on-premises network. With Client VPN, you can access your resources
from any location using an OpenVPN-based VPN client.

Use the `addClientVpnEndpoint()` method to add a client VPN endpoint to a VPC:

```ts fixture=client-vpn
vpc.addClientVpnEndpoint('Endpoint', {
cidr: '10.100.0.0/16',
serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
// Mutual authentication
clientCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/client-certificate-id',
// User-based authentication
userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
});
```

The endpoint must use at least one [authentication method](https://docs.aws.amazon.com/vpn/latest/clientvpn-admin/client-authentication.html):

* Mutual authentication with a client certificate
* User-based authentication (directory or federated)

If user-based authentication is used, the [self-service portal URL](https://docs.aws.amazon.com/vpn/latest/clientvpn-user/self-service-portal.html)
is made available via a CloudFormation output.

By default, a new security group is created and logging is enabled. Moreover, a rule to
authorize all users to the VPC CIDR is created.

To customize authorization rules, set the `authorizeAllUsersToVpcCidr` prop to `false`
and use `addaddAuthorizationRule()`:

```ts fixture=client-vpn
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
cidr: '10.100.0.0/16',
serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
authorizeAllUsersToVpcCidr: false,
});

endpoint.addAuthorizationRule('Rule', {
cidr: '10.0.10.0/32',
groupId: 'group-id',
});
```

Use `addRoute()` to configure network routes:

```ts fixture=client-vpn
const endpoint = vpc.addClientVpnEndpoint('Endpoint', {
cidr: '10.100.0.0/16',
serverCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/server-certificate-id',
userBasedAuthentication: ec2.ClientVpnUserBasedAuthentication.federated(samlProvider),
});

// Client-to-client access
endpoint.addRoute('Route', {
cidr: '10.100.0.0/16',
target: ec2.ClientVpnRouteTarget.local(),
});
```

Use the `connections` object of the endpoint to allow traffic to other security groups.

## Instances

You can use the `Instance` class to start up a single EC2 instance. For production setups, we recommend
Expand Down
57 changes: 57 additions & 0 deletions packages/@aws-cdk/aws-ec2/lib/client-vpn-authorization-rule.ts
@@ -0,0 +1,57 @@
import { Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IClientVpnEndpoint } from './client-vpn-endpoint-types';
import { CfnClientVpnAuthorizationRule } from './ec2.generated';

/**
* Options for a ClientVpnAuthorizationRule
*/
export interface ClientVpnAuthorizationRuleOptions {
/**
* The IPv4 address range, in CIDR notation, of the network for which access
* is being authorized.
*/
readonly cidr: string;

/**
* The ID of the group to grant access to, for example, the Active Directory
* group or identity provider (IdP) group.
*
* @default - authorize all groups
*/
readonly groupId?: string;

/**
* A brief description of the authorization rule.
*
* @default - no description
*/
readonly description?: string;
}

/**
* Properties for a ClientVpnAuthorizationRule
*/
export interface ClientVpnAuthorizationRuleProps extends ClientVpnAuthorizationRuleOptions {
/**
* The client VPN endpoint to which to add the rule.
*/
readonly clientVpnEndoint: IClientVpnEndpoint;
}

/**
* A client VPN authorization rule
*/
export class ClientVpnAuthorizationRule extends Resource {
constructor(scope: Construct, id: string, props: ClientVpnAuthorizationRuleProps) {
super(scope, id);

new CfnClientVpnAuthorizationRule(this, 'Resource', {
clientVpnEndpointId: props.clientVpnEndoint.endpointId,
targetNetworkCidr: props.cidr,
accessGroupId: props.groupId,
authorizeAllGroups: !props.groupId,
description: props.description,
});
}
}
52 changes: 52 additions & 0 deletions packages/@aws-cdk/aws-ec2/lib/client-vpn-endpoint-types.ts
@@ -0,0 +1,52 @@
import { IDependable, IResource } from '@aws-cdk/core';
import { IConnectable } from './connections';

/**
* A client VPN endpoint
*/
export interface IClientVpnEndpoint extends IResource, IConnectable {
/**
* The endpoint ID
*/
readonly endpointId: string;

/**
* Dependable that can be depended upon to force target networks associations
*/
readonly targetNetworksAssociated: IDependable;
}

/**
* A connection handler for client VPN endpoints
*/
export interface IClientVpnConnectionHandler {
/**
* The name of the function
*/
readonly functionName: string;

/**
* The ARN of the function.
*/
readonly functionArn: string;
}

/**
* Transport protocol for client VPN
*/
export enum TransportProtocol {
/** Transmission Control Protocol (TCP) */
TCP = 'tcp',
/** User Datagram Protocol (UDP) */
UDP = 'udp',
}

/**
* Port for client VPN
*/
export enum VpnPort {
/** HTTPS */
HTTPS = 443,
/** OpenVPN */
OPENVPN = 1194,
}

0 comments on commit 1c88783

Please sign in to comment.