I talked about how to use PiVPN to set up an OpenVPN server on a Raspberry Pi at home previously, here and here. The next step for me was to use CloudFlare as a DNS server, instead of signing up for yet another internet service and having another login here or there to worry about.
This very smart guy, Tomasso Barbato, wrote up how to do it, but he includes two versions, an APIvUnknown and an APIv4 version. CloudFlare only supports the APIv4 version as of next month, I guess, so I’m copying the scripts here, as many of my referenced internet pages have gone offline in recent months. Read his page, though, so that you know what to do. I’ve also bolded the variables so that you can simply run a Replace All command in a text editor to easily adapt the scripts for your use. An enterprising hacker would create a bash script to automate all the other scripts, but…
Initial setup
This should be pretty easy, but:
- Go to CloudFlare
- Add an A record to your domain through the DNS page
- Use your current IP address of your server for the record
- Read the page to learn how to do it, but use my edits for an easier time.
The important variables
FULL-DOMAIN: example.com
SUB-DOMAIN: sub.example.com
From the CloudFlare user settings page
EMAIL: Account Email: X-Auth-Email: [email protected]
KEY: API Key: X-Auth-Key: 9a7806061c88ada191ed06f989cc3dac
*Note: the API Key is the shorter of the two keys that you have the option of requesting
Use scripts to obtain
ZONE-ID: Zone ID (domain name): “id”: “dac9320b638f5e225cf483cc5cfdda41”
RECORD-ID: Record ID (subdomain/A record): “id”: “8ada191ed06f989cc3dac9a7806061c8”
*Note: I’m using a VARIABLE: explanation: example
format here.
The scripts
Get Zone ID:
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=FULL-DOMAIN" \ -H "X-Auth-Email: EMAIL" \ -H "X-Auth-Key: KEY" \ -H "Content-Type: application/json" | jq .
Get Record ID:
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE-ID/dns_records?name=SUB-DOMAIN" \ -H "X-Auth-Email: EMAIL" \ -H "X-Auth-Key: KEY" \ -H "Content-Type: application/json" | jq .
Bash script for crontab
#!/bin/sh [ ! -f /var/tmp/current_ip.txt ] && touch /var/tmp/currentip.txt NEWIP=`dig +short myip.opendns.com @resolver1.opendns.com` CURRENTIP=`cat /var/tmp/currentip.txt` if [ "$NEWIP" = "$CURRENTIP" ] then echo "IP address unchanged" else curl -X PUT "https://api.cloudflare.com/client/v4/zones/ZONE-ID/dns_records/RECORD-ID" \ -H "X-Auth-Email: EMAIL" \ -H "X-Auth-Key: KEY" \ -H "Content-Type: application/json" \ --data "{\"type\":\"A\",\"name\":\"SUB-DOMAIN\",\"content\":\"$NEWIP\"}" echo $NEWIP > /var/tmp/currentip.txt fi
By using this script, I now have an OpenVPN server that is somewhat protected by CloudFlare that I can access anywhere and whenever I want, no matter if my home router reboots or if I change internet providers.
There is a caveat: CloudFlare can only protect ports that are used with HTTP HOST headers, SSH or OpenVPN or any other protocol requires the A record to disable its CloudFlare protection. This exposes your IP address somewhat, but it is also protected somewhat. There’s a tradeoff between domain name privacy and personal convenience here.
I also read that a SRV record hides the IP of an origin server better than an A record, so that’s a logical next step, but not one that I have time for right now.
Photo by Nguyen Vu Hung (vuhung)