DEV Community

hunttom
hunttom

Posted on

A Self-Service Raspberry Pi VPN

Recently, I wanted to set up a VPN server residing on a Raspberry Pi on my home network and wanted to share my adventures with you. While this is more of an infrastructure and VPN-based post, I thought that it might provide some developers in need of a secure way to get back to their home networks as I did. Additionally, this is a fun way to brush up on infrastructure work and mess around with a Raspberry Pi!

Here is an overview of my setup:

Necessary equipment:

  1. A Raspberry Pi (Preferable a RBP2+)
  2. An AWS account (or any other Cloud Provider) - In this post I use AWS
  3. A domain.

Problem and Context: I wanted to have a secure way to link back into my home network when traveling and using public networks. VPN Companies were an option but I wanted the following:

  1. The ability to update and check on my IoT projects running on my home network.
  2. Cost - VPN companies have robust servers with world-wide reach. Although, they do incur cost monthly and the RBP option was a lot cheaper (totaling around $2.80 per month) including energy and cost of the AWS hosted zone.
  3. I had a RBP laying around - why not!

Solution: A PiVPN running on my home network allowing me to both reach my home network and the Internet. My VPN endpoint (RBP) remains online because I run a Cron job every 24 hours to update a hosted zone's A record on AWS Route53.

  1. I set up the RBP: updating Linux and changing the login to a very strong password (Security always!). I went a step further and only enabled PEM key login for SSH for extra security.

  2. I set up my router for port forwarding on a random port to my RBP.

  3. Used the PiVPN curl -L https://install.pivpn.io | bash to generate the OpenVPN certificate and set up the OpenVPN server to my preferences.

  4. Created the PiVPN cert and used SCP to download that cert and change the .opvn file to ensure that the endpoint was my DynamicDNS record (example: vpn.example.com).

  5. To circumvent an issue I ran into where my VPN pointed to my router's public IP and my ISP changed my IP address, I modified a DynamicDNS script I found (Compliments to https://willwarren.com/).

  6. Set up a Cron Job to query once a day and update my AWS Route53 A Record if my ISP changes my public IP address again. When SSH'ed into the the RBP run crontab -e and put the desire frequency of triggering the Cron job. An easy tool to use can be found here.
    Example 24 hour Cron job that runs every midnight: 0 0 * * * /bin/bash /home/pi/dynamic_dns_route53.sh

  7. Install AWS CLI on the RBP.

  8. Create an IAM User with a policy dynamicdnspolicy:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "route53changerecord",
                "Effect": "Allow",
                "Action": "route53:ChangeResourceRecordSets",
                "Resource": "arn:aws:route53:::hostedzone/HOSTEDZONE"
            }
        ]
    }
  1. Create an Access Key/Secret key pair and add to AWS CLI profile on the RBP.

  2. Download the DynamicDNS Script from my Repository

  3. Add hosted zone and record set to the dynamic_dns_route53.sh script on lines 8 and 11 from Route53.

  4. Verify that the script ran!

You can change out the script to whatever cloud/DNS provider you have!

Best of success (securely of course!)


PS This worked on both my phone and laptop, I just needed an OpenVPN client to use the cert!

Top comments (0)