Skip to main content

EC2 Client VPN Connection Logging

Overview

This check verifies that AWS Client VPN endpoints have connection logging enabled. Connection logging records client connect and disconnect events to CloudWatch Logs, giving you visibility into who is using your VPN and when.

Think of it like a sign-in sheet for your VPN. Without it, you have no record of who came in or when they left.

Risk

Without connection logging enabled on Client VPN endpoints, your organization loses visibility into remote access activity:

  • Undetected compromised credentials: If an attacker obtains valid VPN credentials, their access goes unnoticed
  • No audit trail: You cannot investigate security incidents or answer "who connected when?"
  • Lateral movement: Attackers can use the VPN as an entry point and move through your network without leaving traces
  • Compliance gaps: Many security frameworks require logging of remote access for audit purposes
  • Extended dwell time: Malicious activity can continue undetected for longer periods

Connection logging is your visibility layer for all VPN access.

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to modify Client VPN endpoints
  • A CloudWatch Logs log group to receive the connection logs (you can create one during setup)
Required IAM permissions (for administrators)

Your IAM user or role needs these permissions:

  • ec2:ModifyClientVpnEndpoint
  • ec2:DescribeClientVpnEndpoints
  • logs:CreateLogGroup (if creating a new log group)
  • logs:CreateLogStream
  • logs:DescribeLogGroups

AWS Console Method

Step 1: Create a CloudWatch Log Group (if needed)

  1. Go to CloudWatch Console in us-east-1
  2. Click Log groups in the left sidebar
  3. Click Create log group
  4. Enter a name like client-vpn-connection-logs
  5. Optionally set a retention period (e.g., 90 days)
  6. Click Create

Step 2: Enable Connection Logging on the VPN Endpoint

  1. Go to VPC Console in us-east-1
  2. Click Client VPN endpoints in the left sidebar
  3. Select the VPN endpoint that needs logging enabled
  4. Click Actions > Modify Client VPN endpoint
  5. Scroll to the Connection logging section
  6. Check Enable connection logging
  7. For CloudWatch Logs log group, select your log group (e.g., client-vpn-connection-logs)
  8. Optionally specify a log stream name, or leave blank to auto-generate
  9. Click Modify Client VPN endpoint

The change takes effect immediately for new connections.

AWS CLI (optional)

Step 1: Create a CloudWatch Log Group (if needed)

aws logs create-log-group \
--log-group-name client-vpn-connection-logs \
--region us-east-1

Optionally set a retention period (e.g., 90 days):

aws logs put-retention-policy \
--log-group-name client-vpn-connection-logs \
--retention-in-days 90 \
--region us-east-1

Step 2: Enable Connection Logging

Replace <your-vpn-endpoint-id> with your Client VPN endpoint ID (e.g., cvpn-endpoint-0123456789abcdef0):

aws ec2 modify-client-vpn-endpoint \
--client-vpn-endpoint-id <your-vpn-endpoint-id> \
--connection-log-options Enabled=true,CloudwatchLogGroup=client-vpn-connection-logs \
--region us-east-1

Expected output:

{
"Return": true
}

Finding Your Client VPN Endpoint IDs

To list all Client VPN endpoints:

aws ec2 describe-client-vpn-endpoints \
--region us-east-1 \
--query 'ClientVpnEndpoints[*].{ID:ClientVpnEndpointId,Description:Description,LoggingEnabled:ConnectionLogOptions.Enabled}' \
--output table
CloudFormation (optional)

This template creates a Client VPN endpoint with connection logging enabled. If you have an existing endpoint, you will need to update it using the console or CLI methods above.

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 client IP addresses
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
Description: Number of days to retain connection logs
Default: 90
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653]

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
ServerCertificateArn: !Ref ServerCertificateArn
ClientCidrBlock: !Ref ClientCidrBlock
ConnectionLogOptions:
Enabled: true
CloudwatchLogGroup: !Ref ClientVpnLogGroup
AuthenticationOptions:
- Type: certificate-authentication
MutualAuthentication:
ClientRootCertificateChainArn: !Ref ServerCertificateArn
VpcId: !Ref VpcId
SplitTunnel: true
TransportProtocol: udp
VpnPort: 443
Tags:
- Key: Name
Value: !Sub '${AWS::StackName}-client-vpn'

ClientVpnTargetNetwork:
Type: AWS::EC2::ClientVpnTargetNetworkAssociation
Properties:
ClientVpnEndpointId: !Ref ClientVpnEndpoint
SubnetId: !Ref SubnetId

Outputs:
ClientVpnEndpointId:
Description: Client VPN endpoint ID
Value: !Ref ClientVpnEndpoint

LogGroupArn:
Description: ARN of the CloudWatch Log Group for connection logs
Value: !GetAtt ClientVpnLogGroup.Arn

Deploy with:

aws cloudformation deploy \
--template-file client-vpn-logging.yaml \
--stack-name client-vpn-with-logging \
--parameter-overrides \
ServerCertificateArn=arn:aws:acm:us-east-1:123456789012:certificate/abc123 \
VpcId=vpc-0123456789abcdef0 \
SubnetId=subnet-0123456789abcdef0 \
--region us-east-1
Terraform (optional)

This example shows how to create a Client VPN endpoint with connection logging enabled:

# Variables
variable "server_certificate_arn" {
description = "ARN of the server certificate in ACM"
type = string
}

variable "client_cidr_block" {
description = "CIDR block for client IP addresses"
type = string
default = "10.0.0.0/22"
}

variable "vpc_id" {
description = "VPC to associate with the Client VPN endpoint"
type = string
}

variable "subnet_id" {
description = "Subnet to associate with the Client VPN endpoint"
type = string
}

variable "log_retention_days" {
description = "Number of days to retain connection logs"
type = number
default = 90
}

# CloudWatch Log Group for connection logs
resource "aws_cloudwatch_log_group" "client_vpn" {
name = "/aws/client-vpn/connection-logs"
retention_in_days = var.log_retention_days

tags = {
Purpose = "Client VPN connection logging"
}
}

# Client VPN Endpoint with logging enabled
resource "aws_ec2_client_vpn_endpoint" "main" {
description = "Client VPN endpoint with connection logging"
server_certificate_arn = var.server_certificate_arn
client_cidr_block = var.client_cidr_block
vpc_id = var.vpc_id
split_tunnel = true
transport_protocol = "udp"
vpn_port = 443

# Enable connection logging
connection_log_options {
enabled = true
cloudwatch_log_group = aws_cloudwatch_log_group.client_vpn.name
}

authentication_options {
type = "certificate-authentication"
root_certificate_chain_arn = var.server_certificate_arn
}

tags = {
Name = "client-vpn-with-logging"
}
}

# Associate VPN endpoint with 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 = "Name of the CloudWatch Log Group for connection logs"
value = aws_cloudwatch_log_group.client_vpn.name
}

Deploy with:

terraform init
terraform plan \
-var="server_certificate_arn=arn:aws:acm:us-east-1:123456789012:certificate/abc123" \
-var="vpc_id=vpc-0123456789abcdef0" \
-var="subnet_id=subnet-0123456789abcdef0"
terraform apply \
-var="server_certificate_arn=arn:aws:acm:us-east-1:123456789012:certificate/abc123" \
-var="vpc_id=vpc-0123456789abcdef0" \
-var="subnet_id=subnet-0123456789abcdef0"

To enable logging on an existing endpoint managed by Terraform, add the connection_log_options block to your existing resource configuration.

Verification

After enabling connection logging, verify the configuration:

  1. Check in the VPC Console:

    • Go to VPC > Client VPN endpoints
    • Select your endpoint
    • Look at the Details tab
    • Verify Connection logging shows Enabled and lists your log group
  2. Check for logs (after a connection):

    • Go to CloudWatch > Log groups
    • Open your VPN log group (e.g., client-vpn-connection-logs)
    • After someone connects to the VPN, you should see log streams with connection events
CLI verification commands

Check if connection logging is enabled on a specific endpoint:

aws ec2 describe-client-vpn-endpoints \
--client-vpn-endpoint-ids <your-vpn-endpoint-id> \
--region us-east-1 \
--query 'ClientVpnEndpoints[0].ConnectionLogOptions'

Expected output when logging is enabled:

{
"Enabled": true,
"CloudwatchLogGroup": "client-vpn-connection-logs",
"CloudwatchLogStream": "cvpn-endpoint-0123456789abcdef0-us-east-1-..."
}

Check all endpoints and their logging status:

aws ec2 describe-client-vpn-endpoints \
--region us-east-1 \
--query 'ClientVpnEndpoints[*].{ID:ClientVpnEndpointId,LoggingEnabled:ConnectionLogOptions.Enabled,LogGroup:ConnectionLogOptions.CloudwatchLogGroup}' \
--output table

Additional Resources

Notes

  • Immediate effect: Connection logging takes effect immediately for new connections. Existing connections are not affected until they reconnect.

  • Log contents: Connection logs include timestamps, usernames (if applicable), source IP addresses, connection duration, and bytes transferred. This data is valuable for security investigations and access audits.

  • Cost considerations: CloudWatch Logs charges apply for log ingestion and storage. Set an appropriate retention period to manage costs. For most use cases, 90 days provides a good balance.

  • Log group permissions: Ensure the VPN service has permission to write to your CloudWatch log group. If you create the log group through the console when configuring the VPN, permissions are set automatically.

  • Centralized logging: Consider streaming VPN connection logs to a centralized security information and event management (SIEM) system for correlation with other security events.

  • Alerting: Set up CloudWatch alarms or metric filters on the VPN logs to alert on suspicious patterns, such as connections from unusual geographic locations or outside business hours.

  • Multiple endpoints: If you have multiple Client VPN endpoints, you must enable logging on each one individually. Consider using infrastructure as code to ensure consistent configuration across all endpoints.