Securely Access Your Server From Anywhere
(With DuckDNS, PiHole, LetsEncrypt & OpenVPN)¶
Last updated: May 2022. For advanced users. Solid tech skills required.
After having successfully set up your Ubuntu server and configured basic as well as advanced security measures, this section will explain how to:
- point a (sub-)domain to your home IP address with DuckDNS
- encrypt traffic with Let's Encrypt
- access local services, use a privacy respecting DNS provider and block ads with Pi-hole
- shield the server from the Internet with a reverse proxy
- securely access the server from anywhere in the world with OpenVPN
How to set up a DuckDNS domain¶
Human-readable addresses are easier to remember than random IPs. Rather than typing 18.192.76.182
into their browser, most users prefer to navigate to www.gofoss.net. For this to work with your server, you need a unique name which points to your home IP address, also known as domain name. In addition, a domain name is required to encrypt traffic, as explained in the next section.
DuckDNS allows to register a (sub-)domain for free and dynamically points it to your home IP address. This means it even works if your IP address changes quite often. Simply head over to DuckDNS and register a (sub-)domain of your choice. As soon as the registration is confirmed, you will receive a unique token.
For the purpose of this tutorial, we've registered the (sub-)domain gofoss.duckdns.org
and received the token ebaa3bd3-177c-4230-8d91-a7a946b5a51e
. This will allow us later on to access services on the server via addresses such as https://myservice.gofoss.duckdns.org
.
LetsEncrypt, a trusted Certificate Authority¶
All traffic should be encrypted over HTTPS. The browser's address bar should always display a secure connection, no matter if you browse the Internet or access self-hosted services. This means you need SSL certificates – either buy them or get them for free from Let's Encrypt, a trusted Certificate Authority. More detailed instructions below.
Show me the step-by-step guide
Perform a LetsEncrypt DNS challenge with Dehydrated¶
Let's Encrypt needs to verify that you actually own the domain before delivering any certificate. A nifty program called Dehydrated makes this possible. Log into the server and download Dehydrated:
sudo apt install git
git clone https://github.com/dehydrated-io/dehydrated.git
Navigate to the directory dehydrated
and create a first configuration file:
cd dehydrated
vi domains.txt
Add the following line, and make sure to provide your own domain name:
*.gofoss.duckdns.org > gofoss.duckdns.org
Save and close the file (:wq!
), then create a second configuration file:
vi config
Add the following lines. Make sure to provide your own email address:
CHALLENGETYPE="dns-01"
BASEDIR=/etc/dehydrated
HOOK="${BASEDIR}/hook.sh"
CONTACT_EMAIL=gofoss@gofoss.net
Save and close the file (:wq!
), then create a third configuration file:
vi hook.sh
Add the following lines. Make sure to provide your own domain name, as well as your own token delivered by DuckDNS:
DOMAIN="gofoss.duckdns.org" # provide your domain here
TOKEN="ebaa3bd3-177c-4230-8d91-a7a946b5a51e" # provide your token here
case "$1" in
"deploy_challenge")
curl "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&txt=$4"
echo
;;
"clean_challenge")
curl "https://www.duckdns.org/update?domains=$DOMAIN&token=$TOKEN&txt=removed&clear=true"
echo
;;
"deploy_cert")
;;
"unchanged_cert")
;;
"startup_hook")
;;
"exit_hook")
;;
*)
echo Unknown hook "${1}"
exit 0
;;
esac
Save and close the file (:wq!
).
Caution: Above instructions need to be modified if you work with another domain than DuckDNS. Please refer to Dehydrated's documentation or Let's Encrypt's community to properly set up the hook for DNS-based validation.
The next set of commands creates a directory where all SSL certificates will be stored, called certs
. The files dehydrated
and hook.sh
are made executable. The dehydrated
directory moves to /etc/dehydrated
. Finally, gofossadmin
is given the ownership of the directory /etc/dehydrated
. Make sure to adjust the administrator name to your own setup:
mkdir certs
chmod a+x dehydrated
chmod a+x hook.sh
cd ..
sudo mv dehydrated /etc/dehydrated
sudo chown -R gofossadmin:gofossadmin /etc/dehydrated
Check the directory layout:
sudo ls -al /etc/dehydrated
The output should look something like:
drwxr-xr-x 2 gofossadmin gofossadmin 4096 Jan 01 00:00 .
drwxr-xr-x 4 gofossadmin gofossadmin 4096 Jan 01 00:00 ..
-rw-r--r-- 1 gofossadmin gofossadmin 200 Jan 01 00:00 certs
-rw-r--r-- 1 gofossadmin gofossadmin 200 Jan 01 00:00 config
-rwxr-xr-x 1 gofossadmin gofossadmin 700000 Jan 01 00:00 dehydrated
-rw-r--r-- 1 gofossadmin gofossadmin 200 Jan 01 00:00 docs
-rw-r--r-- 1 gofossadmin gofossadmin 20 Jan 01 00:00 domains.txt
-rwxr-xr-x 1 gofossadmin gofossadmin 700 Jan 01 00:00 hook.sh
Create a LetsEncrypt wildcard certificate¶
Register with Let's Encrypt:
bash /etc/dehydrated/dehydrated --register --accept-terms
This command creates a directory /etc/dehydrated/accounts
, containing your registration information. The terminal should show something like:
# INFO: Using main config file /etc/dehydrated/config
+ Generating account key...
+ Registering account key with ACME server...
+ Done!
Now, create the SSL certificate:
bash /etc/dehydrated/dehydrated -c
The terminal should prompt something like:
+ Creating chain cache directory /etc/dehydrated/chains
Processing gofoss.duckdns.org
+ Creating new directory /etc/dehydrated/certs/gofoss.duckdns.org ...
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting new certificate order from CA...
+ Received 1 authorizations URLs from the CA
+ Handling authorization for gofoss.duckdns.org
+ 1 pending challenge(s)
+ Deploying challenge tokens...
OK
+ Responding to challenge for gofoss.duckdns.org authorization...
+ Challenge is valid!
+ Cleaning challenge tokens...
OK
+ Requesting certificate...
+ Checking certificate...
+ Done!
+ Creating fullchain.pem...
+ Done!
That's it! Two SSL keys have been created to encrypt all traffic to and from your self-hosted services. We'll explain later how to use these keys.
File | Location |
---|---|
Public key | /etc/dehydrated/certs/gofoss.duckdns.org/fullchain.pem |
Private key | /etc/dehydrated/certs/gofoss.duckdns.org/privkey.pem |
LetsEncrypt renew certificate¶
Let's Encrypt's certificates expire after 90 days, and can be renewed 30 days before expiry. It's a good idea to automate these updates. Create a log file:
sudo touch /var/log/dehydrated
Next, create a weekly cron job which checks the certificate's validity and, if required, renews it:
sudo vi /etc/cron.weekly/dehydrated
Add the following content:
#!/bin/sh
MYLOG=/var/log/dehydrated
echo "Checking cert renewals at `date`" >> $MYLOG
/etc/dehydrated/dehydrated -c >> $MYLOG 2>&1
Save and close the file (:wq!
). Now, make the script executable:
sudo chmod +x /etc/cron.weekly/dehydrated
Test the cronjob:
sudo bash /etc/cron.weekly/dehydrated
sudo cat /var/log/dehydrated
The terminal output should look something like:
Checking cert renewals at Sun 01 Jan 2021 01:29:06 PM CEST
# INFO: Using main config file /etc/dehydrated/config
Processing *.gofoss.duckdns.org
+ Checking domain name(s) of existing cert... unchanged.
+ Checking expire date of existing cert...
+ Valid till Mar 12 10:23:18 2021 GMT (Longer than 30 days). Skipping renew!
Show me the 2-minute summary video
What about self-signed certificates?
Using self-signed certificates for HTTPS encryption is possible. That said, they often won't be recognised by browsers and applications, or generate warnings and error messages. On Android phones for example, self-signed certificates must first be imported and trusted. For these reasons, we suggest to privilege a Certificate Authority like Let's Encrypt.
PiHole setup – block ads & choose upstream DNS servers¶
Pi-hole is a nifty tool: it's capable of resolving local addresses such as https://myservice.gofoss.duckdns.org
, lets you pick an upstream DNS provider of your choice and blocks ads & trackers. Follow the instructions below to set up Pi-hole on your server.
Show me the step-by-step guide
Install PiHole¶
At the time of writing, 5.10 was the latest Pi-hole release. It's quite lightweight, 50 MB of free space and 512 MB of RAM are enough to run it on Ubuntu. Pi-hole also requires a static IP address as well as Apache and PHP, which we configured in previous chapters. Run Pi-hole's install script:
sudo curl -sSL https://install.pi-hole.net | bash
Follow the on-screen instructions:
Instruction | Description |
---|---|
This installer will transform your device into a network-wide ad blocker! | Hit ENTER to continue. |
The Pi-hole is free, but powered by your donations | Hit ENTER to continue. |
The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly | Select Yes , then hit ENTER to continue. |
Choose An Interface | Select your network interface. Press TAB to toggle the selection, SPACE to confirm your selection, and ENTER to continue. |
Select Upstream DNS Provider. To use your own, select Custom | Select a DNS provider of your choice. In this example, we'll use UncensoredDNS, but feel free to select any other DNS provider! We suggest to choose a DNS provider other than your ISP, Cloudfare or Google. Learn more about DNS providers at the end of this section. |
Pi-hole relies on third party lists in order to block ads. | Hit ENTER to continue. We'll explain later how to add more block lists. |
Do you wish to install the web admin interface? | Select On if you want a web interface (recommended), and hit ENTER to continue. |
Do you wish to install the web server (lighttpd)? | We'll use Apache as web server, instead of lighttpd. Select Off and confirm with SPACE , then hit ENTER to continue. |
Do you want to log queries? | Select On (recommended) and hit ENTER to continue. |
Select a privacy mode for FTL | Select the privacy level of your choice, and hit ENTER to continue: • Show everything : records everything; provides the maximum amount of statistics. • Hide domains : displays and stores all domains as "hidden"; disables the Top Domains and Top Ads tables on the dashboard. • Hide domains and clients : displays and stores all domains as "hidden" and all clients as "0.0.0.0"; disables all tables on the dashboard. • Anonymous mode : disables basically everything except the live anonymous statistics; no history is saved to the database, nothing is shown in the query log, there are no top item lists; provides enhanced privacy. |
Installation Complete! | Once the installation completes, you should see this: |
Pi-hole/admin web interface behind an Apache Reverse Proxy¶
We're going to set up an Apache Virtual Host as a Reverse Proxy to access the Pi-hole web interface. Sounds complex, but in essence a reverse proxy further shields the server from the Internet. You can read more about it at the end of this section.
Set the right permissions:
sudo chown www-data:www-data -R /var/www/html/admin/
sudo usermod -aG pihole www-data
sudo chown -R pihole:pihole /etc/pihole
Create an Apache configuration file:
sudo vi /etc/apache2/sites-available/mypihole.gofoss.duckdns.org.conf
Add the following content and make sure to adjust the settings to your own setup, such as domain names (mypihole.gofoss.duckdns.org
), path to SSL keys, IP addresses and so on:
<VirtualHost *:80>
ServerName mypihole.gofoss.duckdns.org
ServerAlias www.mypihole.gofoss.duckdns.org
Redirect permanent / https://mypihole.gofoss.duckdns.org/
</VirtualHost>
<VirtualHost *:443>
ServerName mypihole.gofoss.duckdns.org
ServerAlias www.mypihole.gofoss.duckdns.org
ServerSignature Off
SSLEngine On
SSLProxyEngine On
SSLProxyCheckPeerCN Off
SSLCertificateFile /etc/dehydrated/certs/gofoss.duckdns.org/fullchain.pem
SSLCertificateKeyFile /etc/dehydrated/certs/gofoss.duckdns.org/privkey.pem
DocumentRoot /var/www/html/admin
<Location />
Order deny,allow
Deny from all
Allow from 127.0.0.1
Allow from 192.168.1.0/24
Allow from 10.8.0.1/24
</Location>
<Directory /var/www/html/admin/>
Options +FollowSymlinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/mypihole.gofoss.duckdns.org-error.log
CustomLog ${APACHE_LOG_DIR}/mypihole.gofoss.duckdns.org-access.log combined
</VirtualHost>
Once the content is added, save and close the file (:wq!
). Note how we enable SSL encryption with the instruction SSLEngine On
, and use the SSL certicate /etc/dehydrated/certs/gofoss.duckdns.org/fullchain.pem
as well as the private SSL key /etc/dehydrated/certs/gofoss.duckdns.org/privkey.pem
, which were created earlier on.
Next, enable the Apache Virtual Host (adjust the domain accordingly):
sudo a2ensite mypihole.gofoss.duckdns.org.conf
sudo systemctl reload apache2
Restart Pi-hole and check if everything runs correctly. The output should display "Active":
sudo systemctl restart pihole-FTL
sudo systemctl status pihole-FTL
PiHole – change password, add PiHole block lists¶
Change the default password for Pi-hole's web interface. Provide a strong, unique password:
sudo pihole -a -p
Browse to http://192.168.1.100/admin/
and login with the new credentials. Make sure to adjust the server's IP address to your own setup. The web interface should show on the screen. It provides various settings, which are further described on Pi-hole's website:
Feature | Description |
---|---|
Gravity | Browse to Tools ‣ Update Gravity to fetch the latest block lists. Be patient, it can take some seconds. |
Dashboard | Displays statistics: how many domains have been visited or blocked, how many domains are on the blocklist, and so on. |
Queries | Detailed information on queries. |
Blocklists | Navigate to Group management ‣ Adlists to add more blocklists and filter additional ads and malware. You'll find more information about Pi-hole Blocklists at the end of this section. |
Settings | Easily manage and configure Pi-hole: DNS servers, privacy, etc. |
Local DNS | Pi-hole is capable of resolving local addresses. Navigate to Local DNS ‣ DNS Records and add the following domain/IP combination (adjust according to your own setup): Domain : mypihole.gofoss.duckdns.org IP Address : 192.168.1.100 |
Show me the 3-minute summary video
Temporary workaround for Ubuntu 22.04
At the time of writing, Pi-hole 5.10 doesn't officially support Ubuntu 22.04. For this reason, the usual Pi-hole install script doesn't work correctly. As a temporary workaround, execute the following commands instead:
sudo bash
curl -sSL https://install.pi-hole.net | PIHOLE_SKIP_OS_CHECK=true bash
Don't forget to exit the bash shell once the installation successfully completes. Simply type the following command:
exit
What is private DNS?
What is a DNS provider? On the Internet, each computer has its own IP address. Since these IP addresses aren't easy to remember, the Domain Name System (DNS) was invented. It works a bit like the former telephone switchboards: each time you enter a website address, a DNS resolver looks up the corresponding IP and connects your device to the appropriate computer/server. DNS therefore plays a key role when browsing the Internet. But since everything happens automatically, users often forget that DNS queries are an inherent risk to their privacy:
Risks | Description |
---|---|
Logging | DNS resolvers log every site you visit. Depending on the DNS resolver you use — or rather, which has been imposed on you — Google, Cloudflare, your Internet Service Provider (ISP), your telecom provider or any other third-party sees and stores a list of all websites you visit. Whether or not the traffic is encrypted over HTTPS doesn't matter. |
No encryption | DNS queries are mostly non-encrypted. Even if you fully trust your DNS resolver, without encrypted DNS traffic others could eavesdrop and try to manipulate you (spoofing attack). |
Censorship | Internet providers can also censor your online activities by tracking DNS queries. |
Pi-hole let's you choose which DNS resolver to trust when browsing the Web. Here some privacy-aware DNS providers:
DNS provider | Country | DNS #1 | DNS #2 | Privacy Policy |
---|---|---|---|---|
Digitalcourage | Germany | 5.9.164.112 | -- | Privacy Policy |
UncensoredDNS | Denmark | 89.233.43.71 | 91.239.100.100 | Privacy Policy |
Dismail | Germany | 80.241.218.68 | 159.69.114.157 | Privacy Policy |
DNS Watch | Germany | 84.200.69.80 | 84.200.70.40 | -- |
FDN | France | 80.67.169.12 | 80.67.169.40 | -- |
OpenNIC | Various | Various | Various | Various |
How to block ads? Is Pi-Hole a YouTube ad blocker?
Pi-hole filters web traffic and blocks ads or trackers on your devices, without the need for any additional software. By navigating to Pi-hole's web interface, you can add blocklists to filter additional ads and malware. Note however that Pi-Hole doesn't block in-video ads on YouTube (for that, you'll need something like uBlock Origin).
Block lists | Description |
---|---|
Default | • https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts • https://mirror1.malwaredomains.com/files/justdomains • http://sysctl.org/cameleon/hosts • https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist • https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt • https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt |
PiHole Adlists | • https://adaway.org/hosts.txt • https://v.firebog.net/hosts/AdguardDNS.txt • https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt • https://v.firebog.net/hosts/Easylist.txt • https://raw.githubusercontent.com/StevenBlack/hosts/master/data/SpotifyAds/hosts • https://raw.githubusercontent.com/StevenBlack/hosts/master/data/UncheckyAds/hosts |
Tracking & telemetry | • https://v.firebog.net/hosts/Airelle-trc.txt • https://v.firebog.net/hosts/Easyprivacy.txt • https://v.firebog.net/hosts/Prigent-Ads.txt • https://raw.githubusercontent.com/StevenBlack/hosts/master/data/tyzbit/hosts |
Malicious sites | • https://v.firebog.net/hosts/Airelle-hrsk.txt • https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt • https://mirror1.malwaredomains.com/files/justdomains • https://mirror.cedia.org.ec/malwaredomains/immortal_domains.txt • https://www.malwaredomainlist.com/hostslist/hosts.txt • https://bitbucket.org/ethanr/dns-blacklists/raw/8575c9f96e5b4a1308f2f12394abd86d0927a4a0/bad_lists/Mandiant_APT1_Report_Appendix_D.txt • https://v.firebog.net/hosts/Prigent-Malware.txt • https://v.firebog.net/hosts/Prigent-Phishing.txt • https://v.firebog.net/hosts/Shalla-mal.txt • https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Risk/hosts |
What is a Reverse Proxy?
A Reverse Proxy is an application sitting between a service running on your server and the Internet. All services presented on our website, including Pi-hole, are set up as Apache Virtual Hosts behind a Reverse Proxy. This allows to:
- prevent the server from being directly exposed to the Internet
- run several services side by side on a single server
- minimise the number of open ports (typically ports 80 and 443)
- reach services over custom addresses, rather than random IP addresses and port numbers
- easily manage SSL certificates
- configure distinct security policies, such as HTTP headers, user authentication, access restrictions, and so on
In Ubuntu, Apache Virtual Host configuration files are located in the directory etc/apache2/sites-available
. Here an Apache Virtual Host example:
<VirtualHost *:80>
ServerName example.com # address of the service
ServerAlias www.example.com # address of the service, including www subdomain
Redirect permanent / https://example.com/ # redirection of all non-encrypted http:// traffic to encrypted https:// traffic
</VirtualHost>
<VirtualHost *:443>
ServerName example.com # address of the service
ServerAlias www.example.com # address of the service, including www
ServerSignature Off # hide server information
SSLEngine On # use SSL/TLS protocol
SSLProxyEngine On # use SSL/TLS protocol for proxy
SSLCertificateFile /path/to/fullchain.pem # location of the SSL certificate file in PEM format
SSLCertificateKeyFile /path/to/privkey.pem # location of the PEM-encoded private SSL key file
DocumentRoot /var/www/example # directory from which Apache will serve files
<Location /> # limit access to server, home network (LAN) and VPN
Order deny,allow
Deny from all
Allow from 127.0.0.1
Allow from 192.168.1.0/24
Allow from 10.8.0.1/24
</Location>
<Directory /var/www/example>
Options -Indexes +FollowSymLinks # prevent directory listings and follow symbolic links
AllowOverride All # directives from .htaccess file which can override configuration directives
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log # log files
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined # log files
</VirtualHost>
The Virtual Host is enabled with sudo a2ensite example.com
. Check if there are any syntax errors with sudo apachectl configtest
.
Tell me more about Pi-hole terminal commands
Most of Pi-hole's configuration can be performed on the web interface. Alternatively, you can also configure Pi-hole directly on the server, via the terminal. The full list of commands can be found on Pi-hole's website:
Command | Description |
---|---|
pihole status | status |
pihole -t tail log | real time log |
pihole -c | statistics |
pihole -w -l | list whitelisted domains |
pihole -w example.com | add example.com to whitelist |
pihole -w -d example.com | remove example.com from whitelist |
pihole -b -l | list blacklisted domains |
pihole -b example.com | add example.com to blacklist |
pihole -b -d example.com | remove example.com from blacklist |
pihole -up | update pihole |
pihole -l off | query logging off |
pihole -l on | query logging on |
pihole enable | enable pihole |
pihole disable | disable pihole |
pihole disable 10m | disable pihole for 10 minutes |
pihole disable 60s | disable pihole for 60 seconds |
pihole uninstall | uninstall pihole |
Secure remote access with OpenVPN¶
At this stage, the server is only accessible from within your home network, since it's shielded from the Internet by a firewall. One solution to enable remote access would be to "poke" multiple holes into the firewall and forward ports for each service from your router to the server. This would however expose multiple ports to the Internet and provide attackers with a larger attack surface to force their way into your network.
A Virtual Private Network (VPN) allows to connect to the server from anywhere in the world while mitigating this risk. Only one single port is made public, and only pre-authorised connections are allowed, requiring both a certificate and a password. Read on below for detailed instructions.
Show me the step-by-step guide
OpenVPN installation¶
OpenVPN is open source and uses OpenSSL, TLS and many security features. It can be set up with an easy install script:
wget https://git.io/vpn -O openvpn-install.sh
sudo bash openvpn-install.sh
Follow the on-screen instructions:
Prompt | Instructions |
---|---|
What is the public IPv4 address or hostname? | Enter your public IPv4 address, which you can find for example on whatsmyip.org. For this tutorial, let's assume your public IP address is 88.888.88.88 (adjust accordingly). |
Which protocol do you want for OpenVPN connections? | Choose the recommended UDP protocol. |
What port do you want OpenVPN listening to? | Choose a port, for the purpose of this tutorial we'll use the standard port 1194 . |
Which DNS do you want to use with the VPN? | Since we're using Pi-hole as DNS server, select the option Current system resolvers . |
Finally, tell me your name for the client certificate. | Choose a name for your first VPN client certificate. For the purpose of this tutorial, we'll create a certificate labelled computer_vpn , adjust accordingly. |
Once the installation completes, the terminal should look similar to this:
Welcome to this OpenVPN road warrior installer!
I need to ask you a few questions before starting setup.
You can use the default options and just press enter if you are ok with them.
This server is behind NAT. What is the public IPv4 address or hostname?
Public IPv4 address / hostname [88.888.88.88]: 88.888.88.88
What IPv6 address should the OpenVPN server use?
1) 1a00:a0a:10a:10a0:a00:00ff:faf0:a011
2) 1a00:a0a:10a:10a0:a00:00bb:faf0:a022
IPv6 address [1]: 1
Which protocol do you want for OpenVPN connections?
1) UDP (recommended)
2) TCP
Protocol [1]: 1
What port do you want OpenVPN listening to?
Port [1194]: 1194
Which DNS do you want to use with the VPN?
1) Current system resolvers
2) 1.1.1.1
3) Google
4) OpenDNS
5) NTT
6) AdGuard
DNS [1]: 1
Finally, tell me a name for the client certificate.
Client name [client]: computer_vpn
We are ready to set up your OpenVPN server now.
[etc.]
Finished!
The client configuration is available in: /root/computer_vpn.ovpn
New clients can be added by running this script again.
Certificates¶
A first VPN client certificate, computer_vpn.ovpn
, has been generated during the installation of OpenVPN. Create as many certificates as needed by re-running the install script, one for each device connecting to the server: desktop computers, laptops, tablets, phones, etc.
For the purpose of this tutorial, we'll create a second certificate called phone_vpn.ovpn
. Of course, you can choose any name for the certificates. Just make sure to adjust the commands accordingly:
sudo bash openvpn-install.sh
The terminal should display something similar to:
Looks like OpenVPN is already installed.
What do you want to do?
1) Add a new user
2) Revoke an existing user
3) Remove OpenVPN
4) Exit
Select an option: 1
Tell me a name for the client certificate.
Client name: phone_vpn
[...]
Write out database with 1 new entries
Data Base Updated
Client phone_vpn added, configuration is available at: /root/phone_vpn.ovpn
Finally, move the certificate(s) to the gofossadmin
home folder and set the correct permissions:
cd
sudo mv /root/computer_vpn.ovpn .
sudo mv /root/phone_vpn.ovpn .
sudo chmod 755 *.ovpn
sudo chown gofossadmin:gofossadmin *.ovpn
OpenVPN configuration¶
Open port 1194 (UDP), or whatever port you specified during the installation of OpenVPN:
sudo ufw allow 1194/udp
Check if the port has been successfully added to the firewall rules:
sudo ufw status numbered
Confirm whether the virtual interface tun0
works, and get the name of the default subnetwork:
ip ad | grep tun0
Get the OpenVPN server's IP address:
ip route | grep tun0
Make sure traffic is routed via the VPN tunnel:
sudo apt install traceroute
traceroute 10.8.0.1
Next, we are going to tell clients which connect to the VPN to use Pi-hole as primary DNS server. Edit the OpenVPN configuration file:
sudo vi /etc/openvpn/server/server.conf
Comment out all existing dhcp-option
settings (put a hashtag #
at the beginning of the respective line) and replace them with the tun0
interface:
#push "dhcp-option DNS XX.XX.XXX.XXX"
#push "dhcp-option DNS XX.XX.XXX.XXX"
push "dhcp-option DNS 10.8.0.1"
Restart the OpenVPN server:
sudo systemctl restart openvpn-server@server
Browse to the Pi-hole web interface, in this example http://192.168.1.100/admin
(adjust accordingly). Then navigate to Settings ‣ DNS ‣ Interface settings
and select the option Permit all origins
. Then click on Save
.
Router settings
Check your router settings and make sure:
- the port used by OpenVPN is forwarded correctly (in this example
1194
, adjust accordingly). Refer to the router's manual for more information - the port
53
is closed. Scan for open ports using the tools of Gibson Research Corporation: selectProceed ‣ All service ports
and make sure port53
doesn't appear asopen
Clients¶
Only devices with valid certificates can establish a VPN connection to securely access self-hosted services. Here is how to transfer the previously generated certificates from the server to the devices.
We assume the client device runs Ubuntu/Linux and can establish a remote SSH login. Open a terminal on the client device, switch to the administrator user (adjust accordingly) and retrieve all certificates from the server:
su - gofossadmin
scp -v -P 2222 gofossadmin@192.168.1.100:/home/gofossadmin/*.ovpn .
Finally, configure the device's network connection:
Step | Instruction |
---|---|
1 | Click on the Wifi icon in the top bar. |
2 | Click on Settings . |
3 | Navigate to the Network menu entry. |
4 | Click on the + icon in the VPN section. |
5 | Select Import from file . |
6 | Browse to the certificate (in this example computer_vpn.ovpn ) and click on Open . |
7 | Click on the Wifi icon in the top bar. |
8 | Enable the VPN connection computer_vpn . |
That's it! Your desktop device can securely connect to the server via VPN, from anywhere in the world.
Open F-Droid on your mobile device and install OpenVPN for Android.
Connect the mobile device via USB to the desktop device with which you retrieved all certificates from the server (cf. above). Copy the certificate from the desktop device to the mobile device (in this example, the certificate is named phone_vpn.ovpn
, adjust accordingly).
Finally, open the OpenVPN app on your mobile device and configure it:
Step | Instruction |
---|---|
1 | Tap on + and then Import . |
2 | Browse to the certificate (in this example phone_vpn.ovpn ) and import it. |
That's it! Your mobile device can securely connect to the server via VPN, from anywhere in the world.
OpenVPN & PiHole test¶
Now that everything is set up, traffic should be handled as follows:
- Each time one of your devices looks up an address, it securely connects to the server via VPN
- If the address contains ads or trackers, Pi-hole blocks those elements
- If the address points to a self-hosted service, Pi-hole redirects the request to the service on the server
- If the address points to an external website or service, Pi-hole redirects the request to an upstream DNS server of your choice (e.g. Digitalcourage, UncensoredDNS, etc.)
- All traffic is encrypted via HTTPS
Make sure everything runs smoothly:
- browse to ads-blocker.com or cnn.com an verify if ads are blocked. You can also browse to
https://mypihole.gofoss.duckdns.org
(adjust accordingly) and check the dashboard for blocked queries - browse to a local service, such as
https://mypihole.gofoss.duckdns.org
(adjust accordingly), and verify the address is resolved correctly - browse to dnsleaktest.com or bash.ws and make sure you're using the correct upstream DNS resolver
Support¶
For further details or questions, refer to Pi-hole's documentation, Let's Encrypt's documentation, OpenVPN's documentation or ask the Pi-hole community, the Let's Encrypt community or the OpenVPN community for help.