Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · EC2

EC2.20: Both Site-to-Site VPN tunnels should be up

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub EC2.20 check?

EC2.20 checks that both tunnels of a Site-to-Site VPN connection report UP status and fails the moment either tunnel goes DOWN. It reads the per-tunnel Status field inside VgwTelemetry from describe-vpn-connections, backed by the AWS Config rule vpc-vpn-2-tunnels-up.

Why does EC2.20 matter?

AWS provisions two tunnels per connection across two AZs purely for high availability — if one drops, traffic should fail over silently. The trap is that a connection running on a single tunnel works perfectly until that last tunnel hiccups during maintenance, a BGP reconvergence, or a key rotation, and then there is nothing left to fail over to. The redundancy has degraded from two-of-two to one-of-one and nobody noticed.

How do I fix EC2.20?

  1. Inventory every connection across regions and read each entry's VgwTelemetry, flagging any tunnel in DOWN status.
  2. Diagnose the cause from StatusMessage and timing before changing anything — usually a firewall blocking UDP 500/4500, a key/proposal mismatch, or an idle SA timing out.
  3. Fix the root cause, then harden it: set StartupAction=start so AWS proactively initiates IKE, and generate periodic traffic so the SA does not idle out.
  4. Publish a CloudWatch alarm on the AWS/VPN TunnelState metric (1=up, 0=down) per tunnel wired to on-call paging.

Remediation script · bash

# List every Site-to-Site VPN that currently has a tunnel DOWN.
aws ec2 describe-vpn-connections \
  --query 'VpnConnections[?VgwTelemetry[?Status==`DOWN`]].VpnConnectionId' --output text

# Lock a tunnel to IKEv2 only and turn logging on, one tunnel at a time.
aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0a1b2c3d4e5f6a7b8 \
  --vpn-tunnel-outside-ip-address 203.0.113.20 \
  --tunnel-options '{"IKEVersions":[{"Value":"ikev2"}],"StartupAction":"start","LogOptions":{"CloudWatchLogOptions":{"LogEnabled":true,"LogGroupArn":"arn:aws:logs:us-east-1:111122223333:log-group:/aws/vpn/s2s","LogOutputFormat":"json"}}}'

# Turn on connection logging for a Client VPN endpoint.
aws ec2 modify-client-vpn-endpoint \
  --client-vpn-endpoint-id cvpn-endpoint-0a1b2c3d4e5f6a7b8 \
  --connection-log-options Enabled=true,CloudwatchLogGroup=/aws/clientvpn/prod-access

# Alarm on tunnel state (0 = down) so the next drop pages on-call, not the next scan.
aws cloudwatch put-metric-alarm --alarm-name vpn-tunnel2-down \
  --namespace AWS/VPN --metric-name TunnelState \
  --dimensions Name=VpnId,Value=vpn-0a1b2c3d4e5f6a7b8 Name=TunnelIpAddress,Value=203.0.113.20 \
  --statistic Minimum --period 300 --evaluation-periods 1 \
  --threshold 1 --comparison-operator LessThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:111122223333:network-oncall

Full walkthrough (console steps, edge cases and verification) in the lesson Secure Site-to-Site VPN connections.

Is EC2.20 a false positive?

The connection still passing traffic on one tunnel is exactly why this looks like noise — but a single-tunnel VPN is a latent outage, not a healthy state. The finding is real even though nothing is currently broken.

Part of the learning path Trim your network spend
  • EC2.1 An EBS snapshot is publicly restorable by any account
  • EC2.2 Default security groups still allow traffic
  • EC2.3 Attached EBS volumes are not encrypted at rest
  • EC2.4 Long-stopped instances are abandoned attack surface
  • EC2.6 No VPC flow logs, so there is no network audit trail
  • EC2.7 New EBS volumes are not encrypted by default
  • EC2.8 IMDSv1 lets an SSRF steal instance credentials
  • EC2.9 Instances are directly reachable on public IPv4
  • EC2.10 EC2 API traffic leaves the VPC over the internet
  • EC2.13 SSH (port 22) is open to the entire internet
  • EC2.14 RDP (port 3389) is open to the entire internet
  • EC2.15 Subnets auto-assign public IPs to new instances