mirror of
https://github.com/pi-hole/docs.git
synced 2024-12-06 19:27:12 +01:00
Merge pull request #25 from pi-hole/fix/vpnguide
Update VPN docs from last wiki revision
This commit is contained in:
@@ -1,7 +1,39 @@
|
||||
1. Install the official OpenVPN App
|
||||
See [App Store](https://play.google.com/store/apps/details?id=net.openvpn.openvpn)
|
||||
Full article: https://github.com/pi-hole/pi-hole/wiki/Pi-hole---OpenVPN-server
|
||||
|
||||
2. Create a new certificate as described [here](clients.md#create-certificate)
|
||||
1. Install the official OpenVPN App from the [App Store](https://play.google.com/store/apps/details?id=net.openvpn.openvpn)
|
||||
|
||||
2. Log into your OpenVPN server and use the road warrior installer to create a new certificate for your device:
|
||||
```
|
||||
root@ubuntu-512mb-fra1-01:~# bash openvpn-install.sh
|
||||
Looks like OpenVPN is already installed
|
||||
|
||||
What do you want to do?
|
||||
1) Add a cert for a new user
|
||||
2) Revoke existing user cert
|
||||
3) Remove OpenVPN
|
||||
4) Exit
|
||||
Select an option [1-4]: 1
|
||||
|
||||
Tell me a name for the client cert
|
||||
Please, use one word only, no special characters
|
||||
Client name: android
|
||||
Generating a 2048 bit RSA private key
|
||||
.....+++
|
||||
..................................+++
|
||||
writing new private key to '...'
|
||||
-----
|
||||
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.cnf
|
||||
Check that the request matches the signature
|
||||
Signature ok
|
||||
The Subject's Distinguished Name is as follows
|
||||
commonName :ASN.1 12:'android'
|
||||
Certificate is to be certified until Jan 25 15:07:37 2027 GMT (3650 days)
|
||||
|
||||
Write out database with 1 new entries
|
||||
Data Base Updated
|
||||
|
||||
Client android added, configuration is available at /root/android.ovpn
|
||||
```
|
||||
|
||||
3. Copy the mentioned file (`/root/android.ovpn`) to your Android device (e.g. SD card) and import it in the app:
|
||||
|
||||
@@ -15,8 +47,8 @@
|
||||
|
||||
4. Connect to your OpenVPN server
|
||||
|
||||

|
||||

|
||||
|
||||
5. You are ready to go!
|
||||
|
||||

|
||||

|
||||
+41
-29
@@ -1,49 +1,62 @@
|
||||
### Connect from a client
|
||||
There are various tutorials available for all operating systems for how to connect to an OpenVPN server.
|
||||
## Create a client config file (`.ovpn`)
|
||||
|
||||
Now that the server is configured, you'll want to connect some clients so you can make use of your Pi-hole wherever you are. Doing so requires the use of a certificate. You generate these and the resulting `.ovpn` file by running the installer and choosing `1) Add a new user` for each client that will connect to the VPN.
|
||||
|
||||
You can repeat this process for as many clients as you need. In this example, we'll "Add a new user" by naming the `.ovpn` file the same as the client's hostname but you may want to adopt your own naming strategy.
|
||||
|
||||
Run the OpenVPN installer again
|
||||
|
||||
### Create certificate
|
||||
Log into your OpenVPN server and use the road warrior installer to create a new certificate for your client:
|
||||
```
|
||||
bash openvpn-install.sh
|
||||
./openvpn-install.sh
|
||||
```
|
||||
|
||||
Choose `1) Add a new user` and enter a client name
|
||||
```
|
||||
Looks like OpenVPN is already installed
|
||||
|
||||
What do you want to do?
|
||||
1) Add a cert for a new user
|
||||
2) Revoke existing user cert
|
||||
1) Add a new user
|
||||
2) Revoke an existing user
|
||||
3) Remove OpenVPN
|
||||
4) Exit
|
||||
Select an option [1-4]: 1
|
||||
|
||||
Tell me a name for the client cert
|
||||
Tell me a name for the client certificate
|
||||
Please, use one word only, no special characters
|
||||
Client name: android
|
||||
Generating a 2048 bit RSA private key
|
||||
.....+++
|
||||
..................................+++
|
||||
writing new private key to '...'
|
||||
-----
|
||||
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.cnf
|
||||
Check that the request matches the signature
|
||||
Signature ok
|
||||
The Subject's Distinguished Name is as follows
|
||||
commonName :ASN.1 12:'android'
|
||||
Certificate is to be certified until Jan 25 15:07:37 2027 GMT (3650 days)
|
||||
|
||||
Write out database with 1 new entries
|
||||
Data Base Updated
|
||||
|
||||
Client android added, configuration is available at /root/android.ovpn
|
||||
Client name: iphone7
|
||||
```
|
||||
|
||||
**WARNING** Anyone who gets his hands on this configuration/certificate file can obtain full access to your VPN. Make sure that you use only trusted paths for transferring the file (e.g. *never* send it via an un-encrypted channel, e.g. email or FTP). Best strategy is to use a USB thumb drive to avoid any network transport at all. Make sure to delete the certificate on the USB drive afterwards.
|
||||
This will generate a `.ovpn` file, which needs to be copied to your client machine (often times using the OpenVPN app). This process also generates a few other files found in `/etc/openvpn/easy-rsa/pki/`, which make public key authentication possible; you only need to worry about the `.ovpn` file, though.
|
||||
|
||||
**NOTICE** If one of your certificates has been compromised, remove it using option `2` (see above) and generate a new certificate. This will effectively lock out anyone who might have gotten access to the certificate.
|
||||
## Connect a client using the `.ovpn` file
|
||||
|
||||
The OpenVPN documentation has some decent [guides on connecting desktop clients for Mac, Windows, and Linux](https://openvpn.net/index.php/access-server/docs/admin-guides-sp-859543150/howto-connect-client-configuration.html), so we'll instead explain how to connect a mobile device, since that provides the most usefulness in today's world--**connecting to your ad-blocking VPN via a mobile device**. We'll go through two examples:
|
||||
|
||||
1. connect an iPhone using the OpenVPN Connect mobile app (see [here](https://github.com/pi-hole/pi-hole/wiki/OpenVPN-server:-Connect-from-a-client-(Android)) for Android)
|
||||
2. connect a Linux machine
|
||||
|
||||
### iOS
|
||||
First make sure the OpenVPN connect app is installed on your phone or mobile device.
|
||||
|
||||
Import the `.ovpn` file into iOS. There are several ways to do this, but be careful about transferring it over an insecure medium.
|
||||
|
||||
1. Airdrop the file from another device
|
||||
2. Store the file in a cloud app and open it ion your device
|
||||
3. Message the file to yourself (not recommended)
|
||||
4. Email the file to yourself (not recommended)
|
||||
|
||||
>**WARNING** Anyone who gets his hands on this configuration/certificate file can obtain full access to your VPN. Make sure that you use only trusted paths for transferring the file (e.g. never send it via an un-encrypted channel, e.g. email or FTP). Best strategy is to use an USB thumb drive to avoid any network transport at all (when possible). Make sure to delete the certificate on the USB drive afterwards.
|
||||
|
||||
>**NOTICE** If one of your certificates has been compromised, remove it using option 2 when you run the installer and generate a new certificate. This will effectively lock out anyone who might have gotten access to the certificate.
|
||||
|
||||
Once you get it on your device, you can open the file in the OpenVPN app.
|
||||
|
||||
Click the green plus to add the profile to your phone.
|
||||
|
||||
You can connect from within the app or you can connect from the Settings app once you grant it access to do so.
|
||||
|
||||
### Linux
|
||||
I'll demonstrate the procedure here for Ubuntu Linux (which trivially extends to Linux Mint, etc.)
|
||||
We'll demonstrate the procedure here for Ubuntu Linux (which trivially extends to Linux Mint, etc.)
|
||||
|
||||
1. Install the necessary network-manager plugins
|
||||
```
|
||||
@@ -67,7 +80,6 @@ Further details can be found in the screenshots provided below:
|
||||

|
||||

|
||||

|
||||
|
||||
Your whole network traffic will now securely be transferred to your Pi-hole.
|
||||

|
||||
|
||||
|
||||
+151
-77
@@ -1,93 +1,167 @@
|
||||
### Optional: Firewall configuration (using iptables)
|
||||
If your server is visible to the world, you will want prevent port 53/80 from being accessible from the global Internet. You will want be only able to connect to your Pi-hole from within the VPN.
|
||||
### (optional) Secure the server with firewall rules (`iptables`)
|
||||
|
||||
**This step is recommended if you are running your server in the cloud, such as a droplet made on [Digital Ocean](http://www.digitalocean.com/?refcode=344d234950e1)**. If this is the case, you need to secure the server for your safety as well as others to prevent aiding in DDoS attacks.
|
||||
|
||||
In addition to the risk of being an open resolver, your Web interface is also open to the world increasing the risk. So you will want to prevent ports 53 and 80, respectively, from being accessible from the public Internet.
|
||||
|
||||
It's recommended that you [clear out your entire firewall](https://serverfault.com/questions/200635/best-way-to-clear-all-iptables-rules) so you have full control over it's setup. You have two options for setting up your firewall with your VPN.
|
||||
|
||||
#### Option 1: Allow everything from within your VPN
|
||||
|
||||
Enter this command, which will allow all traffic through the VPN `tun0` interface.
|
||||
|
||||
Using `iptables`: First, verify that there is no rule that explicitly accepts `http` requests
|
||||
```
|
||||
sudo iptables -L --line-numbers
|
||||
iptables -I INPUT -i tun0 -j ACCEPT
|
||||
```
|
||||
|
||||
If you get something like
|
||||
```
|
||||
Chain INPUT (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
1 ACCEPT tcp -- anywhere anywhere tcp dpt:http
|
||||
2 ACCEPT tcp -- anywhere anywhere tcp dpt:domain
|
||||
3 ACCEPT udp -- anywhere anywhere udp dpt:domain
|
||||
#### Option 2: Explicitly allow what can be accessed within the VPN
|
||||
|
||||
Chain FORWARD (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
These commands will allow DNS and HTTP needed for name resolution (using Pi-hole as a resolver) and accessing the Web interface, respectively.
|
||||
|
||||
Chain OUTPUT (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
```
|
||||
you have to first explicitly delete the first INPUT rule using:
|
||||
```
|
||||
sudo iptables -D INPUT 1
|
||||
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
|
||||
```
|
||||
|
||||
We recommend that you empty out the firewall so you have full control over its setup.
|
||||
You will also want to enable SSH and VPN access from anywhere.
|
||||
|
||||
For setting up your firewall in conjunction with your VPN you have **TWO** options:
|
||||
|
||||
Option 1: Allow everything within your VPN:
|
||||
```
|
||||
sudo iptables -I INPUT -i tun0 -j ACCEPT
|
||||
```
|
||||
or
|
||||
|
||||
Option 2: Explicitly allow what can be accessed from within the VPN:
|
||||
```
|
||||
sudo iptables -A INPUT -i tun0 -p tcp --destination-port 53 -j ACCEPT
|
||||
sudo iptables -A INPUT -i tun0 -p udp --destination-port 53 -j ACCEPT
|
||||
sudo iptables -A INPUT -i tun0 -p tcp --destination-port 80 -j ACCEPT
|
||||
sudo iptables -A INPUT -i tun0 -p udp --destination-port 80 -j ACCEPT
|
||||
```
|
||||
|
||||
Obviously, it is important to enable SSH and VPN access from anywhere
|
||||
```
|
||||
sudo iptables -A INPUT -p tcp --destination-port 22 -j ACCEPT
|
||||
sudo iptables -A INPUT -p tcp --destination-port 1194 -j ACCEPT
|
||||
sudo iptables -A INPUT -p udp --destination-port 1194 -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
|
||||
```
|
||||
|
||||
The next crucial setting is to explicitly allow TCP/IP to do "three way handshakes":
|
||||
```
|
||||
sudo iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
```
|
||||
|
||||
Also, we want to allow any loopback traffic, i.e. the Pi is allowed to talk to itself without any limitations using `127.0.0.0/8`:
|
||||
```
|
||||
sudo iptables -I INPUT -i lo -j ACCEPT
|
||||
```
|
||||
|
||||
Finally, prevent access from anywhere else (i.e. if no rule has matched up to this point):
|
||||
```
|
||||
sudo iptables -P INPUT DROP
|
||||
```
|
||||
|
||||
Optional: If you want to allow access to the Pi-hole from within the VPN *and* from the local network, you will have to explicitly allow your local network as well (assuming the local network is within the address space 192.168.**178**.1 - 192.168.**178**.254):
|
||||
```
|
||||
sudo iptables -A INPUT -s 192.168.178.0/24 -p tcp --destination-port 53 -j ACCEPT
|
||||
sudo iptables -A INPUT -s 192.168.178.0/24 -p udp --destination-port 53 -j ACCEPT
|
||||
sudo iptables -A INPUT -s 192.168.178.0/24 -p tcp --destination-port 80 -j ACCEPT
|
||||
sudo iptables -A INPUT -s 192.168.178.0/24 -p udp --destination-port 80 -j ACCEPT
|
||||
```
|
||||
See also [this](https://discourse.pi-hole.net/t/pihole-vpn-with-iptables/2384) thread on Discourse.
|
||||
|
||||
---
|
||||
### Optional: IPv6
|
||||
|
||||
Note that you will have to repeat the firewall setup using `ip6tables` if your server is also reachable via IPv6:
|
||||
|
||||
```
|
||||
sudo ip6tables -A INPUT -i tun0 -p tcp --destination-port 53 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -i tun0 -p tcp --destination-port 80 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -i tun0 -p udp --destination-port 53 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -i tun0 -p udp --destination-port 80 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p tcp --destination-port 22 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p tcp --destination-port 1194 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p udp --destination-port 1194 -j ACCEPT
|
||||
sudo ip6tables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo ip6tables -I INPUT -i lo -j ACCEPT
|
||||
sudo ip6tables -P INPUT DROP
|
||||
```
|
||||
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
```
|
||||
|
||||
Also, we want to allow any loopback traffic, i.e. the server is allowed to talk to itself without any limitations using 127.0.0.0/8:
|
||||
|
||||
```
|
||||
iptables -I INPUT -i lo -j ACCEPT
|
||||
```
|
||||
|
||||
Finally, reject access from anywhere else (i.e. if no rule has matched up to this point):
|
||||
|
||||
```
|
||||
iptables -P INPUT DROP
|
||||
```
|
||||
|
||||
###### Blocking HTTPS advertisement assets
|
||||
|
||||
Since you're `:head-desk:`ing with `iptables`, you can also use this opportunity to block HTTPS advertisements to [improve blocking ads that are loaded via HTTPS](https://discourse.pi-hole.net/t/why-do-some-sites-take-forever-to-load-when-using-pi-hole/3654/4) and also deal with QUIC.
|
||||
|
||||
> Why doesn't Pi-hole just use a certificate to prevent this? The answer is [here](https://discourse.pi-hole.net/t/slow-loading-websites/3408/12).
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Depending on the systems you have connecting, you may benefit from appending `--reject-with tcp-reset` to the command above. If you still get slow load times of HTTPS assets, the above may help.
|
||||
|
||||
If you want to test how your Pi-hole behaves with blocking HTTP vs. HTTPS assets, use [this page](https://pi-hole.net/pages-to-test-ad-blocking-performance/#https-test).
|
||||
|
||||
##### IPv6 `iptables`
|
||||
|
||||
If your server is reachable via IPv6, you'll need to run the same commands but using `ip6tables`:
|
||||
|
||||
```
|
||||
ip6tables -A INPUT -i tun0 -p tcp --destination-port 53 -j ACCEPT
|
||||
ip6tables -A INPUT -i tun0 -p udp --destination-port 53 -j ACCEPT
|
||||
ip6tables -A INPUT -i tun0 -p tcp --destination-port 80 -j ACCEPT
|
||||
ip6tables -A INPUT -p tcp --destination-port 22 -j ACCEPT
|
||||
ip6tables -A INPUT -p tcp --destination-port 1194 -j ACCEPT
|
||||
ip6tables -A INPUT -p udp --destination-port 1194 -j ACCEPT
|
||||
ip6tables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
ip6tables -I INPUT -i lo -j ACCEPT
|
||||
ip6tables -A INPUT -p udp --dport 80 -j REJECT --reject-with icmp6-port-unreachable
|
||||
ip6tables -A INPUT -p tcp --dport 443 -j REJECT --reject-with tcp-reset
|
||||
ip6tables -A INPUT -p udp --dport 443 -j REJECT --reject-with icmp6-port-unreachable
|
||||
ip6tables -P INPUT DROP
|
||||
```
|
||||
View the rules you just created
|
||||
|
||||
```
|
||||
iptables -L --line-numbers
|
||||
```
|
||||
|
||||
and they should look something like this:
|
||||
|
||||
```
|
||||
Chain INPUT (policy DROP)
|
||||
num target prot opt source destination
|
||||
1 ACCEPT all -- anywhere anywhere
|
||||
2 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
|
||||
3 ACCEPT all -- anywhere anywhere
|
||||
4 ACCEPT tcp -- anywhere anywhere tcp dpt:domain
|
||||
5 ACCEPT udp -- anywhere anywhere udp dpt:domain
|
||||
6 ACCEPT tcp -- anywhere anywhere tcp dpt:http
|
||||
7 ACCEPT udp -- anywhere anywhere udp dpt:80
|
||||
8 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
|
||||
9 ACCEPT tcp -- anywhere anywhere tcp dpt:openvpn
|
||||
10 ACCEPT udp -- anywhere anywhere udp dpt:openvpn
|
||||
11 ACCEPT tcp -- 10.8.0.0/24 anywhere tcp dpt:domain
|
||||
12 ACCEPT udp -- 10.8.0.0/24 anywhere udp dpt:domain
|
||||
13 ACCEPT tcp -- 10.8.0.0/24 anywhere tcp dpt:http
|
||||
14 ACCEPT udp -- 10.8.0.0/24 anywhere udp dpt:80
|
||||
15 ACCEPT tcp -- 10.8.0.0/24 anywhere tcp dpt:domain
|
||||
16 ACCEPT tcp -- 10.8.0.0/24 anywhere tcp dpt:http
|
||||
17 ACCEPT udp -- 10.8.0.0/24 anywhere udp dpt:domain
|
||||
18 ACCEPT udp -- 10.8.0.0/24 anywhere udp dpt:80
|
||||
19 REJECT tcp -- anywhere anywhere tcp dpt:https reject-with icmp-port-unreachable
|
||||
|
||||
Chain FORWARD (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
|
||||
Chain OUTPUT (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
```
|
||||
|
||||
Similarly, `ip6tables -L --line-numbers` should look like this:
|
||||
|
||||
```
|
||||
Chain INPUT (policy DROP)
|
||||
num target prot opt source destination
|
||||
1 ACCEPT all anywhere anywhere
|
||||
2 ACCEPT all anywhere anywhere state RELATED,ESTABLISHED
|
||||
3 ACCEPT tcp anywhere anywhere tcp dpt:domain
|
||||
4 ACCEPT udp anywhere anywhere udp dpt:domain
|
||||
5 ACCEPT tcp anywhere anywhere tcp dpt:http
|
||||
6 ACCEPT udp anywhere anywhere udp dpt:80
|
||||
7 ACCEPT tcp anywhere anywhere tcp dpt:ssh
|
||||
8 ACCEPT tcp anywhere anywhere tcp dpt:openvpn
|
||||
9 ACCEPT udp anywhere anywhere udp dpt:openvpn
|
||||
10 REJECT tcp anywhere anywhere tcp dpt:https reject-with icmp6-port-unreachable
|
||||
|
||||
Chain FORWARD (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
|
||||
Chain OUTPUT (policy ACCEPT)
|
||||
num target prot opt source destination
|
||||
```
|
||||
|
||||
##### Verify the rules are working
|
||||
|
||||
Connect to the VPN as a client and verify you can resolve DNS names as well as access the Pi-hole Web interface. These settings are stored in memory until you save them. If it's not working, you can restart your server to start from scratch. Alternatively, you could also go through and delete lines with `iptables -D INPUT <SOME LINE NUMBER>`
|
||||
|
||||
#### Save your `iptables`
|
||||
|
||||
If things look good, you may want to save your rules so you can revert to them if you ever make changes to the firewall. Save them with these commands:
|
||||
|
||||
```
|
||||
iptables-save > /etc/pihole/rules.v4
|
||||
ip6tables-save > /etc/pihole/rules.v6
|
||||
```
|
||||
|
||||
Similarly, you can restore these rules:
|
||||
|
||||
```
|
||||
iptables-restore < /etc/pihole/rules.v4
|
||||
ip6tables-restore < /etc/pihole/rules.v6
|
||||
```
|
||||
---
|
||||
@@ -1,8 +1,9 @@
|
||||
### Optional: Only route DNS via VPN
|
||||
|
||||
With this setup you will force connected clients to use only the DNS provided by the VPN connection, i.e. the Pi-hole. Do this only if you **don't** want to tunnel all traffic from the client thru the VPN, but only its DNS queries.
|
||||
With this setup, you will force connected clients to use **only the DNS provided by the VPN connection, i.e. the Pi-hole.** Do this only if you **don't** want to tunnel all traffic from the client through the VPN, but only its DNS queries.
|
||||
|
||||
Edit your `/etc/openvpn/server.conf` and remove (comment out) the following line:
|
||||
|
||||
Edit your `/etc/openvpn/server.conf` and remove (comment) the following line:
|
||||
```
|
||||
# push "redirect-gateway def1 bypass-dhcp"
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user