Skip to content

Instantly share code, notes, and snippets.

@sethenoka
Created March 21, 2019 21:28
Show Gist options
  • Save sethenoka/e2e566385cae3081cc9850bdd3ab166f to your computer and use it in GitHub Desktop.
Save sethenoka/e2e566385cae3081cc9850bdd3ab166f to your computer and use it in GitHub Desktop.
A script for installing a Wireguard VPN with Pi-Hole (Unbound) recursive DNS
#!/bin/bash
# This file is designed to spin up a Wireguard VPN quickly and easily,
# including configuring Pi-Hole as a recursive local DNS server using
# Unbound to block ads a the DNS level
#
# Make sure to change the public/private keys before running the script
# Also change the IPs, IP ranges, and listening port if desired
# add wireguard repo
sudo add-apt-repository ppa:wireguard/wireguard -y
# update/upgrade server and refresh repo
sudo apt update -y && apt upgrade -y
# install wireguard
sudo apt install wireguard -y
# create Wireguard interface config
cat > /etc/wireguard/wg0.conf << ENDOFFILE
[Interface]
PrivateKey = <server_private_key>
Address = 10.20.20.1/24
ListenPort = 55000
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
SaveConfig = true
[Peer]
PublicKey = <client_public_key>
PresharedKey = <psk>
AllowedIPs = 10.20.20.2/24
Endpoint = <client_public_ip>:<high_port>
ENDOFFILE
# make root owner of the Wireguard config file
sudo chown -v root:root /etc/wireguard/wg0.conf
sudo chmod -v 600 /etc/wireguard/wg0.conf
# install resolveconf for Pi-Hole
sudo apt install resolvconf -y
# bring the Wireguard interface up, must be done prior to Pi-Hole being installed/configured
sudo wg-quick up wg0
# make wg0 interface start at boot time
sudo systemctl enable wg-quick@wg0.service
# enable IPv4 forwarding
sed -i 's/\#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
# after enabling forwarding a reboot is required, without the following two lines
sudo sysctl -p
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
# FIREWALL CONFIGURATION
# track the VPN connection
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# identify and allow traffic on the VPN listening port
sudo iptables -A INPUT -p udp -m udp --dport 55000 -m conntrack --ctstate NEW -j ACCEPT
# allow tcp/udp recursive DNS
sudo iptables -A INPUT -s 10.20.20.0/24 -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -s 10.20.20.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
# install persistent IP tables without the need for user interaction
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
# make the firewall rules persistent
sudo apt install iptables-persistent -y
sudo systemctl enable netfilter-persistent
sudo netfilter-persistent save
# install Pi-Hole
sudo curl -sSL https://install.pi-hole.net | bash
# install Unbound for a local recursive DNS implementation
sudo apt install unbound -y
# download a list of root DNS servers, this should be updated every ~6 months
curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache
# configure Unbound for Pi-Hole on port 5353
cat > /etc/unbound/unbound.conf.d/pi-hole.conf << ENDOFFILE
server:
# if no logfile is specified, syslog is used
# logfile: "/var/log/unbound/unbound.log"
verbosity: 1
port: 5353
do-ip4: yes
do-udp: yes
do-tcp: yes
# may be set to yes if you have IPv6 connectivity
do-ip6: no
# use this only when you downloaded the list of primary root servers
root-hints: "/var/lib/unbound/root.hints"
# respond to DNS requests on all interfaces
interface: 0.0.0.0
max-udp-size: 3072
# IPs authorised to access the DNS Server
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.1 allow
access-control: 10.20.20.0/24 allow
# hide DNS Server info
hide-identity: yes
hide-version: yes
# limit DNS fraud and use DNSSEC
harden-glue: yes
harden-dnssec-stripped: yes
harden-referral-path: yes
# add an unwanted reply threshold to clean the cache and avoid, when possible, DNS poisoning
unwanted-reply-threshold: 10000000
# have the validator print validation failures to the log
val-log-level: 1
# don't use Capitalisation randomisation as it known to cause DNSSEC issues sometimes
# see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
use-caps-for-id: no
# reduce EDNS reassembly buffer size
# suggested by the unbound man page to reduce fragmentation reassembly problems
edns-buffer-size: 1472
# TTL bounds for cache
cache-min-ttl: 3600
cache-max-ttl: 86400
# perform prefetching of close to expired message cache entries
# this only applies to domains that have been frequently queried
prefetch: yes
prefetch-key: yes
# one thread should be sufficient, can be increased on beefy machines
num-threads: 1
# ensure kernel buffer is large enough to not loose messages in traffic spikes
so-rcvbuf: 1m
# ensure privacy of local IP ranges
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: 172.16.0.0/12
private-address: 10.0.0.0/8
private-address: fd00::/8
private-address: fe80::/10
ENDOFFILE
reboot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment