This repository contains the AWS Lambda function and API Gateway setup instructions for controlling a personal OpenVPN server on AWS. It's part of a larger project created during a sabbatical in Taipei to build a complete VPN solution with iOS app control. The Lambda code was generated with assistance from AI tools (ChatGPT and Claude).
This API provides a secure interface to control an EC2 instance running OpenVPN through:
- REST API endpoints using API Gateway
- Lambda function for EC2 control
- API key authentication
- Status monitoring capabilities
The API is designed to work with:
- VPN Infrastructure created via Terraform
- VPNControl iOS App for remote management
The API provides these endpoints:
POST /vpn
GET  /vpn/status
- start: Start the VPN instance
- stop: Stop the VPN instance
- status: Get current instance state
The Lambda function (handler.py) manages EC2 instance operations:
def lambda_handler(event, context):
    action = ""
    if "queryStringParameters" in event and event["queryStringParameters"] is not None:
        action = event["queryStringParameters"].get("action", "").lower()
    elif "action" in event and event["action"] is not None:
        action = event.get("action", "").lower()
    
    # Handle start/stop/status actions
    try:
        if action == "start":
            ec2.start_instances(InstanceIds=[INSTANCE_ID])
            message = f"Instance {INSTANCE_ID} is starting."
        # ... additional action handling- Go to IAM Console → Create role
- Select AWS Service → Lambda
- Attach these policies:
- AWSLambdaBasicExecutionRole
- Custom EC2 control policy:
 
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:DescribeInstances"
            ],
            "Resource": "arn:aws:ec2:your-region:your-account-id:instance/*"
        }
    ]
}- 
Create new Lambda function: - Author from scratch
- Runtime: Python 3.9+
- Attach IAM role from Step 1
 
- 
Set environment variables: - EC2_ID: Your VPN instance ID
 
- 
Upload handler.pycode
- Create REST API
- Create resource "/vpn"
- Add methods:
- POST for control actions
- GET for status
 
- Integration setup:
- Type: Lambda Function
- Lambda Proxy integration: Yes
- Lambda Function: Select your function
 
- 
Enable API key requirement: - Method Request settings
- Set "API Key Required" to true
 
- 
Create API key: - API Gateway → API Keys
- Create new key
- Add to Usage Plan
 
- 
CORS configuration (if needed): - Enable CORS in API Gateway
- Allow necessary headers
 
- Deploy API:
- Create new stage (e.g., "prod")
- Note the Invoke URL
- Save API key for client use
 
curl -X POST "https://your-api-id.execute-api.your-region.amazonaws.com/prod/vpn" \
     -H "x-api-key: your-api-key" \
     -H "Content-Type: application/json" \
     -d '{"action": "start"}'curl -X GET "https://your-api-id.execute-api.your-region.amazonaws.com/prod/vpn/status" \
     -H "x-api-key: your-api-key"curl -X POST "https://your-api-id.execute-api.your-region.amazonaws.com/prod/vpn" \
     -H "x-api-key: your-api-key" \
     -H "Content-Type: application/json" \
     -d '{"action": "stop"}'Successful response:
{
    "statusCode": 200,
    "body": {
        "message": "Instance i-1234567890abcdef0 is starting."
    }
}Error response:
{
    "statusCode": 400,
    "body": {
        "message": "Invalid action. Use 'start', 'stop', or 'status'."
    }
}- 
API Key Protection: - Never commit API keys to source control
- Rotate keys periodically
- Use Usage Plans to limit request rates
 
- 
IAM Permissions: - Follow principle of least privilege
- Restrict EC2 actions to specific instance
- Enable CloudWatch logging
 
- 
Network Security: - Enable HTTPS only
- Configure CORS appropriately
- Consider VPC endpoints for added security
 
- 
CloudWatch Logs: - Lambda function logs
- API Gateway access logs
- Errors and debugging information
 
- 
Metrics to Monitor: - API Gateway 4xx/5xx errors
- Lambda execution duration
- Lambda throttling
- API key usage
 
- Fork the repository
- Create a feature branch
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- AWS for the serverless platform
- ChatGPT and Claude for code generation assistance
For questions or suggestions, please open an issue in the repository.