# Fix AWS VPN Connection Down
Your Site-to-Site VPN connection to AWS shows as DOWN, or traffic isn't flowing between your on-premises network and VPC. VPN connections have two tunnels for redundancy, but when both fail, you lose connectivity entirely. The issue could be with the VPN configuration, your customer gateway device, routing, or even the underlying network.
This guide covers diagnosing VPN failures and restoring connectivity.
Diagnosis Commands
First, check the VPN connection status:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[*].[VpnConnectionId,State,Type,VgwTelemetry]'Get detailed tunnel telemetry:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].VgwTelemetry[*].[OutsideIpAddress,Status,StatusMessage,LastStatusChange]'Check the VPN gateway (VGW):
aws ec2 describe-vpn-gateways \
--vpn-gateway-ids vgw-1234567890abcdef0 \
--query 'VpnGateways[*].[VpnGatewayId,State,Type,VpcAttachments[*].State]'Check the customer gateway configuration:
aws ec2 describe-customer-gateways \
--customer-gateway-ids cgw-1234567890abcdef0 \
--query 'CustomerGateways[*].[CustomerGatewayId,State,Type,IpAddress,BgpAsn]'Get the VPN configuration for your device:
aws ec2 get-vpn-connection-configuration \
--vpn-connection-id vpn-1234567890abcdef0 \
--query 'VpnConnectionConfiguration'Check routes propagated to route tables:
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=vpc-12345" \
--query 'RouteTables[*].Routes[?Origin==`VpnGateway`]'Check VPC route tables for static VPN routes:
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=vpc-12345" \
--query 'RouteTables[*].Routes[?GatewayId==`vpn-1234567890abcdef0`]'Common Causes and Solutions
Tunnel Not Established
VPN tunnel shows DOWN or IPSEC_NEGOTIATION_ERROR:
Check tunnel status:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].VgwTelemetry[*].[OutsideIpAddress,Status,StatusMessage]'Common status messages and causes:
IPSEC_NEGOTIATION_ERROR: - Pre-shared keys don't match - IKE versions incompatible - Encryption algorithms mismatch
Check your customer gateway configuration:
aws ec2 get-vpn-connection-configuration \
--vpn-connection-id vpn-1234567890abcdef0 \
--output text > vpn-config.txtCompare settings with your on-premises device: - Pre-shared key (PSK) - IKE version (v1 or v2) - Encryption algorithms (AES-128, AES-256) - Integrity algorithms (SHA1, SHA2-256, SHA2-384) - Diffie-Hellman groups (2, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)
On your customer gateway device (e.g., Cisco ASA):
```bash # Check IPsec status show crypto ipsec sa
# Check IKE status show crypto ikev2 sa
# Check tunnel interface show interface tunnel0 ```
Update VPN connection options if needed:
aws ec2 modify-vpn-connection-options \
--vpn-connection-id vpn-1234567890abcdef0 \
--local-ipv4-network-cidr 10.0.0.0/16 \
--remote-ipv4-network-cidr 192.168.1.0/24BGP Not Establishing
For BGP-based VPN, the tunnel might establish but BGP doesn't:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].VgwTelemetry[*].[Status,BgpStatus]'If BGP shows DOWN:
Verify BGP ASN matches:
aws ec2 describe-customer-gateways \
--customer-gateway-ids cgw-1234567890abcdef0 \
--query 'CustomerGateways[*].BgpAsn'On your device, check BGP configuration:
```bash # Cisco example show bgp summary show bgp neighbors
# Juniper example show bgp summary show bgp neighbor 169.254.x.x ```
BGP peering uses 169.254.x.x addresses inside the tunnel:
# Get BGP peer IPs from VPN configuration
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].Routes'Ensure your device advertises correct routes:
# Cisco - advertise routes
router bgp 65000
network 192.168.1.0 mask 255.255.255.0
neighbor 169.254.x.x remote-as 64512
neighbor 169.254.x.x activateCustomer Gateway IP Wrong
The customer gateway IP doesn't match your device's public IP:
aws ec2 describe-customer-gateways \
--customer-gateway-ids cgw-1234567890abcdef0 \
--query 'CustomerGateways[*].IpAddress'Compare with your device's actual public IP:
# Check your firewall/router's WAN interface
show interface outside
# or
show interface GigabitEthernet0/0If they don't match, recreate the customer gateway:
```bash # Delete old customer gateway (must delete VPN first) aws ec2 delete-vpn-connection --vpn-connection-id vpn-1234567890abcdef0 aws ec2 delete-customer-gateway --customer-gateway-id cgw-1234567890abcdef0
# Create new with correct IP aws ec2 create-customer-gateway \ --type ipsec.1 \ --public-ip 203.0.113.50 \ --bgp-asn 65000
# Create new VPN connection aws ec2 create-vpn-connection \ --type ipsec.1 \ --customer-gateway-id cgw-new \ --vpn-gateway-id vgw-1234567890abcdef0 ```
Firewall Blocking VPN Traffic
Your on-premises firewall blocks VPN ports:
Required ports for AWS VPN: - UDP 500 (IKE) - UDP 4500 (NAT-T for IPsec) - IP protocol 50 (ESP) - if not using NAT-T
Check firewall rules:
```bash # Cisco ASA show access-list show run access-list outside_in
# Palo Alto show running security-policy ```
Add rules to allow VPN traffic:
# Cisco ASA configuration
access-list outside_in extended permit udp host 203.0.113.50 host <AWS_VPN_IP> eq 500
access-list outside_in extended permit udp host 203.0.113.50 host <AWS_VPN_IP> eq 4500
access-list outside_in extended permit esp host 203.0.113.50 host <AWS_VPN_IP>NAT Traversal Issues
If your device is behind NAT, NAT-T must be enabled:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].Options.EnableTunnelInsideNat'If your customer gateway is behind NAT:
```bash # Enable NAT traversal on your device # Cisco ASA crypto ikev2 policy 10 encryption aes-cbc-256 integrity sha256 group 19 prf sha256 lifetime seconds 28800
crypto ipsec transform-set ESP-AES-256-SHA esp-aes-256 esp-sha-hmac mode tunnel
# NAT-T is usually auto-enabled crypto map outside_map 10 set nat-t keepalive ```
Routing Not Propagated
BGP is up but routes aren't in VPC route table:
aws ec2 describe-route-tables \
--route-table-ids rtb-12345 \
--query 'RouteTables[*].Routes[?Origin==`VpnGateway`]'Enable route propagation:
aws ec2 enable-vgw-route-propagation \
--route-table-id rtb-12345 \
--gateway-id vgw-1234567890abcdef0Check if your device is advertising routes:
```bash # On your device, check advertised routes show bgp advertised-routes
# Or show route advertising-protocol bgp ```
Static Routes Not Configured
For static VPN (non-BGP), you need to add routes manually:
aws ec2 create-route \
--route-table-id rtb-12345 \
--destination-cidr-block 192.168.1.0/24 \
--gateway-id vpn-1234567890abcdef0On your side, add routes pointing to tunnel interface:
# Cisco example
ip route vrf AWS 10.0.0.0 255.255.0.0 Tunnel0VPC Attachment Issues
VGW not attached to VPC:
aws ec2 describe-vpn-gateways \
--vpn-gateway-ids vgw-1234567890abcdef0 \
--query 'VpnGateways[*].VpcAttachments[*].[VpcId,State]'If detached, attach it:
aws ec2 attach-vpn-gateway \
--vpn-gateway-id vgw-1234567890abcdef0 \
--vpc-id vpc-12345Overlapping CIDR Blocks
VPN CIDRs overlap with VPC or other networks:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[*].Options.[LocalIpv4NetworkCidr,RemoteIpv4NetworkCidr]'Check VPC CIDR:
aws ec2 describe-vpcs \
--vpc-ids vpc-12345 \
--query 'Vpcs[*].CidrBlock'If overlapping, use specific subnet CIDRs:
aws ec2 modify-vpn-connection-options \
--vpn-connection-id vpn-1234567890abcdef0 \
--local-ipv4-network-cidr 10.0.1.0/24 \
--remote-ipv4-network-cidr 192.168.1.0/24Dead Peer Detection (DPD)
DPD timeout causing tunnel resets:
AWS VPN uses DPD to detect dead peers. If your device doesn't respond, AWS tears down the tunnel.
Configure DPD on your device:
```bash # Cisco ASA crypto ikev2 dpd 10 2 on-demand
# Juniper SRX set security ike policy ike-policy1 dead-peer-detection interval 10 threshold 5 mode optimize ```
Tunnel Inside IP Conflict
Inside tunnel IPs (169.254.x.x) conflict:
aws ec2 describe-vpn-connections \
--vpn-connection-ids vpn-1234567890abcdef0 \
--query 'VpnConnections[0].VgwTelemetry[*].InsideIpAddress'If you have multiple VPNs, ensure tunnel inside IPs don't overlap. They're automatically assigned by AWS, so conflicts are rare.
Verification Steps
After fixing, verify VPN status:
```bash # Check tunnel status aws ec2 describe-vpn-connections \ --vpn-connection-ids vpn-1234567890abcdef0 \ --query 'VpnConnections[0].VgwTelemetry[*].[Status,BgpStatus,LastStatusChange]'
# Check routes
aws ec2 describe-route-tables \
--filters "Name=route.state,Values=active" "Name=route.origin,Values=VpnGateway" \
--query 'RouteTables[*].Routes[?GatewayId==vpn-1234567890abcdef0]'
```
Test connectivity:
```bash # Ping from EC2 instance to on-premises ping 192.168.1.10
# SSH or connect to on-premises server ssh user@192.168.1.10
# Check from on-premises to AWS ping 10.0.1.50 ```
VPN diagnostic script:
```bash #!/bin/bash VPN_ID="vpn-1234567890abcdef0"
echo "AWS VPN Connection Diagnostics" echo "==============================="
echo "1. VPN Connection Status:" aws ec2 describe-vpn-connections \ --vpn-connection-ids $VPN_ID \ --query 'VpnConnections[*].[VpnConnectionId,State]'
echo "" echo "2. Tunnel Telemetry:" aws ec2 describe-vpn-connections \ --vpn-connection-ids $VPN_ID \ --query 'VpnConnections[0].VgwTelemetry[*].[OutsideIpAddress,Status,BgpStatus,StatusMessage,LastStatusChange]'
echo "" echo "3. VPN Gateway Status:" VGW=$(aws ec2 describe-vpn-connections --vpn-connection-ids $VPN_ID --query 'VpnConnections[0].VpnGatewayId' --output text) aws ec2 describe-vpn-gateways \ --vpn-gateway-ids $VGW \ --query 'VpnGateways[*].[VpnGatewayId,State,VpcAttachments[*].State]'
echo "" echo "4. Customer Gateway:" CGW=$(aws ec2 describe-vpn-connections --vpn-connection-ids $VPN_ID --query 'VpnConnections[0].CustomerGatewayId' --output text) aws ec2 describe-customer-gateways \ --customer-gateway-ids $CGW \ --query 'CustomerGateways[*].[CustomerGatewayId,IpAddress,BgpAsn,State]'
echo ""
echo "5. Routes in VPC Route Tables:"
VPC=$(aws ec2 describe-vpn-gateways --vpn-gateway-ids $VGW --query 'VpnGateways[0].VpcAttachments[0].VpcId' --output text)
aws ec2 describe-route-tables \
--filters "Name=vpc-id,Values=$VPC" \
--query 'RouteTables[*].Routes[?GatewayId=='${VPN_ID}']'
echo "" echo "6. Route Propagation Status:" aws ec2 describe-route-tables \ --filters "Name=vpc-id,Values=$VPC" \ --query 'RouteTables[*].PropagatingVgws[*].GatewayId' ```
Set up monitoring:
# CloudWatch alarm for tunnel down
aws cloudwatch put-metric-alarm \
--alarm-name vpn-tunnel-down \
--alarm-description "VPN tunnel is down" \
--namespace AWS/VPN \
--metric-name TunnelState \
--dimensions Name=VpnConnectionId,Value=$VPN_ID Name=TunnelIpAddress,Value=<tunnel-ip> \
--statistic Minimum \
--period 60 \
--threshold 1 \
--comparison-operator LessThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts