Endless infrastructure for your home network
The ability to securely extend your home network with an endless set of infrastructure can be very useful. You can spin up powerful game servers, add virtually limitless storage, … and so on.
You could just setup resources in Amazon Web Services and expose the necessary endpoints publicly and connect to them. However if you’re looking for a bit more security, you’ll want to go with a secure VPN connection.
In my case, I’m running a Meraki network which is connected to the internet using an MX gateway. The MX gatewau supports site-to-site VPN connections, making the setup much easier.
What held my back settign up VPN in the past is the price of a VPN connection in AWS. At the time of this writing, AWS VPNs cost $0.05 per hour. So if you manually configure AWS VPN to connect to the home network and leave it running it adds up to more than $35 per month. And then you still have to pay for any compute or storage resources you’re using. If you only need the connectivity to be up sporadically it’s a lot of money.
It would be better is we can temporarily create the VPN connection only when we need it. Suppose you only need the VPN connection to be up for 10 afternoons per month. Then we’re looking a cost in the neighborhood of $2 per month. That’s much more acceptable.
Unfortunately VPN connections on AWS don’t have an easy disable function. As long as the VPN connection is in the available status you’ll pay for it. So how do we create the VPN on demand?
One option is to manually setup and tear down the VPN connection when you need it, but that’s a pain. A better way is to create a CloudFormation template and just spin that up each time you need it.
In this post, I’ll share my basic setup with some manual steps. In a follow-up post, I’ll automate the process end-to-end. But first things first…
Preparing the cloud
I this post, I assume that you already have an AWS account with admin access. If you don’t, head over to AWS and get that setup first.
VPCs and subnets don’t cost anything in AWS, so I’ve created those manually as a one time up-front step and I leave them in place. They will later serve as the anchor points to connect the VPN connection.
I’ve created a VPC, and two private subnets. The VPC has a CIDR of 192.168.3.0/24. It’s important that this VPC CIDR doesn’t overlap with the IP addresses on your home network.
The subnets are deployed in a different availability zone and have CIDRs assigned as shown in the diagram.
I plan on deploying any servers or other services into one of these private subnets. Once the VPN is established I will be able to access them from my home network.
Deploying the VPN stack
We’ll be using CloudFormation to create the necessary resources to establish the VPN connection. The CloudFormation template will take a few input parameters:
- HomeIP (required): this is the IP address of the home network. If you’re using a Meraki MX like I do, you can read the IP address from the MX summary page, under WAN 1. Googling ‘google my ip address’ will do that trick as well.
- VPCID (required): the id of the VPC you’ve created. Use the AWS VPC console to find this id
- RouteTableID (required): the id of the route tables associated with the private subnets.
- TagName (optional): a Application tag will be applied to resources that support it.
- Prefix (optional): the prefix for the resource name that will be used.
I’ve uploaded my CloudFormation template to S3 with public access. So you can directly use this in CloudFormation. Navigate to the CloudFormation console and ‘Create Stack’. You can use following CloudFormation template:
https://site-to-site.s3-eu-west-1.amazonaws.com/site-to-site.yaml
Next fill in the parameters based on your own network and AWS VPC setup:
Click through the next set of screens — no need to modify any of the settings. In the last screen click ‘Create Stack’.
This will complete the AWS side of the setup. The stack will show a status of CREATE_COMPLETE.
Connecting home.
Next we configure the Meraki MX to terminate the VPN Connection at home. For this we need to use the AWS CLI to get two pieces of information: the AWS side IP address for the VPN Connection and the pre-shared key. Unfortunately (or fortunately if you like your security) the console doesn’t private access to the secret.
Run following command:
$ aws ec2 describe-vpn-connections --output=text
As part of the output, there’s a blurp of XML and you’ll have to rely on your eagle eyes to obtain the relevant bits. I post the output of the command below and highlight the values you’re looking for:
<vpn_connection id="vpn-086abbf5e5a5e9e3c">
<customer_gateway_id>cgw-082ff0f8dde095b08</customer_gateway_id>
<vpn_gateway_id>vgw-039043816dfd32165</vpn_gateway_id>
<vpn_connection_type>ipsec.1</vpn_connection_type>
<vpn_connection_attributes>NoBGPVPNConnection</vpn_connection_attributes>
<ipsec_tunnel>
<customer_gateway>
<tunnel_outside_address>
<ip_address>94.226.70.21</ip_address>
</tunnel_outside_address>
<tunnel_inside_address>
<ip_address>169.254.108.18</ip_address>
<network_mask>255.255.255.252</network_mask>
<network_cidr>30</network_cidr>
</tunnel_inside_address>
</customer_gateway>
<vpn_gateway>
<tunnel_outside_address>
<ip_address>18.203.213.140</ip_address>
</tunnel_outside_address>
<tunnel_inside_address>
<ip_address>169.254.108.17</ip_address>
<network_mask>255.255.255.252</network_mask>
<network_cidr>30</network_cidr>
</tunnel_inside_address>
</vpn_gateway>
<ike>
<authentication_protocol>sha1</authentication_protocol>
<encryption_protocol>aes-128-cbc</encryption_protocol>
<lifetime>28800</lifetime>
<perfect_forward_secrecy>group2</perfect_forward_secrecy>
<mode>main</mode>
<pre_shared_key>OghgpuFVZJfrc0iXONQkKBN0rT1PJFpD</pre_shared_key>
</ike>
... more data after this point ... you can ignore ...
Note the values for vpn_gateway outside ip address, and the pre_shared_key.
Navigate the the site-to-site VPN configurations in the Meraki MX.
Then add a non-Meraki VPN peer using the information from the earlier steps. The private subnets is the subnet of the AWS VPC. The public IP address is the VPN gateway outside IP address you collected from the command above. Make sure you use the AWS IPsec policies preset.
You’ll also want to ensure that your home network is participating in the VPN
The result
Once all of this is setup, the end result looks like the diagram below. The private IP address range for my home network is 192.168.2.0/24.
You can spin up an EC2 instance in either of the private subnets and ping its private IP address from your home network. Ensure that you place the EC2 instance in a security group that allows ICMP or SSH access depending on how you’re trying to access the host. Also, it does take around 10 mins for the VPN connection to come up.
When you’re done, you can tear down the VPN connection by deleting the stack.
Have fun!