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?
- Inventory every connection across regions and read each entry's VgwTelemetry, flagging any tunnel in DOWN status.
- 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.
- 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.
- 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.
More EC2 controls
- 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