Friday, June 19, 2020

Setup free Cloud VPN with Ad Blocking

Use Oracle Cloud always free tier, OpenVPNPi-Hole, and Quad9 DNS to setup your own ad, tracking, and malware blocking VPN!

Oracle Cloud offers an always free tier option which includes the ability to provision up-to two Linux VMs (from a choice of distributions) with 1 GB memory, 50 GB storage each, and public IP addresses. Ideal for this type of work, and considering these VMs are running on HA (high availability) hardware in a datacenter with redundant power and network links makes it hard to beat for the price!

Together with Pi-Hole and OpenVPN which has clients for Windows, macOS, Linux, iOS, and Android it's fairly easy to setup and get working.

Oracle Cloud VM


Go-to https://docs.cloud.oracle.com/en-us/iaas/Content/home.htm to learn about the services, how to get setup with the free account, and Launch a Linux instance guide which will walk you through getting a VM up and running with networking, which you can then SSH into.

When creating a VM the default image is Oracle Linux. I chose the Ubuntu 20.04 image (not the minimal one), as I'm most familiar with Debian/Ubuntu.

Once a VM is up and running, and logged in via SSH, update the system and reboot:

apt-get update
apt-get upgrade
reboot

Installing OpenVPN



I went with the defaults except it does not detect the public IP of the Oracle cloud instance, manually enter that. For the DNS servers, I prefer Quad9 which blocks known Malware domains and doesn't log. This selection doesn't matter too much because we're going to change it later to use the DNS server Pi-Hole installs, which I choose Quad9 for upstream DNS.

After installing the script prompts to setup a user and outputs a config file for the client.
  • Port 1194 has to be enabled via the Oracle Cloud Console > Networking > Virtual Cloud Networks > [network name you created] > Public Subnet > Default Security List > add a rule for UDP port 1194 (stateful).
  • Angristan's OpenVPN install script made the necessary changes to iptables and everything just worked.
  • Note that the default iptables contains a number of rules for the iSCSI boot block volume, do not clear the iptables rules or modify these rules. More info in Oracle-Provided Images > Essential Firewall Rules.

After installing OpenVPN, I tested it with the defaults before moving on to installing Pi-Hole.

Note: This OpenVPN install script creates a pair a iptables scripts that are run when the OpenVPN service starts and stops. One adds rules, one removes them:

/etc/iptables/add-openvpn-rules.sh
/etc/iptables/rm-openvpn-rules.sh

Be aware these use the -I option to insert the rules at the top of their respective chains, if like me you have some geo whitelist and tor exit node block ipsets being inserted under the "related, established" connection tracking rule (usually 1st) 2nd and 3rd, then you may want to insert the INPUT rules further down by increasing the number after INPUT, e.g:

iptables -I INPUT 7 -i ens3 -p udp -m udp --dport 1194 -j ACCEPT
iptables -I INPUT 8 -i tun0 -j ACCEPT


There is also PiVPN (better to install it after PiHole if used) which will run on any Debian based system, not used or tested it yet, just making a note of it.

Installing Pi-Hole


Install methods are listed at https://github.com/pi-hole/pi-hole/#one-step-automated-install, I use the curl command.

The Pi-Hole script offers a list of upsteam DNS servers to use, I prefer Quad9 as they block known malware domains and don't log.

Configure Pi-Hole to listen on all interfaces, by default it picks an Ethernet interface, go-to http://10.8.0.1/admin > login > Settings > DNS > Listen on all interfaces.

Update OpenVPN server configuration to push the VPN tunnel IP for DNS, edit /etc/openvpn/server.conf Comment out the preset servers and add:

push "dhcp-option DNS 10.8.0.1"
# push "dhcp-option DNS 9.9.9.9"
# push "dhcp-option DNS 149.112.112.112"

Restart OpenVPN server:

systemctl restart openvpn@server

Logging


If logging is a concern, this can be disabled.


sudo pihole logging off

In the Pi-Hole interface, Settings > Privacy > Anonymous mode


sudo service pihole-FTL stop
sudo rm /etc/pihole/pihole-FTL.db
sudo service pihole-FTL start

Clear out archived copies of /var/log/pihole.log with

sudo rm /var/log/pihole.log*

This will leave basic stats available on the dashboard, but wont log or display anything specific about clients or DNS queries.

I "think" that is all that is required, searching for info on how to turn off logging doesn't turn up info / explanations on how-to clearly and fully do this in one place.

Automatic Updates


The Oracle Ubuntu image appears to be partially setup for automatic updates, it was already installed and had a config file present.

The options I configured in /etc/apt/apt.conf.d/50unattended-upgrades were:

// Automatically reboot *WITHOUT CONFIRMATION* if
//  the file /var/run/reboot-required is found after the upgrade
Unattended-Upgrade::Automatic-Reboot "true";

// Automatically reboot even if there are users currently logged in
// when Unattended-Upgrade::Automatic-Reboot is set to true
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
//  Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "10:00";

Note the time is in UTC (assuming it's the default timezone in Oracle Cloud VMs). 10am UTC is 2am Pacific Time in my case.


Incidentally I found when trying to get automatic-updates working on my Raspberry Pi that it doesn't work, the config file needs to be edited - https://raspberrypi.stackexchange.com/a/102350



Some more info on automatic-updates


Pi-Hole Updates


Running pihole -up manually will update the Pi-Hole software.

To automate it, sudo -i to switch to root, crontab -e to edit the crontab, and enter:

# Pi-Hole weekly update
0 11 * * 0 /usr/local/bin/pihole -up > /var/log/pihole-up.log

Minutes, Hours, Days of month, Months of year, Day of week, Command, What to do with the output.

This will run the update at 11:00 am once a week on Sunday (day zero of the week) in the timezone of the machine, since mine is UTC and I'm Pacific time -8 hours this is 3am every Sunday morning. Output the results to /var/log/pihole-up.log. Plenty of crontab generators online.


Speedtest


Speedtest-cli is a command line speed test tool (requires Python). From the VM it reports 420 to 490 mbps in both directions. Over the VPN tunnel I get up-to 100 mbps.


Additional Block Lists

Additional block lists can be added via Group Management > Adlists

These don't seem to be an exact science, DYOR.

See:



Enable client to client communication

In /etc/openvpn/server.conf add an entry/line with: client-to-client

Add an iptables forwarding rule to enable traffic to pass out of and back into the tun0 interface:

iptables -A FORWARD -i tun0 -o tun0 -j ACCEPT

I later found I didn't need this rule, maybe a system reboot after the addition of client-to-client to server.conf works on its own?

Restart OpenVPN server and check status: 

systemctl restart openvpn

systemctl status openvpn


Multiple Instances for both UDP and TCP

(Rough notes)

By default OpenVPN is setup to listen on UDP port 1194, UDP is preferred as its more efficient and any TCP traffic being tunneled will handle dropped packet retries.

Some networks may block outgoing UDP traffic and/or limit traffic to web browsing only on TCP ports 80 and 443.

A work around is to enable multiple instances of OpenVPN server, one listening on UDP and one on TCP port 443 which is least likely to be restricted.

Copy /etc/openvpn/server.conf to /etc/openvpn/server2.conf

Edit the original server.conf change dev tun to dev tun0.

Edit server2.conf:

  • Change dev tun to dev tun1, 
  • port to 443 and proto to TCP
  • Change the server line to use a new subnet e.g server 10.9.0.0 255.255.255.0
  • If clients are assigned static IPs configs in the ccd directory and ipp.txt, duplicate directory and files and update addresses with server configs referencing each one.

Start the new server: systemctl start openvpn@server2.service
Check the new server status: systemctl status openvpn@server2.service
Enable autostart with: systemctl -f enable openvpn@server2.service

Update the iptables rules in /etc/iptables/add-openvpn-rules.sh or /etc/iptables/rules.v4 to enable incoming connections on TCP 443 (depending on where this rule is added), and duplicate any rules related for the new OpenVPN subnet and new tun1 interface. (Need to add details).

Inter client communication (if needed) between each instance needs a pair of iptables rules to forward traffic between tun0 and tun1, e.g:

iptables -I FORWARD -i tun0 -o tun1 -j ACCEPT
iptables -I FORWARD -i tun1 -o tun0 -j ACCEPT

Edit or remove/add a new VPN client profile to duplicate it, edit the duplicated file and change proto to tcp and the port number on the remote entry, we have one profile for UDP, and one for TCP when needed. It may be possible to include several remote lines in one profile such as https://openvpn.net/faq/how-do-i-set-up-my-profile-for-server-failover/. (Need to test this and see if it'll work reliably).


Renew Expired Server Certificate

These will expire after 3 years (I found this out the hard way)!

https://github.com/angristan/openvpn-install/issues/1002#issuecomment-1229525488

Running those commands worked, no changed needed to clients - macOS or iPhone at least.

A later comment on that issue suggested using easyrsa renew, but I couldn't figure out what version of easyrsa I had.


Privacy Badger (EFF)

Adds and additional layer to the browser

https://privacybadger.org/