{"id":15968865,"url":"https://github.com/kimitrii/self-hosted-vpn","last_synced_at":"2025-07-08T05:36:56.454Z","repository":{"id":257699519,"uuid":"855556314","full_name":"kimitrii/self-hosted-vpn","owner":"kimitrii","description":"WireGuard VPN Server on AWS with Terraform","archived":false,"fork":false,"pushed_at":"2024-09-18T04:09:43.000Z","size":46,"stargazers_count":9,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T04:24:04.162Z","etag":null,"topics":["aws","ec2","vpn","wireguard"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kimitrii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-11T04:12:02.000Z","updated_at":"2024-12-22T16:07:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"0e48017f-d476-4f5c-a8c8-742e887aff44","html_url":"https://github.com/kimitrii/self-hosted-vpn","commit_stats":null,"previous_names":["kimitrii/self-hosted-vpn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimitrii%2Fself-hosted-vpn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimitrii%2Fself-hosted-vpn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimitrii%2Fself-hosted-vpn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kimitrii%2Fself-hosted-vpn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kimitrii","download_url":"https://codeload.github.com/kimitrii/self-hosted-vpn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245702595,"owners_count":20658643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","ec2","vpn","wireguard"],"created_at":"2024-10-07T19:04:20.310Z","updated_at":"2025-03-26T17:32:35.158Z","avatar_url":"https://github.com/kimitrii.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WireGuard VPN Server on AWS with Terraform\n\nThis project provides an automated setup for deploying a WireGuard VPN server on an EC2 instance running Amazon Linux 2023 using Terraform. This guide will walk you through the process of deploying the VPN server and connecting a single client, with instructions on how to add more clients if needed.\n\n## Sumary\n\n- [Requirements](#requirements)\n- [Getting Started](#getting-started)\n  - [Environment Variables](#1-environment-variables)\n  - [Infrastructure Overview](#2-infrastructure-overview)\n  - [Deployment](#3-deployment)\n    - [Running Locally](#running-locally)\n    - [Running with GitHub Actions](#running-with-github-actions)\n    - [Connecting Your Device to the VPN](#connecting-your-device-to-the-vpn)\n  - [VPN Configuration](#4-vpn-configuration)\n  - [Connecting Additional Clients](#5-connecting-additional-clients)\n  - [Remote State with S3](#6-remote-state-with-s3)\n- [Troubleshooting](#troubleshooting)\n- [Disclaimer](#disclaimer)\n\n## Requirements\n\n- AWS account with permissions to manage EC2, S3, and VPC resources.\n- SSH key pair for connecting to the EC2 instance.\n- Terraform installed on your local machine or a CI/CD pipeline.\n- `wg` (WireGuard) tool installed locally for key generation.\n\n\n## Getting Started\n\n### 1. Environment Variables\n\nThe following environment variables need to be set before running `terraform apply`:\n\n- `SERVER_PRIVATE_KEY`: (required) Private key of the WireGuard server.\n- `CLIENT_PUBLIC_KEY`: (required) Public key of the client connecting to the VPN.\n- `CLIENT_PRESHARED_KEY`: (required) Preshared key for extra encryption between the server and client.\n- `VPN_PUBLIC_KEYPAIR`: (required) SSH public key for EC2 instance access.\n- `EC2_TYPE`: (required) EC2 instance type (default: `t4g.nano` for a low-cost option).\n- `EC2_AV_ZONE`: (required) Availability zone for the EC2 instance (example: `us-east-1a`).\n- `VPN_ZONE`: (required) AWS region for the VPN (example: `us-east-1`).\n\nObs: For the CI/CD pipeline, ensure that these environment variables are set as secrets in GitHub Actions.\n\n##### Key Generation Commands\n\nTo generate the necessary keys for WireGuard, run the following commands:\n\n```bash\n# Server Private Key\nwg genkey | tee server_private.key | wg pubkey \u003e server_public.key\n\n# Client Public and Private Keys\nwg genkey | tee client_private.key | wg pubkey \u003e client_public.key\n\n# Preshared Key for Extra Security\nwg genpsk | tee client_preshared.key\n\nFor SSH access to the EC2 instance, generate the public key pair with:\nssh-keygen -t rsa -b 2048 -f /aws_ec2_key.pem\n```\n\n### 2. Infrastructure Overview\n\nThe Terraform configuration will create the following AWS architecture:\n\n![AWS diagram](/img/aws-diagram.jpg)\n\n### 3. Deployment\n\n##### Running Locally\n\n\nTo deploy the infrastructure from local machine, ensure you have the required environment variables set in a `/terraform/terraform.tfvars` file and Terraform and AWS CLI installed.\n`terraform.tfvars` exemple:\n````\nSERVER_PRIVATE_KEY   = \"\u003cyour-server-privete-key\u003e\"\nCLIENT_PUBLIC_KEY    = \"\u003cyour-client-public-key\u003e\"\nCLIENT_PRESHARED_KEY = \"\u003cyour-client-preshared-key\u003e\"\nVPN_PUBLIC_KEYPAIR   = \"\u003cyour-SSH-public-key\u003e\"\nEC2_TYPE             = \"t4g.nano\"\nEC2_AV_ZONE          = \"us-east-1a\"\nVPN_ZONE             = \"us-east-1\"\n````\n\nIf you wish to remove the remote state backend for local deployment, remove the following block from `/terraform/main.tf`:\n````\nbackend \"s3\" {\n    bucket  = \"tf-remote-state-vpn\"\n    key     = \"state/terraform.tfstate\"\n    region  = \"us-east-1\"\n    encrypt = true\n  }\n````\nThem inside `/terraform/` run:\n````\nterraform init \u0026\u0026 terraform apply -auto-approve\n````\n\n##### Running with GitHub Actions\nTo automate the deployment with GitHub Actions, the following additional environment variables need to be set for the CI/CD pipeline:\n\n- AWS_ACCESS_KEY_ID\n- AWS_SECRET_ACCESS_KEY\n\nThe user behind these credentials should have the following policies attached:\n\n- `AmazonEC2FullAccess`\n- `AmazonS3FullAccess`\n\nObs: Is required to follow the [Remote State with S3](#6-remote-state-with-s3) step to deploy with git actions\n\n##### Connecting Your Device to the VPN\n\nAfter successfully deploying the VPN server, follow these steps to connect your client device:\n\n1. Retrieve the EC2 Public IP: \n   - Go to the AWS Management Console.\n   - Navigate to EC2 Dashboard and locate the instance you just deployed.\n   - Copy the `Public IPv4 address` of the EC2 instance.\n\n2. Configure Your Client:\n   - Open your WireGuard client application (on your device).\n   - In the `[Peer]` the `Endpoint` field, paste the public IP address followed by `:51820` (which is the default port for WireGuard).\n\nExample:\n\nIf the public IP of your EC2 instance is `54.123.45.67`, set the endpoint in your client as:\n`54.123.45.67:51820`\n\n\nNow, your device should be able to connect to the VPN.\n\n\n### 4. VPN Configuration\n\nThe WireGuard configuration is automatically generated in the `/etc/wireguard/wg0.conf` file during the EC2 instance deployment.\n\nThe configuration file is created by the `/scripts/wireguard-installer.sh` script, which is executed when you launch the instance. If you need to customize the VPN settings to meet your specific requirements, you should modify the `scripts/wireguard-installer.sh` file before launch the instance with terraform.\n\n### 5. Connecting Additional Clients\nIf you want to add more clients after the VPN is running, you need to SSH into the EC2 instance and modify the /etc/wireguard/wg0.conf file. Add a new [Peer] section with the new client's PublicKey, PresharedKey, and AllowedIPs configuration.\n\nAlternatively, if you're modifying the configuration before deploying the server, you can add the new client directly in the wireguard-installer.sh file under the # Create and write VPN configuration section.\n\n### 6. Remote State with S3\n\nIf using GitHub Actions or a remote state for Terraform when deploy locally, ensure you have created an S3 bucket with versioning and access control configured. You can run `terraform apply -auto-approve` for the example configuration bellow:\n\n````\nresource \"aws_s3_bucket\" \"tf-remote-state\" {\n  bucket = \"tf-remote-state-vpn\" # Change the bucket name\n\n  tags = {\n    Name        = \"Terraform Remote State\"\n    Environment = \"Prod\"\n  }\n}\n\nresource \"aws_s3_bucket_acl\" \"tf-s3-acl\" {\n  bucket = aws_s3_bucket.tf-remote-state.id\n  acl    = \"private\"\n}\n\nresource \"aws_s3_bucket_versioning\" \"versioning_example\" {\n  bucket = aws_s3_bucket.tf-remote-state.id\n  versioning_configuration {\n    status = \"Enabled\"\n  }\n}\n````\n\nAnd the `main.tf`file will look like this:\n````\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~\u003e 5.0\"\n    }\n  }\n\n  backend \"s3\" {\n    bucket  = \"tf-remote-state-vpn\" # same bucket as aws_s3_bucket.tf-remote-state\n    key     = \"state/terraform.tfstate\"\n    region  = \"us-east-1\"\n    encrypt = true\n  }\n}\n\nprovider \"aws\" {\n  region = var.VPN_ZONE\n}\n````\n\n## Troubleshooting\n### Common Issues\n\n- Client Unable to Connect to the Internet: Ensure that the `Address` specified in the `[Interface]` section of `/etc/wireguard/wg0.conf` is within the range of the CIDR block of your subnet. If the address is not within this range, the client may connect to the VPN but not access the internet. For example, if your subnet CIDR block is `10.0.0.0/24`, the VPN address should be within this range, such as `10.0.0.2/32`.\n\n- Invalid Key Configuration: Double-check that all keys (server private key, client public key, and preshared key) are correctly generated and applied. Misconfigured or incorrect keys can prevent successful VPN connections.\n\n## Disclaimer\n\nThis project was created solely for personal use and educational purposes. I do not recommend or endorse its use for commercial or enterprise environments. If you choose to deploy this project in such environments, you do so at your own risk.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimitrii%2Fself-hosted-vpn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkimitrii%2Fself-hosted-vpn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkimitrii%2Fself-hosted-vpn/lists"}