This commit adds comprehensive VPN infrastructure to enable secure, certificate-based access to code-server deployments. VPN provides an additional security layer by requiring network-level authentication before accessing internal resources. Features: - AWS Client VPN endpoint with certificate-based authentication - Split tunnel support (route only VPC traffic through VPN) - CloudWatch logging for all VPN connections - Multi-platform client support (Windows, macOS, Linux, iOS, Android) - Automatic certificate generation and ACM upload - Client configuration export scripts - Integration with both EC2 and EKS deployments New Terraform Module: - modules/vpn: Complete AWS Client VPN infrastructure - VPN endpoint with configurable authentication - Network associations for HA across multiple AZs - Authorization rules for VPC access - Security groups for VPN traffic - CloudWatch log groups and streams - Support for SAML/federated authentication Scripts: - scripts/generate-vpn-certificates.sh: Generate and upload VPN certificates - Creates CA, server, and client certificates - Automatically uploads to AWS Certificate Manager - Outputs certificate ARNs for Terraform configuration - scripts/export-vpn-config.sh: Export client VPN configuration - Downloads VPN config from AWS - Embeds client certificates - Creates platform-ready .ovpn files Deployment Updates: - EC2 and EKS deployments now support optional VPN - New variables for VPN configuration - Updated outputs to include VPN endpoint information - Example configurations with VPN settings Documentation: - VPN-SETUP-GUIDE.md: Comprehensive VPN setup guide - Certificate generation process - Terraform configuration - Client setup for all major platforms - Testing and troubleshooting - Advanced configuration options - Cost considerations and optimization Configuration Options: - Certificate-based or SAML/SSO authentication - Split tunnel (recommended) or full tunnel - UDP (faster) or TCP (more reliable) transport - Configurable session timeout (8-24 hours) - Custom DNS servers - Client login banner - Multiple authorization rules Security Features: - X.509 certificate authentication - Private subnet associations - Network-level access control - Session logging and audit trail - Support for multi-factor (VPN cert + OAuth2/SAML) Cost: ~$216/month base + ~$0.40/user/day for active connections
14 KiB
AWS Client VPN Setup Guide for Code-Server
This guide explains how to set up AWS Client VPN to securely access your code-server deployment. With VPN enabled, users must connect to the VPN before accessing code-server, adding an extra layer of security.
Table of Contents
- Overview
- Why Use VPN
- Architecture
- Prerequisites
- Setup Steps
- Client Setup
- Testing VPN Connection
- Advanced Configuration
- Troubleshooting
- Cost Considerations
Overview
AWS Client VPN is a managed client-based VPN service that enables you to securely access your AWS resources from any location using an OpenVPN-based VPN client.
Key Features
- Certificate-based Authentication: Secure authentication using X.509 certificates
- Split Tunneling: Only route VPC traffic through VPN (internet traffic goes direct)
- Session Logging: CloudWatch logs for all VPN connections
- Multi-platform Support: Works on Windows, macOS, Linux, iOS, and Android
- High Availability: AWS managed service with automatic failover
Why Use VPN
Security Benefits
- Network-Level Access Control: VPN required before accessing code-server
- Hide Internal Infrastructure: ALB and resources stay completely private
- Additional Authentication Layer: Certificates + OAuth2/SAML = multi-factor
- Audit Trail: All VPN connections logged in CloudWatch
- IP Whitelisting Alternative: No need to manage IP allowlists
Use Cases
- Fully Private Deployment: No public endpoints at all
- Compliance Requirements: Meet regulatory requirements for private access
- Remote Team Access: Secure access for distributed teams
- Development Environments: Keep dev/staging completely isolated
Architecture
With VPN Enabled
User Device
↓
AWS Client VPN Endpoint (Certificate Auth)
↓
Private Subnets
↓
Internal ALB → OAuth2 Proxy → Code-Server
↓
Private EC2/EKS Resources
VPN Network Flow
- User connects to VPN with client certificate
- VPN assigns IP from client CIDR (172.16.0.0/22 by default)
- VPN routes VPC traffic (10.0.0.0/16) through tunnel
- User accesses internal ALB at private IP
- OAuth2 Proxy provides SAML/OIDC authentication
- Code-Server accessible only via VPN
Prerequisites
- OpenSSL installed (for certificate generation)
- AWS CLI configured with appropriate permissions
- Terraform >= 1.0
- IAM permissions to:
- Create VPN endpoints
- Import certificates to ACM
- Create CloudWatch log groups
- Modify security groups
Setup Steps
1. Generate VPN Certificates
VPN requires server and client certificates for authentication.
cd terraform/scripts
# Generate certificates (will upload to ACM automatically)
./generate-vpn-certificates.sh [cert-dir] [region] [common-name]
# Example:
./generate-vpn-certificates.sh ./vpn-certs us-east-1 code-server-vpn
This script:
- Creates a Certificate Authority (CA)
- Generates server certificate
- Generates client certificate
- Uploads both to AWS Certificate Manager
- Outputs certificate ARNs for Terraform
Output Files:
ca.key- CA private key (keep secure!)ca.crt- CA certificateserver.key- Server private key (keep secure!)server.crt- Server certificateclient.key- Client private key (distribute to users)client.crt- Client certificate (distribute to users)certificate-arns.txt- ARNs for Terraformterraform-vars.txt- Terraform configuration snippet
Security Note:
- Store
ca.keyandserver.keysecurely (never share these!) - Back up all certificates securely
- Distribute
client.keyandclient.crtto authorized users only
2. Configure Terraform
Edit your terraform.tfvars file:
# EC2 or EKS deployment
# Enable VPN
enable_vpn = true
# Certificate ARNs from step 1
vpn_server_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/xxxxx"
vpn_client_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/yyyyy"
# VPN Configuration
vpn_client_cidr_block = "172.16.0.0/22" # Must not overlap with VPC CIDR
vpn_split_tunnel = true # Recommended
vpn_transport_protocol = "udp" # udp (faster) or tcp
vpn_port = 443 # 443 or 1194
vpn_session_timeout_hours = 24 # 8-24 hours
vpn_client_login_banner = "Welcome to Code-Server VPN. Authorized access only."
# Make ALB internal (required for VPN-only access)
internal_alb = true
3. Deploy VPN
Deploy the infrastructure with VPN enabled:
# EC2 Deployment
cd deployments/ec2
terraform apply
# EKS Deployment
cd deployments/eks
terraform apply
Terraform will create:
- Client VPN Endpoint
- VPN Network Associations (in private subnets)
- Authorization Rules (allow access to VPC CIDR)
- Security Group for VPN
- CloudWatch Log Group for VPN connections
Deployment Time: ~5-10 minutes for VPN endpoint to become available
4. Export Client Configuration
After deployment completes, export the VPN client configuration:
cd terraform/scripts
# Auto-detect VPN endpoint from Terraform state
./export-vpn-config.sh
# Or specify manually
./export-vpn-config.sh <vpn-endpoint-id> [region] [output-dir] [cert-dir]
# Example:
./export-vpn-config.sh cvpn-endpoint-0123456789abcdef0 us-east-1 ./vpn-config ./vpn-certs
This script:
- Downloads VPN configuration from AWS
- Embeds client certificate and key
- Creates platform-ready
.ovpnfile
Output: code-server-vpn.ovpn - ready to distribute to users
5. Distribute to Users
Securely distribute these files to authorized users:
code-server-vpn.ovpn- VPN configuration file
Distribution Methods:
- Encrypted email
- Secure file sharing (e.g., 1Password, encrypted USB)
- MDM system for corporate devices
- Secure internal portal
Client Setup
macOS
-
Install Tunnelblick (free, open-source)
brew install --cask tunnelblick # Or download from https://tunnelblick.net/ -
Import Configuration
- Double-click
code-server-vpn.ovpn - Tunnelblick will import it automatically
- Double-click
-
Connect
- Click Tunnelblick icon in menu bar
- Select "Connect code-server-vpn"
- VPN should connect within a few seconds
Windows
-
Install OpenVPN Connect
- Download from https://openvpn.net/client-connect-vpn-for-windows/
- Install and launch
-
Import Configuration
- File → Import Profile
- Select
code-server-vpn.ovpn
-
Connect
- Click "Connect" on the profile
- Wait for connection to establish
Linux
-
Install OpenVPN
# Debian/Ubuntu sudo apt-get update sudo apt-get install openvpn # RHEL/CentOS sudo yum install openvpn # Arch sudo pacman -S openvpn -
Connect
sudo openvpn --config code-server-vpn.ovpn -
Run as Service (optional)
sudo cp code-server-vpn.ovpn /etc/openvpn/client/code-server.conf sudo systemctl start openvpn-client@code-server sudo systemctl enable openvpn-client@code-server
iOS
-
Install OpenVPN Connect
- Download from App Store
-
Transfer Configuration
- Email to yourself, or
- Use AirDrop, or
- Upload to iCloud/Dropbox
-
Import and Connect
- Open
.ovpnfile - Import to OpenVPN Connect
- Tap "Connect"
- Open
Android
-
Install OpenVPN for Android
- Download from Google Play Store
-
Transfer Configuration
- Email to yourself, or
- Upload to Google Drive/Dropbox
-
Import and Connect
- Open
.ovpnfile - Import to OpenVPN
- Tap "Connect"
- Open
Testing VPN Connection
1. Connect to VPN
Connect using your platform's VPN client (see Client Setup above).
2. Verify VPN Connection
macOS/Linux:
# Check VPN interface
ifconfig | grep tun
# Check VPN IP assignment
ifconfig tun0 # or tun1, etc.
# Should show IP in 172.16.0.0/22 range
Windows:
# Check VPN adapter
ipconfig | findstr "172.16"
3. Test Access to Code-Server
Get the internal ALB DNS name:
# From Terraform output
terraform output alb_dns_name # EC2
# Or
kubectl get ingress -n code-server # EKS
Access code-server:
# EC2
curl -I http://<alb-dns-name>
# EKS
curl -I http://<alb-dns-name>
Expected Result: You should get a redirect to OAuth2 login or code-server login page.
4. Check CloudWatch Logs
View VPN connection logs:
aws logs tail /aws/vpn/<prefix> --follow
You should see connection events with your IP address.
Advanced Configuration
Multiple Client Certificates
To create additional client certificates for different users:
# Generate new client cert
openssl genrsa -out client2.key 2048
openssl req -new -key client2.key -out client2.csr
openssl x509 -req -days 3650 -in client2.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client2.crt
# Create user-specific .ovpn file
./export-vpn-config.sh <vpn-endpoint-id> us-east-1 ./user2-config ./
# Manually replace client cert/key in the .ovpn file
SAML/SSO Authentication
For enterprise deployments, use SAML-based authentication instead of certificates:
# terraform.tfvars
vpn_authentication_type = "federated-authentication"
enable_saml_authentication = true
saml_provider_arn = "arn:aws:iam::123456789012:saml-provider/YourSAMLProvider"
This combines VPN (network access) with SAML (user authentication).
Split Tunnel Configuration
Enabled (default - recommended):
vpn_split_tunnel = true
- Only VPC traffic (10.0.0.0/16) routed through VPN
- Internet traffic goes directly
- Better performance for users
Disabled (full tunnel):
vpn_split_tunnel = false
- All traffic routed through VPN
- More secure but slower
- Required for some compliance scenarios
Custom DNS Servers
Route DNS queries through VPN:
vpn_dns_servers = ["10.0.0.2"] # VPC DNS resolver
Session Timeout
Configure VPN session duration:
vpn_session_timeout_hours = 12 # 8-24 hours
Users will be disconnected after this period and must reconnect.
Troubleshooting
Connection Fails
Check Certificate Validity:
openssl x509 -in client.crt -text -noout
# Verify "Not After" date
Check VPN Endpoint Status:
aws ec2 describe-client-vpn-endpoints \
--client-vpn-endpoint-ids <endpoint-id>
Check CloudWatch Logs:
aws logs tail /aws/vpn/<prefix> --follow
Cannot Access Code-Server After Connecting
1. Verify VPN IP Assignment:
ifconfig | grep 172.16 # macOS/Linux
ipconfig | findstr "172.16" # Windows
2. Check Authorization Rules:
aws ec2 describe-client-vpn-authorization-rules \
--client-vpn-endpoint-id <endpoint-id>
3. Check Security Groups:
# Verify VPN security group allows traffic to ALB
aws ec2 describe-security-groups --group-ids <sg-id>
4. Test DNS Resolution:
nslookup <alb-dns-name>
dig <alb-dns-name>
Split Tunnel Not Working
Check routing table after VPN connection:
macOS/Linux:
netstat -rn | grep tun
# Should only see VPC CIDR (10.0.0.0/16) routes
Windows:
route print | findstr "172.16"
Certificate Expired
Certificates are valid for 10 years by default. To renew:
- Generate new certificates (see Step 1)
- Update certificate ARNs in Terraform
- Run
terraform apply - Export new client configuration
- Distribute to users
Cost Considerations
AWS Client VPN Pricing (as of 2024)
Endpoint Association:
- $0.10 per hour per subnet association
- For 3 subnets (multi-AZ): ~$216/month
Connection Time:
- $0.05 per hour per connection
- For 10 active users (8 hrs/day): ~$88/month
Total Estimated Cost:
- Base: ~$216/month (always running)
- Variable: ~$0.40 per user per day
Cost Optimization:
-
Single Subnet Association (not recommended for production):
subnet_ids = [module.vpc.private_subnet_ids[0]] # Only one AZSaves: ~$140/month (but loses HA)
-
Scheduled VPN (for dev environments):
- Use Lambda to disable VPN outside business hours
- Potential savings: ~50-70%
-
Alternative: Direct Connect or Site-to-Site VPN:
- For office connectivity: Site-to-Site VPN ($0.05/hr = ~$36/month)
- For large teams: Direct Connect (higher setup, lower per-GB cost)
Security Best Practices
-
Certificate Management:
- Store CA private key in HSM or secure vault
- Rotate certificates annually
- Revoke certificates for departed users
-
Monitoring:
- Set up CloudWatch Alarms for unusual connection patterns
- Review VPN logs regularly
- Alert on failed authentication attempts
-
Network Segmentation:
- Use separate subnets for VPN clients if needed
- Apply additional security groups for VPN traffic
- Implement network ACLs for defense in depth
-
Multi-Factor Authentication:
- Combine VPN (certificate) + OAuth2/SAML for true MFA
- Optionally add SAML to VPN itself for triple-factor
-
Access Control:
- Use separate client certificates per user for audit trail
- Implement IP-based restrictions if needed
- Regular access reviews
Additional Resources
Support
For issues or questions:
- Check Troubleshooting section
- Review CloudWatch Logs
- Check AWS VPN endpoint status
- Consult main README.md