Deploying a VPN server to AWS

As you would expect, there are several good options to do that. You can use a commercial product such as a virtual appliance from CISCO or Juniper or use an open source solution such as OpenVPN. In addition, we also need to decide how to deploy our VPN. We can use an EC2 instance or a container and an ELB.

For these kinds of off-the-shelf solutions, one of the fastest ways to get going is to use the AWS Marketplace (http://amzn.to/2snWDXn). If you look at the different solutions offered in terms of VPN, you will see one for SoftEther which is completely free (http://amzn.to/2rDDDqF):

SoftEther is an open source VPN server which supports many protocols including L2TP/IPSec. The good thing about this protocol is that Windows, Mac, Linux, and most switches and routers will support this protocol natively so you don't have to install a custom VPN client to establish the VPN connection.

We will install this appliance by creating a CloudFormation template for it. Using a product from the marketplace such as SoftEther is easy; you simply need to point to the correct AMI ID to start using it.

We will create a new script and call it vpnserver-cf-template.py:

  1. The script starts, as always, with our boilerplates: import, template variable, and description:
"""Generating CloudFormation template.""" 
 
from troposphere import ( 
    ec2, 
    GetAtt, 
    Output, 
    Parameter, 
    Ref, 
    Template, 
    Select, 
) 
 
t = Template() 
 
t.add_description("Effective DevOps in AWS: SoftEtherVPN Server") 
  1. Next, we will add the different parameters needed to correctly deploy our VPN. We will request an SSHkeypair, the VPC ID, and the public subnets since our VPN needs to be accessible from the internet:
t.add_parameter(Parameter( 
    "KeyPair", 
    Description="Name of an existing EC2KeyPair to SSH", 
    Type="AWS::EC2::KeyPair::KeyName", 
    ConstraintDescription="must be the name of an existing EC2KeyPair." 
)) 
 
t.add_parameter(Parameter( 
    "VpcId", 
    Type="AWS::EC2::VPC::Id", 
    Description="VPC" 
)) 
 
t.add_parameter(Parameter( 
    "PublicSubnet", 
    Description="PublicSubnet", 
    Type="List<AWS::EC2::Subnet::Id>", 
    ConstraintDescription="PublicSubnet" 
)) 
  1. We will now configure our security group. We need to open UDP 4500, UDP 500, and TCP 443. Note that we aren't opening the SSH port. If you ever need to SSH to that instance, you can update the template to also open TCP 22. In addition, we are setting the VpcId parameter so that the security group gets created in the proper VPC:
t.add_resource(ec2.SecurityGroup( 
    "VPNSecurityGroup", 
    GroupDescription="SoftEther security group", 
    SecurityGroupIngress=[ 
        ec2.SecurityGroupRule( 
            IpProtocol="udp", 
            FromPort="4500", 
            ToPort="4500", 
            CidrIp="0.0.0.0/0", 
        ), 
        ec2.SecurityGroupRule( 
            IpProtocol="udp", 
            FromPort="500", 
            ToPort="500", 
            CidrIp="0.0.0.0/0", 
        ), 
        ec2.SecurityGroupRule( 
            IpProtocol="tcp", 
            FromPort="443", 
            ToPort="443", 
            CidrIp="0.0.0.0/0", 
        ) 
    ], 
    VpcId=Ref("VpcId") 
))
  1. The only other resource we need is the EC2 instance that will run our VPN. We will specify the image ID of the SoftEther appliance and create a network interface on one of the public subnets provided. In this case, we are keeping the code fairly simple so we will simply extract the first public subnet provided at creation time to configure our network interface:
t.add_resource(ec2.Instance( 
    "server", 
    ImageId="ami-a4c7edb2", 
    InstanceType="t2.micro", 
    KeyName=Ref("KeyPair"), 
    NetworkInterfaces=[ 
        ec2.NetworkInterfaceProperty( 
            GroupSet=[Ref("VPNSecurityGroup")], 
            AssociatePublicIpAddress='true', 
            SubnetId=Select("0", Ref("PublicSubnet")), 
            DeviceIndex='0', 
        )] 
)) 
  1. The last portion of our template will contain information to configure the VPN client. To prevent anyone from connecting to the VPN, the VPN server will by default, use the instance-id as a password and a preshared key for authentication:
t.add_output(Output( 
    "VPNAddress", 
    Description="VPN address", 
    Value=GetAtt("server", "PublicIp") 
)) 
 
t.add_output(Output( 
    "VPNUser", 
    Description="VPN username", 
    Value="vpn" 
)) 
 
t.add_output(Output( 
    "VPNPassword", 
    Description="VPN password", 
    Value=Ref("server") 
)) 
 
t.add_output(Output( 
    "VPNL2TP", 
    Description="L2TPpreshared key for authentication", 
    Value=Ref("server") 
)) 
 
t.add_output(Output( 
    "VPNAdminPassword", 
    Description="Password to connect administration mode", 
    Value=Ref("server") 
)) 
  1. Lastly, we will print out the template, using the code:
print t.to_json() 

Our template is ready to be used. It should look as follows: http://bit.ly/2v1UJQ0.

You can commit the changes:

$ git add vpnserver-cf-template.py
$ git commit -m "Adding a template for the SoftEther VPN server"
$ git push
$ python vpnserver-cf-template.py > vpnserver-cf.template

We can now deploy it. We will do it using the CLI. We will first extract our VPC ID and the first public subnet id as we will need those IDs to create our stack:

$ aws ec2 describe-vpcs --query 'Vpcs[].[VpcId,CidrBlock]' --output text
vpc-f7dc4093 172.31.0.0/16
vpc-2bac0452 10.10.0.0/16
$ aws ec2 describe-subnets --query 'Subnets[].SubnetId' 
--filters 'Name=tag:Name,Values=vpc-10 Public A' --output text
subnet-2aed4070

We can now create our new CloudFormation stack as follows (adapt the ID using the output of the previous commands):

$ aws cloudformation create-stack 
--stack-name vpn
--capabilities CAPABILITY_IAM
--template-body file://vpnserver-cf.template
--parameters
ParameterKey=KeyPair,ParameterValue=EffectiveDevOpsAWS
ParameterKey=VpcId,ParameterValue=vpc-2bac0452
ParameterKey=PublicSubnet,ParameterValue=subnet-2aed4070

Once the template is deployed, you can look at the template output to get the information needed to configure your computer to connect to SoftEther, as follows:

$ aws cloudformation describe-stacks 
--stack-name vpn
--query 'Stacks[0].Outputs'
[
{
"Description": "VPN username",
"OutputKey": "VPNUser",
"OutputValue": "vpn"
},
{
"Description": "VPN address",
"OutputKey": "VPNAddress",
"OutputValue": "54.234.114.241"
},
{
"Description": "VPN password",
"OutputKey": "VPNPassword",
"OutputValue": "i-04cc709357306118e"
},
{
"Description": "L2TPpreshared key for authentication",
"OutputKey": "VPNL2TP",
"OutputValue": "i-04cc709357306118e"
},
{
"Description": "Password to connect administration mode",
"OutputKey": "VPNAdminPassword",
"OutputValue": "i-04cc709357306118e"
}
]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset