mirror of
https://github.com/cdr/code-server.git
synced 2025-12-09 18:02:16 +01:00
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
182 lines
5.9 KiB
HCL
182 lines
5.9 KiB
HCL
# VPN Module for Code-Server
|
|
# Creates AWS Client VPN endpoint for secure access to private resources
|
|
|
|
# CloudWatch Log Group for VPN connection logs
|
|
resource "aws_cloudwatch_log_group" "vpn" {
|
|
name = "/aws/vpn/${var.name_prefix}"
|
|
retention_in_days = var.log_retention_days
|
|
|
|
tags = var.tags
|
|
}
|
|
|
|
resource "aws_cloudwatch_log_stream" "vpn" {
|
|
name = "vpn-connection-logs"
|
|
log_group_name = aws_cloudwatch_log_group.vpn.name
|
|
}
|
|
|
|
# Client VPN Endpoint
|
|
resource "aws_ec2_client_vpn_endpoint" "main" {
|
|
description = "Client VPN endpoint for ${var.name_prefix}"
|
|
server_certificate_arn = var.server_certificate_arn
|
|
client_cidr_block = var.client_cidr_block
|
|
split_tunnel = var.split_tunnel
|
|
vpc_id = var.vpc_id
|
|
|
|
# Authentication using certificate-based or Active Directory
|
|
authentication_options {
|
|
type = var.authentication_type
|
|
root_certificate_chain_arn = var.authentication_type == "certificate-authentication" ? var.client_certificate_arn : null
|
|
|
|
# For Active Directory authentication
|
|
active_directory_id = var.authentication_type == "directory-service-authentication" ? var.active_directory_id : null
|
|
}
|
|
|
|
# Additional authentication option for MFA (optional)
|
|
dynamic "authentication_options" {
|
|
for_each = var.enable_saml_authentication ? [1] : []
|
|
content {
|
|
type = "federated-authentication"
|
|
saml_provider_arn = var.saml_provider_arn
|
|
self_service_saml_provider_arn = var.self_service_saml_provider_arn
|
|
}
|
|
}
|
|
|
|
# Connection logging
|
|
connection_log_options {
|
|
enabled = true
|
|
cloudwatch_log_group = aws_cloudwatch_log_group.vpn.name
|
|
cloudwatch_log_stream = aws_cloudwatch_log_stream.vpn.name
|
|
}
|
|
|
|
# DNS servers to use
|
|
dns_servers = var.dns_servers
|
|
|
|
# Transport protocol
|
|
transport_protocol = var.transport_protocol
|
|
|
|
# VPN port
|
|
vpn_port = var.vpn_port
|
|
|
|
# Session timeout
|
|
session_timeout_hours = var.session_timeout_hours
|
|
|
|
# Client connect options (for custom authorization)
|
|
dynamic "client_connect_options" {
|
|
for_each = var.enable_client_connect_handler ? [1] : []
|
|
content {
|
|
enabled = true
|
|
lambda_function_arn = var.client_connect_lambda_arn
|
|
}
|
|
}
|
|
|
|
# Client login banner
|
|
dynamic "client_login_banner_options" {
|
|
for_each = var.client_login_banner != "" ? [1] : []
|
|
content {
|
|
enabled = true
|
|
banner_text = var.client_login_banner
|
|
}
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-vpn-endpoint"
|
|
}
|
|
)
|
|
}
|
|
|
|
# Associate VPN endpoint with subnets
|
|
resource "aws_ec2_client_vpn_network_association" "main" {
|
|
count = length(var.subnet_ids)
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
subnet_id = var.subnet_ids[count.index]
|
|
|
|
lifecycle {
|
|
# The issue why we are ignoring changes is that on the first resource creation, its terraform-aws-client-vpn-endpoint
|
|
# This will change on AWS's next apply to the instance ID.
|
|
ignore_changes = [subnet_id]
|
|
}
|
|
}
|
|
|
|
# Authorization rule to allow access to VPC CIDR
|
|
resource "aws_ec2_client_vpn_authorization_rule" "vpc_access" {
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
target_network_cidr = var.vpc_cidr
|
|
authorize_all_groups = var.authorize_all_groups
|
|
access_group_id = var.authorize_all_groups ? null : var.access_group_id
|
|
description = "Allow access to VPC"
|
|
}
|
|
|
|
# Additional authorization rules for specific CIDRs
|
|
resource "aws_ec2_client_vpn_authorization_rule" "additional" {
|
|
count = length(var.additional_authorization_rules)
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
target_network_cidr = var.additional_authorization_rules[count.index].cidr
|
|
authorize_all_groups = var.additional_authorization_rules[count.index].authorize_all_groups
|
|
access_group_id = var.additional_authorization_rules[count.index].access_group_id
|
|
description = var.additional_authorization_rules[count.index].description
|
|
}
|
|
|
|
# Route to direct traffic to the VPC
|
|
resource "aws_ec2_client_vpn_route" "vpc_route" {
|
|
count = var.split_tunnel ? 1 : 0
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
destination_cidr_block = var.vpc_cidr
|
|
target_vpc_subnet_id = aws_ec2_client_vpn_network_association.main[0].subnet_id
|
|
description = "Route to VPC"
|
|
|
|
depends_on = [aws_ec2_client_vpn_network_association.main]
|
|
}
|
|
|
|
# Additional routes for specific networks
|
|
resource "aws_ec2_client_vpn_route" "additional" {
|
|
count = length(var.additional_routes)
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
destination_cidr_block = var.additional_routes[count.index].cidr
|
|
target_vpc_subnet_id = aws_ec2_client_vpn_network_association.main[0].subnet_id
|
|
description = var.additional_routes[count.index].description
|
|
|
|
depends_on = [aws_ec2_client_vpn_network_association.main]
|
|
}
|
|
|
|
# Security group for VPN endpoint
|
|
resource "aws_security_group" "vpn" {
|
|
name_prefix = "${var.name_prefix}-vpn-"
|
|
description = "Security group for Client VPN endpoint"
|
|
vpc_id = var.vpc_id
|
|
|
|
ingress {
|
|
description = "VPN traffic"
|
|
from_port = var.vpn_port
|
|
to_port = var.vpn_port
|
|
protocol = var.transport_protocol == "tcp" ? "tcp" : "udp"
|
|
cidr_blocks = var.vpn_ingress_cidr_blocks
|
|
}
|
|
|
|
egress {
|
|
description = "Allow all outbound"
|
|
from_port = 0
|
|
to_port = 0
|
|
protocol = "-1"
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
}
|
|
|
|
tags = merge(
|
|
var.tags,
|
|
{
|
|
Name = "${var.name_prefix}-vpn-sg"
|
|
}
|
|
)
|
|
|
|
lifecycle {
|
|
create_before_destroy = true
|
|
}
|
|
}
|
|
|
|
# Apply security group to VPN endpoint
|
|
resource "aws_ec2_client_vpn_endpoint_security_group_association" "main" {
|
|
count = var.apply_security_group ? 1 : 0
|
|
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.main.id
|
|
security_group_id = aws_security_group.vpn.id
|
|
}
|