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
- 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
Mappings
sections withLatestAmiId
parameter 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
CustomResource
AWS Lambda migrated over topython3.7
runtime due tonodejs6.10
no longer being supported and thenodejs8.10
runtime approaching EOL: AWS Lambda: Node.js v8.10 Runtime Approaching End of Life (EOL)- Source used for new
CustomResource
running onpython3.7
runtime 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 server
withremote-cert-tls server
in client config- Due to
ns-cert-type
slated 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-lzo
from server and client configs- Due to the VORACLE security advisory (2018)
- Replaced
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.
- Python 3 (tested on Python 3.6 and 3.7)
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.
# Target aws profile to create
AWS_VPN_PROFILE='testprofile'
# Configure Access Keys
aws configure --profile $AWS_VPN_PROFILE
# 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
aws cloudformation deploy \
--template-file cfn-openvpn.yaml \
--stack-name openvpn-personal \
--profile $AWS_VPN_PROFILE \
--parameter-overrides SSHKeyName=$SSHKEYPAIR \
--capabilities CAPABILITY_IAM
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