I've got myself a Raspberry Pi 3 and want to use it as my home router and VPN gateway. At some point, I'll probably accidentally step on it or pour a flat white on it and then wonder how I set it up to do what it's supposed to do.
To avoid this, here are some notes and scripts to make it less painful when that happens. Don't confuse this with a tutorial. I'm writing this first and foremost for myself. However, if you have any suggestions, feel free to send PRs my way.
Have a WiFi access point that I can connect my phone and ChromeCast to and transparently get routed through an OpenVPN.
To set up the other side of this, I can whole-heartedly recommend the docker-openvpn suite which makes the server-side setup a breeze.
You get a WiFi hotspot that tunnels all requests through
tun0 which is
backed by an OpenVPN connection. I'm not sure if this is stable enough for
use and there's no good way from the outside to enable/disable VPNs.
2016-03-18for this. Also, don't be a jerk, and use the Torrent option.
dd bs=4M if=2016-03-18-raspbian-jessie.img of=/dev/sdb
.landomain, so I could directly connect to
raspberrypi.lan. Obviously, take care of conflicts if you have more than one.
nmapis your friend.
ssh [email protected], password is
ssh [email protected] "mkdir -p ~/.ssh/"; scp ~/.ssh/id_rsa.pub [email protected]:/home/pi/.ssh/authorized_keys
sudo raspi-configand select option 1: "Expand Filesystem".
playbook.yml and make the necessary adjustments,
notably add your premiumize.me credentials to it. Afterwards, you can run it
ansible-playbook -i hosts playbook.yml
This assumes that the hostname in
hosts can be resolved and you can log in
password-less via the
pi user. It also expects the Pi to already have a
working internet connection.
Everything should automatically start up, but Linux boxes are painfully stateful so if the VPN or something else didn't come up, just reboot that thing.
Afterwards, you should be able to connect to the device via WiFi. The defaults are SSID "passy-pi" and password "raspberrypi". Afterwards, your connected device should be transparently routed through the VPN. Sorry, Netflix.
I now have a second ChromeCast that only connects to this AP and hence thinks it's in whatever country I tell it to. Neat.
In case something is wrong with the WiFi and you just want to verify if the routing works, you can add a route manually.
On your target device, assuming it's IPv4:
# Figure out your current default route: $ route -n | grep 0.0.0.0 # Delete the default GW $ route del default gw <ip_address_from_above> # Add the new route to the Pi $ route add default gw <pi_ip_addr>
Something I only found out about when working on this that I should have really known before is that you can selectively run ansible tasks by specifying tags.
If you, for instance, change your VPN settings but don't want to also run an
apt-get upgrade you can use the
openvpn tag like so:
ansible-playbook -i hosts playbook.yml --tags openvpn
Multiple tags can be comma-separated.
Certain movie streaming services has gotten a lot more aggressive lately and not only block the usual suspects, but entire fucking IP ranges (both IPv4 and IPv6) for hosting providers like DigitalOcean, AWS and Linode. I wish they had done this a couple of weeks earlier so I could have avoided all the previous work.
But anyway, one so far unaddressed attack vector is using a custom DNS. This even comes with a bunch of benefits like better performance and no traffic limits. And all it takes is a couple of
iptables rules to rewrite all DNS requests to those custom servers.
I'm currently testing ViperDNS for just that, which even offers a 7 day free trial.
In order to prepare your Pi for the service, you need to change your
playbook.yml ever so slightly. You can either leave the
openvpn part out entirely if you've never provisioned your device before or (damn you statefulness) make sure to set
none to avoid unnecessarily spinning up instances. Be aware that an empty string here means running daemons for all
*.conf files in
playbook.yml.dnsexample for an example. The interesting bits here are
firewall.mode: "dns" rather than
"tunnel" which is the default and the
force_dns: "18.104.22.168" which overrides all incoming DNS requests (or anything really talking to port 53) to the given IP address.
Afterwards, just replay the playbook and reboot the device.
If you've updated just the DNS redirect and want to skip the other tasks, the
tag you want to use is
ansible-playbook -i hosts playbook.yml --tags firewall