EC2 Client VPN Endpoints Should Have Client Connection Logging Enabled
Overview
This check verifies that your AWS Client VPN endpoints have connection logging enabled. Client VPN endpoints allow remote users to securely connect to your VPC resources. When connection logging is enabled, AWS records who connects, when they connect, and when they disconnect to CloudWatch Logs.
Risk
Without connection logging, you have no visibility into who is accessing your network through the VPN. This creates several security risks:
- Stolen credentials go undetected - If someone compromises VPN credentials, you won't know they're using them
- No audit trail - You can't investigate security incidents or track user activity
- Compliance gaps - Many frameworks require logging of remote access activity
- Delayed incident response - Without logs, detecting and responding to threats takes longer
Remediation Steps
Prerequisites
You need:
- Access to the AWS Console with permissions to modify Client VPN endpoints, OR
- AWS CLI configured with appropriate permissions
- A CloudWatch Logs log group (you can create one during this process)
AWS Console Method
- Open the Amazon VPC Console at https://console.aws.amazon.com/vpc/
- In the left navigation, click Client VPN endpoints
- Select the endpoint that needs logging enabled
- Click Actions, then Modify client VPN endpoint
- Scroll to the Connection logging section
- Toggle Enable connection logging to ON
- For CloudWatch Logs log group, either:
- Select an existing log group, OR
- Click Create log group to create a new one (recommended name:
/aws/client-vpn/<endpoint-name>)
- Optionally specify a log stream name (AWS will create a default if left blank)
- Click Save changes
AWS CLI (optional)
Step 1: Create a CloudWatch Log Group (if needed)
aws logs create-log-group \
--log-group-name /aws/client-vpn/my-vpn-endpoint \
--region us-east-1
Step 2: Enable connection logging on your Client VPN endpoint
aws ec2 modify-client-vpn-endpoint \
--client-vpn-endpoint-id cvpn-endpoint-1234567890abcdef0 \
--connection-log-options Enabled=true,CloudwatchLogGroup=/aws/client-vpn/my-vpn-endpoint \
--region us-east-1
Replace:
cvpn-endpoint-1234567890abcdef0with your actual Client VPN endpoint ID/aws/client-vpn/my-vpn-endpointwith your log group name
Optional: Set log retention
aws logs put-retention-policy \
--log-group-name /aws/client-vpn/my-vpn-endpoint \
--retention-in-days 30 \
--region us-east-1
CloudFormation (optional)
This template creates a Client VPN endpoint with connection logging enabled.
AWSTemplateFormatVersion: '2010-09-09'
Description: Client VPN Endpoint with Connection Logging Enabled
Parameters:
ServerCertificateArn:
Type: String
Description: ARN of the server certificate in ACM
ClientCidrBlock:
Type: String
Description: CIDR block for VPN clients
Default: '10.0.0.0/22'
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC to associate with the Client VPN endpoint
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet to associate with the Client VPN endpoint
LogRetentionDays:
Type: Number
Default: 30
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653]
Description: Number of days to retain connection logs
Resources:
ClientVpnLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/aws/client-vpn/${AWS::StackName}'
RetentionInDays: !Ref LogRetentionDays
ClientVpnEndpoint:
Type: AWS::EC2::ClientVpnEndpoint
Properties:
Description: Client VPN endpoint with connection logging
ClientCidrBlock: !Ref ClientCidrBlock
ServerCertificateArn: !Ref ServerCertificateArn
AuthenticationOptions:
- Type: certificate-authentication
MutualAuthentication:
ClientRootCertificateChainArn: !Ref ServerCertificateArn
ConnectionLogOptions:
Enabled: true
CloudwatchLogGroup: !Ref ClientVpnLogGroup
VpcId: !Ref VpcId
SecurityGroupIds:
- !Ref ClientVpnSecurityGroup
SplitTunnel: true
TransportProtocol: udp
VpnPort: 443
TagSpecifications:
- ResourceType: client-vpn-endpoint
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-client-vpn'
ClientVpnSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for Client VPN endpoint
VpcId: !Ref VpcId
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-client-vpn-sg'
ClientVpnTargetNetworkAssociation:
Type: AWS::EC2::ClientVpnTargetNetworkAssociation
Properties:
ClientVpnEndpointId: !Ref ClientVpnEndpoint
SubnetId: !Ref SubnetId
Outputs:
ClientVpnEndpointId:
Description: Client VPN Endpoint ID
Value: !Ref ClientVpnEndpoint
LogGroupName:
Description: CloudWatch Log Group for connection logs
Value: !Ref ClientVpnLogGroup
Key configuration: The ConnectionLogOptions block with Enabled: true is what enables connection logging.
Terraform (optional)
# Variables
variable "server_certificate_arn" {
description = "ARN of the server certificate in ACM"
type = string
}
variable "client_cidr_block" {
description = "CIDR block for VPN clients"
type = string
default = "10.0.0.0/22"
}
variable "vpc_id" {
description = "VPC ID to associate with the Client VPN endpoint"
type = string
}
variable "subnet_id" {
description = "Subnet ID to associate with the Client VPN endpoint"
type = string
}
variable "log_retention_days" {
description = "Number of days to retain connection logs"
type = number
default = 30
}
variable "name_prefix" {
description = "Prefix for resource names"
type = string
default = "client-vpn"
}
# CloudWatch Log Group for connection logs
resource "aws_cloudwatch_log_group" "vpn_logs" {
name = "/aws/client-vpn/${var.name_prefix}"
retention_in_days = var.log_retention_days
tags = {
Name = "${var.name_prefix}-connection-logs"
}
}
# Security Group for Client VPN
resource "aws_security_group" "vpn" {
name = "${var.name_prefix}-sg"
description = "Security group for Client VPN endpoint"
vpc_id = var.vpc_id
tags = {
Name = "${var.name_prefix}-sg"
}
}
# Client VPN Endpoint with connection logging enabled
resource "aws_ec2_client_vpn_endpoint" "main" {
description = "Client VPN endpoint with connection logging"
client_cidr_block = var.client_cidr_block
server_certificate_arn = var.server_certificate_arn
split_tunnel = true
transport_protocol = "udp"
vpn_port = 443
authentication_options {
type = "certificate-authentication"
root_certificate_chain_arn = var.server_certificate_arn
}
# Connection logging configuration - THIS IS THE KEY SETTING
connection_log_options {
enabled = true
cloudwatch_log_group = aws_cloudwatch_log_group.vpn_logs.name
}
security_group_ids = [aws_security_group.vpn.id]
vpc_id = var.vpc_id
tags = {
Name = var.name_prefix
}
}
# Associate the Client VPN with a subnet
resource "aws_ec2_client_vpn_network_association" "main" {
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
subnet_id = var.subnet_id
}
# Outputs
output "client_vpn_endpoint_id" {
description = "Client VPN Endpoint ID"
value = aws_ec2_client_vpn_endpoint.main.id
}
output "log_group_name" {
description = "CloudWatch Log Group for connection logs"
value = aws_cloudwatch_log_group.vpn_logs.name
}
Key configuration: The connection_log_options block with enabled = true is what enables connection logging.
Verification
After enabling connection logging:
- Go to the VPC Console > Client VPN endpoints
- Select your endpoint and view the Details tab
- Confirm Connection logging shows as Enabled
- Verify the CloudWatch log group name is displayed
CLI verification
aws ec2 describe-client-vpn-endpoints \
--client-vpn-endpoint-ids cvpn-endpoint-1234567890abcdef0 \
--query 'ClientVpnEndpoints[0].ConnectionLogOptions' \
--region us-east-1
Expected output showing logging is enabled:
{
"Enabled": true,
"CloudwatchLogGroup": "/aws/client-vpn/my-vpn-endpoint",
"CloudwatchLogStream": "cvpn-endpoint-1234567890abcdef0"
}
Additional Resources
- AWS Client VPN Administrator Guide - Connection Logging
- AWS Client VPN Administrator Guide
- CloudWatch Logs User Guide
Notes
- No downtime: Enabling connection logging does not interrupt existing VPN connections
- Log retention: Set a retention policy on your CloudWatch log group to control storage costs
- Log content: Connection logs include connection attempts (successful and failed), client IP addresses, connection timestamps, and disconnection reasons
- IAM permissions: The Client VPN service needs permission to write to CloudWatch Logs. AWS handles this automatically when you enable logging through the console
- Cost consideration: CloudWatch Logs charges for ingestion and storage. High-traffic VPN endpoints may generate significant log volume