Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
OpenVPN Cloudformation template
{
"Description": "EC2 OpenVPN host for stage-railz",
"Mappings": {
"AmiMap": {
"us-east-1": {
"bastion": "ami-2757f631",
"ecs": "ami-b2df2ca4",
"ubuntu1604": "ami-2757f631"
},
"us-west-2": {
"bastion": "ami-7ac6491a",
"ecs": "ami-022b9262",
"ubuntu1604": "ami-7ac6491a"
}
}
},
"Parameters": {
"AvailabilityZones": {
"Description": "Availability Zones to deploy instances in.",
"Type": "CommaDelimitedList"
},
"DefaultSG": {
"Description": "Top level security group.",
"Type": "AWS::EC2::SecurityGroup::Id"
},
"ImageName": {
"Default": "bastion",
"Description": "The image name to use from the AMIMap (usually found in the config file.)",
"Type": "String"
},
"InstanceType": {
"Default": "m3.medium",
"Description": "EC2 Instance Type",
"Type": "String"
},
"MaxSize": {
"Default": "1",
"Description": "Maximum # of instances.",
"Type": "Number"
},
"MinSize": {
"Default": "1",
"Description": "Minimum # of instances.",
"Type": "Number"
},
"OfficeNetwork": {
"Default": "0.0.0.0/0",
"Description": "CIDR block allowed to connect to bastion hosts.",
"Type": "String"
},
"PrivateSubnets": {
"Description": "Subnets to deploy private instances in.",
"Type": "List<AWS::EC2::Subnet::Id>"
},
"PublicSubnets": {
"Description": "Subnets to deploy public instances in.",
"Type": "List<AWS::EC2::Subnet::Id>"
},
"S3VpnKeysBucketName": {
"Description": "The S3 bucket that contains the keys for the OpenVPN server",
"Type": "String"
},
"SshKeyName": {
"Type": "AWS::EC2::KeyPair::KeyName"
},
"VpcCidr": {
"Description": "The name of this VPC for tagging",
"Type": "String"
},
"VpcId": {
"Description": "Vpc Id",
"Type": "AWS::EC2::VPC::Id"
},
"VpcName": {
"Description": "The name of this VPC for tagging",
"Type": "String"
}
},
"Resources": {
"AllowSSHAnywhere": {
"Properties": {
"FromPort": 22,
"GroupId": {
"Ref": "DefaultSG"
},
"IpProtocol": "tcp",
"SourceSecurityGroupId": {
"Ref": "BastionSG"
},
"ToPort": 22
},
"Type": "AWS::EC2::SecurityGroupIngress"
},
"BastionAccessPolicy": {
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"ec2:AssociateAddress",
"ec2:Describe",
"ec2:ModifyInstanceAttribute"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Action": [
"s3:Get*"
],
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "S3VpnKeysBucketName"
}
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "S3VpnKeysBucketName"
},
"/*"
]
]
}
]
}
]
},
"PolicyName": "BastionAccessPolicy",
"Roles": [
{
"Ref": "BastionRole"
}
]
},
"Type": "AWS::IAM::Policy"
},
"BastionAutoscalingGroup": {
"Properties": {
"AvailabilityZones": {
"Ref": "AvailabilityZones"
},
"LaunchConfigurationName": {
"Ref": "BastionLaunchConfig"
},
"MaxSize": {
"Ref": "MaxSize"
},
"MinSize": {
"Ref": "MinSize"
},
"Tags": [
{
"Key": "Name",
"PropagateAtLaunch": true,
"Value": "stage-railz.openvpn"
},
{
"Key": "Application",
"PropagateAtLaunch": true,
"Value": {
"Ref": "AWS::StackId"
}
},
{
"Key": "network",
"PropagateAtLaunch": true,
"Value": "public"
}
],
"VPCZoneIdentifier": {
"Ref": "PublicSubnets"
}
},
"Type": "AWS::AutoScaling::AutoScalingGroup"
},
"BastionInstanceProfile": {
"Properties": {
"Path": "/",
"Roles": [
{
"Ref": "BastionRole"
}
]
},
"Type": "AWS::IAM::InstanceProfile"
},
"BastionLaunchConfig": {
"Properties": {
"AssociatePublicIpAddress": "true",
"IamInstanceProfile": {
"Ref": "BastionInstanceProfile"
},
"ImageId": {
"Fn::FindInMap": [
"AmiMap",
{
"Ref": "AWS::Region"
},
{
"Ref": "ImageName"
}
]
},
"InstanceType": {
"Ref": "InstanceType"
},
"KeyName": {
"Ref": "SshKeyName"
},
"SecurityGroups": [
{
"Ref": "DefaultSG"
},
{
"Ref": "BastionSG"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash -x\nfunction base {\n echo \"=== Boostrap Starting \"\n apt-get update\n apt-get install -y curl python-pip\n DEBIAN_FRONTEND=noninteractive apt-get install -y iptables-persistent\n pip install awscli\n\n # IP Configuration\n aws ec2 modify-instance-attribute --no-source-dest-check --instance-id `curl http://169.254.169.254/latest/meta-data/instance-id` --region ",
{
"Ref": "AWS::Region"
},
"\n\n cat <<EOT > /etc/iptables/rules.v4\n*nat\n:PREROUTING ACCEPT [85:4110]\n:INPUT ACCEPT [84:4046]\n:OUTPUT ACCEPT [70:11051]\n:POSTROUTING ACCEPT [0:0]\n-A POSTROUTING -s 172.20.0.0/16 -o eth0 -j MASQUERADE\n-A POSTROUTING -s 172.29.0.0/20 -o eth0 -j MASQUERADE\nCOMMIT\n# Completed on Tue Mar 28 11:19:00 2017\n# Generated by iptables-save v1.6.0 on Tue Mar 28 11:19:00 2017\n*filter\n:INPUT ACCEPT [2584:919039]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [2388:528346]\n-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT\n-A FORWARD -s 172.20.0.0/16 -i eth0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\n-A FORWARD -s 172.29.0.0/20 -i tun0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\n-A FORWARD -s 172.29.0.0/20 -d 172.20.0.0/16 -i tun0 -o eth0 -m conntrack --ctstate NEW -j ACCEPT\nCOMMIT\nEOT\n\n iptables-restore < /etc/iptables/rules.v4\n\n echo \"net.ipv4.ip_forward = 1\" >> /etc/sysctl.conf\n sysctl -p\n\n # OpenVPN configuration\n\n mkdir -p /etc/openvpn/keys\n aws s3 cp s3://",
{
"Ref": "S3VpnKeysBucketName"
},
" /etc/openvpn/keys --recursive --include \"ca.crt\" --include \"server.crt\" --include \"server.key\" --include \"dh2048.pem\"\n chmod -R 0600 /etc/openvpn/keys\n aws s3 cp s3://",
{
"Ref": "S3VpnKeysBucketName"
},
"/server.conf /etc/openvpn\n aws s3 cp s3://",
{
"Ref": "S3VpnKeysBucketName"
},
"/ldap.conf /etc/openvpn\n\n cat <<EOT >/etc/pam.d/openvpn\nauth sufficient pam_ldap.so config=/etc/openvpn/ldap.conf\nauth required pam_deny.so\naccount required pam_ldap.so config=/etc/openvpn/ldap.conf\naccount required pam_permit.so\nEOT\n\n DEBIAN_FRONTEND=noninteractive apt-get install -y libpam-ldap\n\n apt-get install -y openvpn \n systemctl start openvpn@server\n\n echo \"=== Boostrap complete \"\n}\n\nbase 2>&1 | tee /tmp/bootstrap.log\n"
]
]
}
}
},
"Type": "AWS::AutoScaling::LaunchConfiguration"
},
"BastionRole": {
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"Path": "/"
},
"Type": "AWS::IAM::Role"
},
"BastionSG": {
"Properties": {
"GroupDescription": "BastionSecurityGroup",
"SecurityGroupIngress": [
{
"CidrIp": {
"Ref": "OfficeNetwork"
},
"FromPort": 1194,
"IpProtocol": "udp",
"ToPort": 1194
}
],
"VpcId": {
"Ref": "VpcId"
}
},
"Type": "AWS::EC2::SecurityGroup"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.