This repo contains modules for running a production-ready OpenVPN server and managing OpenVPN user accounts. The modules are:
- init-openvpn - initializes the public key infrastructure (PKI) via OpenSSL for use by OpenVPN. Designed to be run via user-data on boot
- install-openvpn - Scripts to install the OpenVPN image in a packer-generated AMI
- openvpn-admin - A command-line utility to request and revoke certificates and to process those requests
- openvpn-server - Terraform templates that deploy OpenVPN
- start-openvpn-admin - Scripts to start openvpn-admin on the openvpn-server in order to process certificate requests and revocations
Note: The OpenVPN tools offer partial Ubuntu 20.04 support, but have not been tested fully for compatibility with other Gruntwork modules. For the release notes, checkout this PR that adds support for Ubuntu 20.04. For issues or contributions, please follow the Contributions section of this README, or simply raise a Github issue.
The openvpn-server module will deploy a single server into an Auto Scaling Group (ASG) for redundancy
purposes. Should the server fail, a new server will be automatically provisioned by the ASG. Upon initial boot, the
init-openvpn module will establish a new public key infrastructure (PKI), including
a Certificate Authority (CA), server certificate and a certificate revocation list. These assets will then be backed up
to an S3 bucket and encrypted for protection should a server failure occur.
In a failure scenario, when a replacement server is started by the ASG, the PKI will be automatically restored from the S3 bucket ensuring the previously-issued client certificates will continue to function.
Users who are members of the proper IAM group will use the openvpn-admin utility to request
a new certificate. Behind the scenes, this certificate request will be sent to the server via an SQS queue, will be signed by
the server and an OpenVPN client configuration file (.ovpn) with the certificates embedded will be written to disk on the
requestor's workstation. This .ovpn
file can then be imported into any number of popular OpenVPN clients.
Users who are members of the proper IAM group will be allowed to use the same openvpn-admin utility to revoke an existing user's certificate. Behind the scenes, the revocation requests will be sent to the server via an SQS queue, the certificate will be revoked and a confirmation will be sent to back to the requestor's workstation.
If your IAM users are defined in one AWS account (e.g., security account) and the OpenVPN server is deployed in another
account (e.g., the dev or prod account), then in order for users to be able to request or revoke OpenVPN certificates,
they will need access to the SQS queues in the account with the OpenVPN server. When deploying the openvpn-server
module, you can specify the ARNs of the AWS account where IAM users are defined using the
external_account_arns
parameter, and the module will create two IAM roles—one for users and one for admins—that can be
assumed by users in those accounts to get access to the SQS queues. See the how to switch between accounts
documentation
for instructions on assuming IAM roles in other AWS accounts.
Your VPN users may have problems connecting to multiple VPNs at the same time, unless you follow these best practices:
- Make sure that your VPC CIDRs do not overlap.
- Make sure that your VPN subnet CIDRs do not overlap. For example, use
172.16.1.0
for Dev,172.16.2.0
for Prod, and so on. - Make sure that your
openvpn-server
module'suser-data/user-data.sh
includes--search-domain "${search_domain}"
in its arguments toinit-openvpn
, and pass the appropriate search domain in to the user data template object. See the example here for details. - Use Viscosity rather than Tunnelblick. Tunnelblick does not support setting DNS nameservers when connecting to multiple VPNs at the same time, and suffers from a bug that clobbers the state of your internet connection if you ever connect to more than one VPN at a time.
At Gruntwork, we've taken the thousands of hours we spent building infrastructure on AWS and condensed all that experience and code into pre-built packages or modules. Each module is a battle-tested, best-practices definition of a piece of infrastructure, such as a VPC, ECS cluster, or an Auto Scaling Group. Modules are versioned using Semantic Versioning to allow Gruntwork clients to keep up to date with the latest infrastructure best practices in a systematic way.
Most of our modules contain either:
- Terraform code
- Scripts & binaries
To use a module in your Terraform templates, create a module
resource and set its source
field to the Git URL of
this repo. You should also set the ref
parameter so you're fixed to a specific version of this repo, as the master
branch may have backwards incompatible changes (see module
sources).
For example, to use v1.0.0
of the openvpn module, you would add the following:
module "openvpn-server" {
source = "git::git@github.com:gruntwork-io/module-openvpn.git//modules/openvpn-server?ref=v1.0.0"
// set the parameters for the OpenVPN module
}
Note: the double slash (//
) is intentional and required. It's part of Terraform's Git syntax (see module
sources).
See the module's documentation and vars.tf
file for all the parameters you can set. Run terraform get -update
to
pull the latest version of this module from this repo before runnin gthe standard terraform plan
and
terraform apply
commands.
You can install the scripts and binaries in the modules
folder of any repo using the Gruntwork
Installer. For example, if the scripts you want to install are
in the modules/mongodb-scripts
folder of the https://github.com/gruntwork-io/terraform-aws-mongodb repo, you could install them
as follows:
gruntwork-install --module-name "init-openvpn" --repo "https://github.com/gruntwork-io/terraform-aws-openvpn" --tag "0.0.1"
See the docs for each script & binary for detailed instructions on how to use them.
We are following the principles of Semantic Versioning. During initial development, the major
version is to 0 (e.g., 0.x.y
), which indicates the code does not yet have a stable API. Once we hit 1.0.0
, we will
follow these rules:
- Increment the patch version for backwards-compatible bug fixes (e.g.,
v1.0.8 -> v1.0.9
). - Increment the minor version for new features that are backwards-compatible (e.g.,
v1.0.8 -> v1.1.0
). - Increment the major version for any backwards-incompatible changes (e.g.
v1.0.8 -> v2.0.0
).
The version is defined using Git tags. Use GitHub to create a release, which will have the effect of adding a git tag.
See the examples folder for sample code to build the openvpn-admin binary, a packer template to build an AMI and Terraform code to launch everything necessary to run OpenVPN in your AWS environment.
See the test folder for details.
Checkout this PR that adds support for Ubuntu 20.04
- Update the conditional logic in the
init-vpn
&install-vpn
bin/install.sh
scripts to allow the required OS distro. Other modules may also need updating. - Update the packer example to have a configuration for the new OS build
- Use Packer to create a new AMI.
- Apply some of the example terraform code (e.g.
openvpn-host
). - SSH into the EC2 instance and see if there's any error logs - e.g. in the
user-data
log. - Test by requesting a new certificate from the server.
Please see LICENSE.txt for details on how the code in this repo is licensed.
- Convert to CIDR format for parameters