openvpn-cfn
openvpn-cfn copied to clipboard
Roll your own Amazon Linux 2 OpenVPN with AWS CloudFormation (w/ Dynamically Discovered Latest AMI Id via Parameter Store)

Deploy OpenVPN to AWS via CloudFormation and Amazon Linux 2
This is a new and improved version of a CFN template blogged about by Linux Academy.
To read a detailed blog post on how it was setup, checkout: Deploy an OpenVPN Instance to AWS with CloudFormation
NOTE: This worked much more like a personal learning tool, and I'd rather recommend something like AlgoVPN when it comes to deploying and managing your own VPN in AWS due to the community and expertise around the project.
If you want to see the original OpenVPN CFN template that I worked on fixing/expanding, taking note that it is out-dated and no longer functional, you can take a look at it here:
The following blog articles walkthrough how the base CFN template was initially created, along with full descriptions as to why each resource is used:
- How to Roll Your Own VPN with AWS CloudFormation – Part One
- How to Roll Your Own VPN with AWS CloudFormation – Part Two
- How to Roll Your Own VPN with AWS CloudFormation – Part Three
Updates in This New CFN Template
- Updated for Amazon Linux 2
- Added parameter for specifying OpenVPN version. Default: version
2.4.7(latest available, tested version from EPEL as of November, 2019) - Updated to export single OVPN instead of .zip of client configuration
- Replaced AMI
Mappingssections withLatestAmiIdparameter dynamically referencing AWS Systems Manager Parameter Store for latest Amazon Linux 2 AMI ID in relative region (by default)- A simple lookup is now available to CFN templates, as seen here: Query for the latest Amazon Linux AMI IDs using AWS Systems Manager Parameter Store
CustomResourceAWS Lambda migrated over topython3.7runtime due tonodejs6.10no longer being supported and thenodejs8.10runtime approaching EOL: AWS Lambda: Node.js v8.10 Runtime Approaching End of Life (EOL)- Source used for new
CustomResourcerunning onpython3.7runtime came from: custom-resource-s3-bucket-delete
- Source used for new
- Updated for Easy-RSA v3.x
- Parameterized OpenVPN port and protocol
- Parameterized
EASYRSA_ALGO(Default: rsa, but can also be ec) andEASYRSA_REQ_CN(Default:ChangeMe) Easy-RSA vars - Updated OpenVPN client and server config values
- Replaced
ns-cert-type serverwithremote-cert-tls serverin client config- Due to
ns-cert-typeslated for full deprecation by v2.5.x of OpenVPN, and due to mobile clients (Android / iOS) currently erroring out if present
- Due to
- Removed
comp-lzofrom server and client configs- Due to the VORACLE security advisory (2018)
- Replaced
Step-by-Step Deployment
This can be done via the GUI by uploading the cfn-openvpn.yaml while creating a stack, in the AWS Console, or it can be done via the CLI. If going through the GUI, an SSH key pair needs to be made first via the EC2 service.
Otherwise, keep following for a CLI approach to the deployment that sets up a Python virtualenv, creates an SSH key pair, and deploys the CFN stack.
Prerequisites
- Python 3 (tested on Python 3.6 and 3.7)
awscli Setup
Checkout awscli v2 if needed. Using the CLI can make deployments of CFN templates much easier, following the below steps.
NOTE: Don't install awscli via pypi (ex.
pip install awscli), as that is awscli v1.
awscli Setup: Configure AWS CLI Profile
# Target aws profile to create
AWS_VPN_PROFILE='testprofile'
# Configure Access Keys
aws configure --profile $AWS_VPN_PROFILE
Create EC2 SSH Key Pair
# Target aws profile to use
AWS_VPN_PROFILE='testprofile'
# Generate SSH Key Pair; set file permissions (Linux/MacOS)
SSHKEYPAIR='openvpn'
aws ec2 create-key-pair \
--key-name $SSHKEYPAIR \
--output text \
--profile $AWS_VPN_PROFILE \
--query 'KeyMaterial' > $SSHKEYPAIR.pem
chmod 400 $SSHKEYPAIR.pem
Create OpenVPN via CFN
aws cloudformation deploy \
--template-file cfn-openvpn.yaml \
--stack-name openvpn-personal \
--profile $AWS_VPN_PROFILE \
--parameter-overrides SSHKeyName=$SSHKEYPAIR \
--capabilities CAPABILITY_IAM
[Optional] Access OpenVPN EC2 Instance
OPENVPNIP=`aws cloudformation describe-stacks \
--stack-name openvpn-personal \
--profile $AWS_VPN_PROFILE \
--output text \
| grep OpenVPNEIP \
| sed s/^.*EIP// \
| tr -d '[:blank:]'`
ssh -i $SSHKEYPAIR.pem ec2-user@$OPENVPNIP