Skip to content

Commit

Permalink
Merge pull request #1 from jmhale/feature/multi-client-support
Browse files Browse the repository at this point in the history
Add multi-client support
  • Loading branch information
jmhale authored Mar 5, 2019
2 parents 36557ba + 3ea846f commit f12683c
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 24 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog
All notable changes to this project will be documented in this file.

## [0.0.2] - 2019-03-02
### Added
- Multi-client support via the module variable.
- This CHANGELOG
### Removed
- Single-client public key via AWS SSM as it now conflicts with the module variable method.

## [0.0.1] - 2019-02-24
### Added
- Working module to deploy WireGuard with single client support.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ A Terraform module to deploy a WireGuard VPN server on AWS.
Before using this module, you'll need to generate a key pair for your server and client, and store the server's private key and client's public key in AWS SSM, which cloud-init will source and add to WireGuard's configuration.

- Install the WireGuard tools for your OS: https://www.wireguard.com/install/
- Generate a key pair for the client
- `wg genkey | tee client-privatekey | wg pubkey > client-publickey`
- Generate a key pair for each client
- `wg genkey | tee client1-privatekey | wg pubkey > client1-publickey`
- Generate a key pair for the server
- `wg genkey | tee server-privatekey | wg pubkey > server-publickey`

- Add the client public key to the AWS SSM parameter: `/wireguard/wg-laptop-public-key`
- `aws ssm put-parameter --name /wireguard/wg-laptop-public-key --type SecureString --value $ClientPublicKeyValue`
- Add the server private key to the AWS SSM parameter: `/wireguard/wg-server-private-key`
- `aws ssm put-parameter --name /wireguard/wg-server-private-key --type SecureString --value $ServerPrivateKeyValue`
- Add each client's public key, along with the next available IP address as a key:value pair to the wg_client_public_keys map. See Usage for details.

## Variables
| Variable Name | Type | Required |Description |
Expand All @@ -24,6 +22,8 @@ Before using this module, you'll need to generate a key pair for your server and
|`vpc_id`|`string`|Yes|The VPC ID in which Terraform will launch the resources.|
|`ingress_security_group_id`|`string`|Yes|The ID of the Security Group to allow SSH access from.|
|`ami_id`|`string`|No. Defaults to Ubuntu 16.04 AMI in us-east-1|The AMI ID to use.|
|`env`|`string`|No. Defaults "prod"|The environment for WireGuard|
|`wg_client_public_keys`|`list`|Yes.|List of maps of client IPs and public keys. See Usage for details.|

## Usage
```
Expand All @@ -32,6 +32,11 @@ module "wireguard" {
ssh_key_id = "ssh-key-id-0987654"
vpc_id = "vpc-01234567"
public_subnet_ids = ["subnet-01234567"]
wg_client_public_keys = [
{"192.168.2.2/32" = "QFX/DXxUv56mleCJbfYyhN/KnLCrgp7Fq2fyVOk/FWU="},
{"192.168.2.3/32" = "+IEmKgaapYosHeehKW8MCcU65Tf5e4aXIvXGdcUlI0Q="},
{"192.168.2.4/32" = "WO0tKrpUWlqbl/xWv6riJIXipiMfAEKi51qvHFUU30E="},
]
}
```

Expand Down
18 changes: 14 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ data "template_file" "user_data" {

vars {
wg_server_private_key = "${data.aws_ssm_parameter.wg_server_private_key.value}"
wg_laptop_public_key = "${data.aws_ssm_parameter.wg_laptop_public_key.value}"
peers = "${join("\n", data.template_file.wg_client_data_json.*.rendered)}"
eip_id = "${aws_eip.wireguard_eip.id}"
}
}

data "template_file" "wg_client_data_json" {
template = "${file("${path.module}/templates/client-data.tpl")}"
count = "${length(var.wg_client_public_keys)}"

vars {
client_pub_key = "${element(values(var.wg_client_public_keys[count.index]), 0)}"
client_ip = "${element(keys(var.wg_client_public_keys[count.index]), 0)}"
}
}

data "template_cloudinit_config" "config" {
part {
content_type = "text/cloud-config"
Expand All @@ -20,7 +30,7 @@ resource "aws_eip" "wireguard_eip" {
}

resource "aws_launch_configuration" "wireguard_launch_config" {
name_prefix = "wireguard-lc-"
name_prefix = "wireguard-${var.env}-lc-"
image_id = "${var.ami_id}"
instance_type = "t2.micro"
key_name = "${var.ssh_key_id}"
Expand All @@ -35,7 +45,7 @@ resource "aws_launch_configuration" "wireguard_launch_config" {
}

resource "aws_autoscaling_group" "wireguard_asg" {
name_prefix = "wireguard-asg-"
name_prefix = "wireguard-${var.env}-asg-"
max_size = 1
min_size = 1
launch_configuration = "${aws_launch_configuration.wireguard_launch_config.name}"
Expand All @@ -50,7 +60,7 @@ resource "aws_autoscaling_group" "wireguard_asg" {
tags = [
{
key = "Name"
value = "wireguard"
value = "wireguard-${var.env}"
propagate_at_launch = true
},
{
Expand Down
3 changes: 3 additions & 0 deletions templates/client-data.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Peer]
PublicKey = ${client_pub_key}
AllowedIPs = ${client_ip}
4 changes: 1 addition & 3 deletions templates/user-data.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ write_files:
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = ${wg_laptop_public_key}
AllowedIPs = 192.168.2.2/32
${peers}
runcmd:
- export INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
- export REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep -oP '\"region\"[[:space:]]*:[[:space:]]*\"\K[^\"]+')
Expand Down
9 changes: 9 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
variable "ssh_key_id" {}

variable "vpc_id" {}

variable "ami_id" {
Expand All @@ -8,3 +9,11 @@ variable "ami_id" {
variable "public_subnet_ids" {
type = "list"
}

variable "wg_client_public_keys" {
type = "list"
}

variable "env" {
default = "prod"
}
8 changes: 4 additions & 4 deletions wireguard-iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ data "aws_iam_policy_document" "wireguard_policy_doc" {
"ec2:AssociateAddress",
]

resources = ["*"] ## TODO: See if we can scope this to wireguard_eip
resources = ["*"]
}
}

resource "aws_iam_policy" "wireguard_policy" {
name = "tf-wireguard"
name = "tf-wireguard-${var.env}"
description = "Terraform Managed. Allows Wireguard instance to attach EIP."
policy = "${data.aws_iam_policy_document.wireguard_policy_doc.json}"
}

resource "aws_iam_role" "wireguard_role" {
name = "tf-wireguard"
name = "tf-wireguard-${var.env}"
description = "Terraform Managed. Role to allow Wireguard instance to attach EIP."
path = "/"
assume_role_policy = "${data.aws_iam_policy_document.ec2_assume_role.json}"
Expand All @@ -40,6 +40,6 @@ resource "aws_iam_role_policy_attachment" "wireguard_roleattach" {
}

resource "aws_iam_instance_profile" "wireguard_profile" {
name = "tf-wireguard"
name = "tf-wireguard-${var.env}"
role = "${aws_iam_role.wireguard_role.name}"
}
10 changes: 6 additions & 4 deletions wireguard-securitygroups.tf
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
resource "aws_security_group" "sg_wireguard_external" {
name = "wireguard-external"
name = "wireguard-${var.env}-external"
description = "Terraform Managed. Allow Wireguard client traffic from internet."
vpc_id = "${var.vpc_id}"

tags {
Name = "wireguard-external"
Name = "wireguard-${var.env}-external"
Project = "wireguard"
tf-managed = "True"
env = "${var.env}"
}

ingress {
Expand All @@ -25,14 +26,15 @@ resource "aws_security_group" "sg_wireguard_external" {
}

resource "aws_security_group" "sg_wireguard_admin" {
name = "wireguard-admin"
name = "wireguard-${var.env}-admin"
description = "Terraform Managed. Allow admin traffic to internal resources from VPN"
vpc_id = "${var.vpc_id}"

tags {
Name = "wireguard-admin"
Name = "wireguard-${var.env}-admin"
Project = "vpn"
tf-managed = "True"
env = "${var.env}"
}

ingress {
Expand Down
4 changes: 0 additions & 4 deletions wireguard-ssm.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
data "aws_ssm_parameter" "wg_server_private_key" {
name = "/wireguard/wg-server-private-key"
}

data "aws_ssm_parameter" "wg_laptop_public_key" {
name = "/wireguard/wg-laptop-public-key"
}

0 comments on commit f12683c

Please sign in to comment.