GithubHelp home page GithubHelp logo

jmhale / terraform-aws-wireguard Goto Github PK

View Code? Open in Web Editor NEW
129.0 5.0 138.0 114 KB

Terraform module to deploy WireGuard on AWS

License: GNU General Public License v3.0

HCL 87.39% Smarty 0.95% Shell 11.65%
terraform terraform-modules wireguard vpn aws

terraform-aws-wireguard's Introduction

terraform-aws-wireguard

A Terraform module to deploy a WireGuard VPN server on AWS. Can also used to run one or more servers behind a loadbalancer, for redundancy.

Prerequisites

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 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 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
subnet_ids list Yes A list of subnets for the Autoscaling Group to use for launching instances. May be a single subnet, but it must be an element in a list.
ssh_key_id string Yes A SSH public key ID to add to the VPN instance.
vpc_id string Yes The VPC ID in which Terraform will launch the resources.
env string Optional - defaults to prod The name of environment for WireGuard. Used to differentiate multiple deployments.
use_eip bool Optional Whether to attach an Elastic IP address to the VPN server. Useful for avoiding changing IPs.
eip_id string Optional When use_eip is enabled, specify the ID of the Elastic IP to which the VPN server will attach.
target_group_arns string Optional The Loadbalancer Target Group to which the vpn server ASG will attach.
additional_security_group_ids list Optional Used to allow added access to reach the WG servers or allow loadbalancer health checks.
asg_min_size integer Optional - default to 1 Number of VPN servers to permit minimum, only makes sense in loadbalanced scenario.
asg_desired_capacity integer Optional - default to 1 Number of VPN servers to maintain, only makes sense in loadbalanced scenario.
asg_max_size integer Optional - default to 1 Number of VPN servers to permit maximum, only makes sense in loadbalanced scenario.
instance_type string Optional - defaults to t2.micro Instance Size of VPN server.
wg_server_net cidr address and netmask Yes The server ip allocation and net - wg_client_public_keys entries MUST be in this netmask range.
wg_client_public_keys list Yes List of maps of client IP/netmasks and public keys. See Usage for details. See Examples for formatting.
wg_server_port integer Optional - defaults to 51820 Port to run wireguard service on, wireguard standard is 51820.
wg_persistent_keepalive integer Optional - defaults to 25 Regularity of Keepalives, useful for NAT stability.
wg_server_private_key_param string Optional - defaults to /wireguard/wg-server-private-key The Parameter Store key to use for the VPN server Private Key.
ami_id string Optional - defaults to the newest Ubuntu 16.04 AMI AMI to use for the VPN server.
wg_server_interface string Optional - defaults to eth0 Server interface to route traffic to for installations forwarding traffic to private networks.

Examples

Please see the following examples to understand usage with the relevant options.

Simple Elastic IP/public subnet usage

See examples/simple_eip/main.tf file.

Complex Elastic Load Balancer/private subnet usage

See examples/complex_elb/main.tf file.

Outputs

Output Name Description
vpn_asg_name The name of the wireguard Auto Scaling Group
vpn_sg_admin_id ID of the internal Security Group to associate with other resources needing to be accessed on VPN.
vpn_sg_external_id ID of the external Security Group to associate with the VPN.

Caveats

  • I would strongly recommend forking this repo or cloning it locally and change the source definition to be something that you control. You really don't want your infra to be at the mercy of my changes.

terraform-aws-wireguard's People

Contributors

atrull avatar exolab avatar hlarsen avatar jmhale avatar sgarner avatar sheeeng avatar wheller avatar wpietri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

terraform-aws-wireguard's Issues

awscli secretsmanager usage update

in the README you have an older format to put the secrets into AWS SecretsManager. The updated format is as follows:

aws secretsmanager create-secret --name /wireguard/wg-server-private-key --secret-string $secretstring

Updating userdata (adding clients) causes clients to fail to reconnect to new instance.

Having an odd (maybe not?) issue where when I update the userdata (add new clients), and it spins up a new launch config/ASG, existing clients fail to automatically reconnect. The config is still valid, but I need to manually hit these devices with a

wg-quick down wg0
wg-quick up wg0

before they work again. If I check the systemctl status, the service is running, but fails to detect that the connection is down.

Server config:

[Interface]
Address = 10.0.0.1/24
PrivateKey = <redacted>
ListenPort = 51820
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens5 -j MASQUERADE

[Peer]
PublicKey = <redacted>
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25

Client config:

[Interface]
PrivateKey = <redacted>
Address = 10.0.0.2/32

[Peer]
PublicKey = <redacted>
AllowedIPs = 10.0.0.0/16, 10.33.0.0/16
Endpoint = dns_name.url.com:51820
PersistentKeepalive = 25

and here's my module invoke:

module "wireguard" {
  source = "../../modules/wireguard-vpn"

  env                           = var.env_short
  ssh_key_id                    = var.key_pair
  vpc_id                        = module.vpc.vpc_id
  subnet_ids                    = module.vpc.public_subnets
  instance_profile              = data.terraform_remote_state.global.outputs.instance_profile_ec2
  additional_security_group_ids = [aws_security_group.base.id]
  wg_server_private_key_param   = "/${var.env_short}/wireguard/wg-server-private-key"
  asg_min_size                  = 1
  asg_desired_capacity          = 1
  asg_max_size                  = 1
  wg_subnet_cidr                = module.vpc.public_subnets_cidr_blocks
  wg_server_net                 = "10.0.0.1/24" # client IPs MUST exist in this net
  wg_client_public_keys = [
    { (var.public_keys["1"]) = (data.aws_ssm_parameter.wg_public_key["1"].value) },   #Client1 (Hector)
  ]
}

"aws_ssm_parameter" "wg_server_private_key":

I always get:

Error: Error describing SSM parameter: ParameterNotFound: 

  on .terraform/modules/vpc.wireguard/wireguard-ssm.tf line 1, in data "aws_ssm_parameter" "wg_server_private_key":
   1: data "aws_ssm_parameter" "wg_server_private_key" {

either I set the param to:
wg_server_private_key_param = "/wireguard/wg-server-private-key"
or not.

the param has been set via the cli - I've double checked.

The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created.

module "wireguard" {
  source = "[email protected]:jmhale/terraform-wireguard.git?ref=v1.0.0"
}
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.wireguard.data.template_file.wg_client_data_json[2]: Refreshing state...
module.wireguard.data.template_file.wg_client_data_json[0]: Refreshing state...
module.wireguard.data.template_file.wg_client_data_json[1]: Refreshing state...
module.wireguard.data.aws_ssm_parameter.wg_server_private_key: Refreshing state...
module.wireguard.data.aws_iam_policy_document.wireguard_policy_doc: Refreshing state...
module.wireguard.data.aws_iam_policy_document.ec2_assume_role: Refreshing state...
module.wireguard.data.aws_ami.ubuntu: Refreshing state...

------------------------------------------------------------------------

Warning: Interpolation-only expressions are deprecated

  on .terraform/modules/wireguard/main.tf line 64, in resource "aws_autoscaling_group" "wireguard_asg":
  64:   name                 = "${aws_launch_configuration.wireguard_launch_config.name}"

Terraform 0.11 and earlier required all non-constant expressions to be
provided via interpolation syntax, but this pattern is now deprecated. To
silence this warning, remove the "${ sequence from the start and the }"
sequence from the end of this expression, leaving just the inner expression.

Template interpolation syntax is still used to construct strings from
expressions when the template includes multiple interpolation sequences or a
mixture of literal strings and interpolations. This deprecation applies only
to templates that consist entirely of a single interpolation sequence.


Error: Invalid count argument

  on .terraform/modules/wireguard/wireguard-iam.tf line 28, in resource "aws_iam_policy" "wireguard_policy":
  28:   count              = (var.eip_id != "disabled" ? 1 : 0) # only used for EIP mode

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.


Error: Invalid count argument

  on .terraform/modules/wireguard/wireguard-iam.tf line 36, in resource "aws_iam_role" "wireguard_role":
  36:   count              = (var.eip_id != "disabled" ? 1 : 0) # only used for EIP mode

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

where is usage?

Hi @jmhale ! Love your terraform module, and am testing it to build an instance. I keep reading in various places in the commentary about the "Usage" section but haven't been able to locate it.

Also, your code for secretsmanager usage is out of date. I will be submitting a separate issue for that one :)

release is v1.0.0, tag is 1.0.0

this causes issues using [email protected]:jmhale/terraform-wireguard.git?ref=v1.0.0 as a source in tf - using 1.0.0 instead of v1.0.0 works.

the other tags are all prefixed with v so i'm guessing this was unintentional.

Why do we need to specify next available ip

I plan to deploy wiregaurd on a public subnet. I would like to know why we need to specify the next available public ip? Since there are other instances as well in the same public subnet, how can I be aware of the next available public ip.

Thanks and appreciate any help on this,
Rohin

having trouble getting EIP to associate

Hey @jmhale

so, after many trials, I'm getting the following issue:

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.wireguard.data.template_file.wg_client_data_json[0]: Refreshing state...
module.wireguard.data.aws_iam_policy_document.wireguard_policy_doc: Refreshing state...
module.wireguard.data.aws_ssm_parameter.wg_server_private_key: Refreshing state...
module.wireguard.data.aws_ami.ubuntu: Refreshing state...
module.wireguard.data.aws_iam_policy_document.ec2_assume_role: Refreshing state...


Error: Invalid count argument

on .terraform/modules/wireguard/wireguard-iam.tf line 28, in resource "aws_iam_policy" "wireguard_policy":
28: count = (var.eip_id != "disabled" ? 1 : 0) # only used for EIP mode

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

Error: Invalid count argument

on .terraform/modules/wireguard/wireguard-iam.tf line 36, in resource "aws_iam_role" "wireguard_role":
36: count = (var.eip_id != "disabled" ? 1 : 0) # only used for EIP mode

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

-0-0-0-0-0-0-0--0-00-0-0-0-0--00-0-0-0-0-0-0-

Now, if I manually provide the EIP id, it works but hilariously by creating it's OWN EIP that is WON'T associate with the EC2 instance it creates -_-

Any help here? What could I be missing?

working instance can be killed before new one is ready

Issue #18 exposes another problem. The creation of a new box failed while running the user-data script. But the working VPN was killed anyhow. Is there some way for it to fail safely, so that the working VPN stays up until a working replacement is ready?

wg-server udp port 51820 open to 0.0.0.0/0

Hi
i have to ask two things:

  1. Regarding wireguard-server, we configure a security group which allows everyone to connect on udp port 51820. Is it needed by design or can we avoid this open udp port for everyone. How much is this insecure then?

  2. what does %i here means when we add iptables command:
    PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Thanks

wireguard PPA no longer valid

Today I added somebody to the VPN, as I had a number of times before. To my surprise, the VPN stopped working for everybody. After a fair bit of digging, I discovered this in the logs:

Aug  3 18:03:41 ip-172-31-13-114 systemd[1]: Starting Execute cloud user/final scripts...
Aug  3 18:03:41 ip-172-31-13-114 cloud-init[1806]: #!/bin/bash -v
Aug  3 18:03:41 ip-172-31-13-114 cloud-init[1806]: add-apt-repository "ppa:wireguard/wireguard"
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]:  #033[1m
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: ==========================================================================
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: DEPRECATION NOTICE: These packages have now moved into Ubuntu 20.04,
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: 19.10, 18.04, and 16.04. Therefore this PPA only has packages for Ubuntu
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: 14.04. However, we are planning to sunset this PPA and 14.04 support with
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: it. For that reason, if you are in fact using this PPA with 14.04, and
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: would like us to maybe reconsider the deprecation of this PPA, please
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: email us at team {at} wireguard.com to explain why it's inconvenient for
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: you to upgrade to a newer Ubuntu release and the size of your deployment.
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: If you're reading this because you're following an online tutorial on
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: installing WireGuard, please contact the authors to request that they
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: simplify their instructions to simply:
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]:     $ sudo apt install wireguard
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: This PPA is no longer required for WireGuard. Press CTRL+C, and do not
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: proceed with adding it.
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: More information can be found at:
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: - https://lists.zx2c4.com/pipermail/wireguard/2020-August/005737.html
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: - https://lists.zx2c4.com/pipermail/wireguard/2020-July/005670.html
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: ==========================================================================
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: #033[0m
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: WireGuard is a novel VPN that runs inside the Linux Kernel. This is the
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: Ubuntu packaging for WireGuard. More info may be found at its website,
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: listed below.
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: More info: https://www.wireguard.com/
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: Packages: wireguard wireguard-tools wireguard-dkms
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]: Install with: $ sudo apt install wireguard
Aug  3 18:03:42 ip-172-31-13-114 cloud-init[1806]:  More info: https://launchpad.net/~wireguard/+archive/ubuntu/wireguard
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: keyring `/tmp/tmpl7t0j4rn/secring.gpg' created
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: keyring `/tmp/tmpl7t0j4rn/pubring.gpg' created
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: requesting key 504A1A25 from hkp server keyserver.ubuntu.com
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: /tmp/tmpl7t0j4rn/trustdb.gpg: trustdb created
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: key 504A1A25: public key "Launchpad PPA for wireguard-ppa" imported
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg: Total number processed: 1
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: gpg:               imported: 1  (RSA: 1)
Aug  3 18:03:43 ip-172-31-13-114 cloud-init[1806]: OK

Hand-installing wireguard from the official repo and then hand-running the rest of the userdata script seems to have fixed things. I'm not going to mess with our VPN right now while people are using it, but perhaps it's sufficient to drop the ppa line in user-data.txt?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.