OpenVPN and routing all client traffic through it

OldManBrodie

Ars Legatus Legionis
44,119
Subscriptor
Quick network layout:
10.0.0.1 - Asus router - DHCP set up for 10.0.0.0/21 subnet (10.0.01 - 10.0.7.254).
10.0.1.1 - primary pihole for adblocking
10.0.1.2 - secondary/HA pihole
10.0.1.3 - PiVPN running on an RPi 4 / OpenVPN clients on 10.8.0.0/24

I have several machines I'd like to be able to SSH into remotely via the VPN. However, I'd also like to still have an internet connection available while on the VPN, using my piholes as the DNS servers.

I have the first part of that working fine. While connected to the VPN on my phone, I can access internal devices. However, I cannot browse the internet at all, much less while using my piholes for DNS.

In the past, I think I had somehow used TAP connections to just bridge the VPN and the home network, and it worked fine. Now, however, OpenVPN 3 says it doesn't support TAP anymore? More importantly, I can't use TAP on my non-rooted Pixel. I've been reading up a ton on how I need to set up routes to accomplish what I am describing. I've followed several guides, and I just can't seem to get it working. I understand, conceptually, how the routing is supposed to work, but I can't figure out to implement it.

I'm at my wit's end. I've been trying to learn for Linux stuff for running a home lab box with docker, but the networking side of things is still confusing to me.

Here are the pertinent config files.

OpenVPN server.conf:

Code:
dev tun
proto udp
port 1194
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/pivpn.crt
key /etc/openvpn/easy-rsa/pki/private/pivpn.key
dh none
ecdh-curve prime256v1
topology subnet
server 10.8.0.0 255.255.255.0                   # It should add clients to the 10.8.x.x range
push "dhcp-option DNS 10.0.1.1"            # PiHole0
push "dhcp-option DNS 10.0.1.2"            # PiHole1
push "route 10.0.0.1 255.255.248.0"        # Create route to home network gateway?
push "redirect-gateway def1"
client-to-client
client-config-dir /etc/openvpn/ccd
keepalive 15 120
remote-cert-tls client
tls-version-min 1.2
tls-crypt /etc/openvpn/easy-rsa/pki/ta.key
cipher AES-256-CBC
auth SHA256
user openvpn
group openvpn
persist-key
persist-tun
crl-verify /etc/openvpn/crl.pem
status /var/log/openvpn-status.log 20
status-version 3
syslog
verb 3

Client config:
Code:
client
dev tun
proto udp
remote vpn.mydomain.com 1194        # This is a DDNS address
resolv-retry infinite
nobind
remote-cert-tls server
tls-version-min 1.2
verify-x509-name pivpn name
cipher AES-256-CBC
auth SHA256
auth-nocache
verb 3

## Cert info snipped for privacy/brevity

And then on my router, I have this static route set up:
Code:
Network/Host IP    Netmask            Gateway        Interface
10.8.0.0            255.255.255.0    10.0.1.3    LAN
 

Burn24

Smack-Fu Master, in training
53
First off, I sympathise. Linux networking is complex but usually makes sense, and in my experience adding both docker and openvpn makes it a lot worse, and make a lot less sense. I have special scorn for docker, it is a poorly-behaved networking nightmare.

I humbly suggest looking into setting up wireguard instead of openvpn. People 'liked' and 'used' openvpn because it was the only free choice for a long time that was easier than ipsec, but now we have wireguard. It is a lot easier to setup. I currently use it to cheap-vpn into AWS private hosted services, and it's been working well on Fedora and android.

At this point I would be using tcpdump listening on various interfaces to see what packets are actually doing, and if they're going where you expect them to go. if you ping from a vpn client to the asus IP, and tcpdump on the interface on the openvpn server that the packets should be going out on, towards the asus, you should be able to see if your openvpn setup is correctly sending the ping, and if the asus is responding as expected. It should help bisect the problem somewhat.

Don't be intimidated by tcpdump. If your openvpn internal interface is eg enp5s0, asking it to show icmp on that interface is probably as simple as running (as root) tcpdump -i enp5s0 icmp . It does a lot more, and can be really noisy, but it'd be someting really useful to learn.

At first I thought your asus was missing the return path for the VPN network, but it sounds like you got that.
 

OldManBrodie

Ars Legatus Legionis
44,119
Subscriptor
Right now, I'm only using this RPi for a VPN server, so I don't have to mess around with the docker AND VPN together.

I had tried WireGuard, too, but I ran into the same issue: I could access devices on the network, but I couldn't access the internet from the client. I switched back to OpenVPN because I wanted to try bridging. I guess I can go back to WG, now that I know I'm going to have to dick around with routing in either case. With the routing, though, I'm still kind of unclear with what I'm setting up.... am setting up a route on the server to know how to get the home network, and on the router to tell packets how to get back to the VPN network? I think I need an ELI5 for routing...

Regarding tcpdump, is that tool specific to TCP packets? Because I was running OpenVPN as UDP. I think I had WG set up with UDP, too.
 
this is extraneous, though it should not cause issues.
Code:
push "route 10.0.0.1 255.255.248.0"        # Create route to home network gateway?

i can only imagine that your vpn box has the .1 IP assigned to the tun0 interface, but double check that. seems like it would be 10.8.0.1/24. Since you can browse your local network, it seems the basic connectivity is working and basic routing is in place. why you cant get to the internet seems like there is something missing. tcpdump will look at UDP and TCP packets, so you should be able to find the traffic. it does not seem the UDP/1194 traffic is your problem, so you would want to look at DNS, HTTP & HTTPS. something like tcpdump -nnt -s0 -i tap0 port 53 or port 80 or port 443.

you might also try tcpdump -nnt -s0 -i eth0 port 53 or port 80 or port 443 adjusting <eth0> to be whatever wired interface is on the PiVPN. you can add -w /tmp/ovpn.pcap option to either command and have the capture written out to a file. then you copy that file to a machine that has wireshark installed. that might help you look at the traffic easier.

in either case, you are looking for the traffic from/to a host on the 10.8.0.0/24 network. where you dont see the traffic is the leg of the path that needs to be investigated. by the by, have you turned on IP forwarding in the kernel? this would go in /etc/sysctl.conf or wherever you distro puts these kernel options.
Code:
# Controls IP packet forwarding
net.ipv4.ip_forward = 1

note, i am running openvpn 2.6.9 on fedora, so you running version 3.x may have differences. my server TUN config:
Code:
# TUN Config on UDP/1194
mode server
tls-server
local sslvpn-tun.bpk2.com
management 127.0.0.1 7506
port 1194
proto udp
dev tun
script-security 2
ca ca.crt
cert sslvpn.crt
key sslvpn.key
tls-crypt tls-auth.key
dh dh.pem
cipher AES-256-GCM
auth sha256
server 192.168.185.0 255.255.255.0
topology subnet
push "redirect-gateway def1"
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 192.168.248.254"
push "dhcp-option WINS 192.168.253.3"
passtos
keepalive 10 120
fast-io
user nobody
group nobody
ping-timer-rem
persist-tun
persist-key
verb 4
mute 20
plugin /usr/lib64/openvpn/plugins/openvpn-auth-ldap.so "/etc/openvpn/auth/ldap.conf"
my client TUN config:
Code:
client
dev tun
proto udp
remote sslvpn-tun.bpk2.com
float
port 1194
resolv-retry infinite
keepalive 10 120
ping-timer-rem
persist-tun
persist-key
ca ca.crt
cert client.crt
key client.key
tls-crypt tls-auth.key
#tls-auth-v2 v2crypt-client.key
remote-certs-tls server
cipher AES-256-CBC
auth-nocache
pull
verb 4
mute 20
explicit-exit-notify 2
it seems the heavy lifting is done. some small tweak somewhere sounds like the missing piece.
 
thinking about this a bit more, i think the route you push, push "route 10.0.0.1 255.255.248.0" # Create route to home network gateway? is the problem. you are adding a static route that says the entire /21 network should be routed via 10.0.0.1. the client should be routing everything that goes across the VPN via 10.8.0.1. the server will handle getting things from the VPN subnet (10.8.0.0/24) to the rest of the network and out to the internet and back, because it has route(s) that manage all of that.

i would try removing the push route statement and restart the service. that may be the piece that gets things working.
 

teubbist

Ars Scholae Palatinae
823
I have the first part of that working fine. While connected to the VPN on my phone, I can access internal devices. However, I cannot browse the internet at all, much less while using my piholes for DNS.

If you want LAN access, but have Internet follow its normal path out(i.e. not via the VPN), then remove this from the server config and restart:

Code:
push "redirect-gateway def1"

As that tells the VPN client to send all traffic via the VPN.

If you actually want Internet access via the VPN, then you'll need to enable forwarding on the VPN server and quite possibly NAT as well, depending how what your internet facing router is doing/capable of.
 

Paladin

Ars Legatus Legionis
32,552
Subscriptor
Aside from the VPN server routing issues, make sure that your Asus router/firewall will do network address translation for the source IPs your VPN clients are assigned. Otherwise the traffic will hit the Asus and be dropped because it doesn't know what to do with it to get it out to the internet. Or as teubbist mentions, the VPN server will have to do NAT for it.

Theoretically, your router might be able to do all the VPN features without having to run a separate server. Asus routers can often run the Merlin firmware which can do OpenVPN and Wireguard natively, I think. Pretty easy setup.
 

OldManBrodie

Ars Legatus Legionis
44,119
Subscriptor
Asus routers can often run the Merlin firmware which can do OpenVPN and Wireguard natively, I think. Pretty easy setup.
Man, I didn't even think of that. I remembered that they have a VPN client, but I didn't think to check for a VPN server

In any case, in a fit of rage last night, I nuked the card and started fresh, this time with a straight-up Ubuntu server 22.04 image. I decided to try out wg-easy one more time, and it worked! Previous attempts at using this container were done on my lab box, which has a bunch of other docker stuff running on it. I think I might have screwed up something with the networking on that one. So putting it alone on a separate system might have solved that particular issue.

In any case, thank you for trying to help me. Hopefully this will just run automatically now.
 
  • Like
Reactions: Paladin

Paladin

Ars Legatus Legionis
32,552
Subscriptor
Disconnect vs disable? Like... uh, I am not sure how you do the one vs. the other. Turn off the wifi on a phone completely (airplane mode sort of) vs. having it forget the wifi network password or turning off your wifi router? That is a weird one. They should be effectively the same unless it is not really getting off the wifi in one case or the other.