OpenVPN + Pihole: Pihole works on LAN, VPN connects, but can't ping or connect to the internet or devices in my home network other than pihole over the VPN connection

Expected Behaviour:

I am able to access the internet via pihole's dns sinkhole on my local lan and when connected via openvpn.

Actual Behaviour:

I am able to use pihole normally on my lan and connect to the vpn, however when connected via openvpn, I can't access the internet or other devices on my network, only the raspberry pi running pihole and openvpn via ssh and the web panel.

Debug Token:

https://tricorder.pi-hole.net/dvcgds1knr

I followed the official pihole and openvpn setup guide. Pihole is set to listen on all interfaces and permit all origins and port UDP 1194 is forwarded to 192.168.1.2. It probably isn't relevant, but the ethernet interface pihole is listening on is called enxb827eb887102 instead of eth0.

I seem to be having the same issue as the person here: Openvpn + pihole : LAN works, VPN connects but no connection and I tried to use their solution, however, I'm not using ip tables, so it doesn't work for me.

This is my /etc/openvpn/server.conf and /etc/openvpn/server/server.conf

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0
server-ipv6 fddd:1194:1194:1194::/64
push "redirect-gateway def1 ipv6 bypass-dhcp"
ifconfig-pool-persist ipp.txt
push "route 192.168.1.0 255.255.255.0"
push "dhcp-option DNS 192.168.1.2"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
crl-verify crl.pem
explicit-exit-notify

I can't figure out why it won't work, any help would be greatly appreciated.

How do you route the packets between the interfaces if you're not using iptables ?

Hi, thanks for the reply,

I didn't initially realise what ip tables were, I assumed they were just something you setup if your server wasn't behind a nat network because in the official documentation, there is a firewall section which says that issuing these certain commands needed to be done if your server wasn't behind a nat network. I didn't realise that they were still there, just automatically configured if behind a nat network. I also assumed this because in the other thread I linked to, the guy had the file /etc/pihole/rules.v4 which I didn't have and rules.v4 was part of the firewall documentation I talked about earlier, so I thought he must be running his server in the cloud and therefore thought that his solution didn't apply to me.

However, I'm still confused as to how I will actually be able to get it working.

It's going to be an easy fix :slight_smile:

what is the output of sudo iptables -L

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere udp dpt:openvpn

Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT all -- 10.8.0.0/24 anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Does this mean that the output's not configured and that's why it's not working

When the setup asked you what port you want it on, it expected a numeric value which would have transitioned here.

Not quite sure how it's working for you, but that definitely is not the right setting.

Let's purge all the settings and re-add them properly, in order for your VPN to work as it needs to.

Please issue the following commands (while root):

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
iptables -I INPUT -p udp --dport 1194 -j ACCEPT
iptables -I FORWARD -s 10.8.0.0/24 -j ACCEPT
iptables -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 192.168.1.2

This should get you back in business, the proper way.

Unless you use iptables persistent, I recommend adding that last line to/etc/rc.local in order to "inject" it after every reboot.

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 192.168.1.2

Thank you so much, this fixed it instantly, I also did a reboot to make sure that the injecting of the last line worked and it did perfectly. Thanks again for all your help :smile:

1 Like

Hi, I thought my problem was fixed, but it turns out it only partially is. I am able to connect to the internet and ping devices on my local network when accessing the vpn through my local network, but when outside of my local network, I am able to connect to the vpn, but unable to connect to the internet or ping devices other than pihole.

I have port forwarded 1194 on my router and I ran a udp open port scanner and it verified that the port was open.

Many thanks

I think your Pi-hole needs to be set to “Listen to all, permit all origins” under settings/dns/listening behavior

Thanks for your reply, it was already set to that, I set it to only listen on the pihole interface, and then set it back to Listen on all interfaces, permit all origins, but it still doesn't work

Do you have a /etc/dnsmasq.d/02-pivpn.conf file that locks Pi-hole to a specific interface?

No, I have 01-pihole.conf, 02-pihole-dhcp.conf and 04-pihole-static-dhcp.conf, but no 02-pivpn.conf

In 01-pihole.conf, there is a line that says except-interface=nonexisting, if that's any help

That will allow pihole-FTL to listen on all interfaces but if the VPN interface is not up when pihole-FTL starts then it will not be accepted.

The first option "Listen on all interfaces" might be better for you.

I've discovered the problem, the iptables commands I was given are being removed after every reboot, even though I added the last line in /etc/rc.local, but I might not have added correctly, is it correct? I simply added the line at the end of the file as you can see, also, if I wanted to change the port that was being used for openvpn, how would I go about that?

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

exit 0

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 192.168.1.2

What OS are you using? If it's one that uses /etc/network/interfaces then add a post-up line to your interface configuration.

Or use iptables-persistent package.

Or fix the rc.local script. (It's exiting before it gets to the iptables command.)

Thanks for your reply, I'm running raspbian, should this have fixed it then?

_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 10.8.0.0/24 -j SNAT --to 192.168.1.2

exit 0

Try it and see.

It seems not, I can't even connect anymore, beforehand, I was able to connect, but just not access the internet or other devices on my network, I also tried to copy and paste all the commands back in, which worked every other time, but not this time.