Skip to content

Instantly share code, notes, and snippets.

@britonad
Last active February 6, 2024 16:49
Show Gist options
  • Save britonad/c0e72172354f9481d5c183905dc9dcb5 to your computer and use it in GitHub Desktop.
Save britonad/c0e72172354f9481d5c183905dc9dcb5 to your computer and use it in GitHub Desktop.
#!/bin/bash
# VPN bootstrap script.
# 1st step
# update repositories and install libraries
apt update && apt upgrade -y && apt install -y make git mosh pwgen htop lnav
apt install -y unbound > /dev/null 2>&1
# configure locale
locale-gen en_GB.UTF-8
locale-gen en_US.UTF-8
# create a user and add to sudo group
echo "Enter your user name:"
read -r USER_NAME
adduser --disabled-password --gecos "" "${USER_NAME}"
usermod -aG sudo "${USER_NAME}"
# set a password
USER_PASSWORD="$(pwgen -s 20 -y)"
echo -e "Your password is \e[34m\"${USER_PASSWORD}\"\e[0m. \e[91mDON'T FORGET TO SAVE IT!\e[0m"
usermod --password "$(openssl passwd -1 "${USER_PASSWORD}")" "${USER_NAME}"
# sync root .ssh directory with vald user
rsync --archive --chown="${USER_NAME}":"${USER_NAME}" ~/.ssh "/home/${USER_NAME}"
# setup sshd
sed -i "0,/PermitRootLogin yes/s//PermitRootLogin no/" /etc/ssh/sshd_config
sed -i "0,/#PasswordAuthentication yes/s//PasswordAuthentication no/" /etc/ssh/sshd_config
sed -i "0,/#PermitEmptyPasswords no/s//PermitEmptyPasswords no/" /etc/ssh/sshd_config
systemctl restart ssh
# Add local DNS resolvers to /etc/hosts
# to be able to see them in "Queries answered by"
cat >> /etc/hosts <<EOF
# Local DNS resolvers
127.1.1.2 unbound
EOF
# Download the current root hints file (the list of primary root servers which are serving the domain "."
# - the root domain). Update it roughly every six months. Note that this file changes infrequently.
wget -O root.hints https://www.internic.net/domain/named.root
sudo mv root.hints /var/lib/unbound/
# Add Unbound conf
cat > /etc/unbound/unbound.conf.d/pi-hole.conf <<EOF
server:
# If no logfile is specified, syslog is used
# logfile: "/var/log/unbound/unbound.log"
verbosity: 3
interface: 127.1.1.2
port: 5353
do-ip4: yes
do-udp: yes
do-tcp: yes
# May be set to yes if you have IPv6 connectivity
do-ip6: no
# You want to leave this to no unless you have *native* IPv6. With 6to4 and
# Terredo tunnels your web browser should favor IPv4 for the same reasons
prefer-ip6: no
# Use this only when you downloaded the list of primary root servers!
# If you use the default dns-root-data package, unbound will find it automatically
root-hints: "/var/lib/unbound/root.hints"
access-control: 127.0.0.0/8 allow
access-control: 0.0.0.0/0 deny
access-control: ::1 allow
access-control: ::0/0 deny
hide-identity: yes
hide-version: yes
# Trust glue only if it is within the server's authority
harden-glue: yes
# Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
harden-dnssec-stripped: yes
# Don't use Capitalization randomization 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.
# IP fragmentation is unreliable on the Internet today, and can cause
# transmission failures when large DNS messages are sent via UDP. Even
# when fragmentation does work, it may not be secure; it is theoretically
# possible to spoof parts of a fragmented DNS message, without easy
# detection at the receiving end. Recently, there was an excellent study
# >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
# by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
# in collaboration with NLnet Labs explored DNS using real world data from the
# the RIPE Atlas probes and the researchers suggested different values for
# IPv4 and IPv6 and in different scenarios. They advise that servers should
# be configured to limit DNS messages sent over UDP to a size that will not
# trigger fragmentation on typical network links. DNS servers can switch
# from UDP to TCP when a DNS response is too big to fit in this limited
# buffer size. This value has also been suggested in DNS Flag Day 2020.
edns-buffer-size: 1232
# Perform prefetching of close to expired message cache entries
# This only applies to domains that have been frequently queried
prefetch: yes
# One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
num-threads: 1
# Ensure kernel buffer is large enough to not lose 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
EOF
mkdir -p /etc/dnsmasq.d
echo 'edns-packet-max=1232' > /etc/dnsmasq.d/99-edns.conf
# restart unbound and bypass failed to start Unbound DNS server error.
sleep 5
systemctl restart unbound
# logging for unbound
mkdir -p /var/log/unbound
touch /var/log/unbound/unbound.log
chown unbound /var/log/unbound/unbound.log
# checks
dig pi-hole.net @127.1.1.2 -p 5353
dig sigfail.verteiltesysteme.net @127.1.1.2 -p 5353
dig sigok.verteiltesysteme.net @127.1.1.2 -p 5353
# shows how unbound is doing
systemctl status unbound.service
@britonad
Copy link
Author

britonad commented Jan 11, 2022

$ sh -c "$(curl -fsSL https://gist.githubusercontent.com/britonad/c0e72172354f9481d5c183905dc9dcb5/raw/0e43b5cb46b4828a23c9bd2a03fd0e39cb8238d8/vpn-boostrap.sh)"

2nd step

$ wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh # choose your static, public IP address
$ curl -sSL https://install.pi-hole.net | bash  # choose your tun0 interface
$ vim /etc/openvpn/server/server.conf
#and
## and replace `push "dhcp-option DNS 8.8.4.4"` with `push "dhcp-option DNS 10.8.0.1"`
#!/usr/bin/env sh

iptables -A INPUT -i tun0 -p tcp --destination-port 53 -j ACCEPT
iptables -A INPUT -i tun0 -p udp --destination-port 53 -j ACCEPT
iptables -A INPUT -i tun0 -p tcp --destination-port 80 -j ACCEPT
iptables -A INPUT -p tcp --destination-port 22 -j ACCEPT
iptables -A INPUT -p tcp --destination-port 1194 -j ACCEPT
iptables -A INPUT -p udp --destination-port 1194 -j ACCEPT
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I INPUT -i lo -j ACCEPT
iptables -P INPUT DROP
iptables -A INPUT -p udp --dport 80 -j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p tcp --dport 443 -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp --dport 443 -j REJECT --reject-with icmp-port-unreachable
iptables -A INPUT -p udp -m multiport --dports 60000:61000 -j ACCEPT

iptables-save > /etc/pihole/rules.v4
ip6tables-save > /etc/pihole/rules.v6

install iptables-persistent

apt install iptables-persistent

@britonad
Copy link
Author

britonad commented Jan 11, 2022

3rd step

$ touch /lib/systemd/system/hints.timer

[Unit]
Description=Download root hints monthly

[Timer]
OnCalendar=monthly
RandomizedDelaySec=2h
Persistent=true

[Install]
WantedBy=timers.target

$ touch /lib/systemd/system/hints.service

[Unit]
Description=Hints

[Service]
Type=oneshot
ExecStart=/root/.scripts/update-hints.sh
PrivateTmp=true

$ mkdir ~/.scripts && touch /root/.scripts/update-hints.sh

#!/usr/bin/env sh
# Download root hints

wget -O /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
$ systemctl restart unbound && systemctl enable hints.timer && systemctl start hints.timer && systemctl status hints.timer

@britonad
Copy link
Author

to set pihole password

pihole -a -p

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment