Score:0

OpenVPN - Problems routing between clients in different subnets

us flag

I've been searching for many hours to try and solve a problem I am facing, but with no luck.

I have an OpenVPN (CentOS 7) setup consisting of a VPN server and clients, some of which are in different subnets with access controlled using iptables. A Windows server also connects to the OpenVPN server, and users need to connect over their tunnels to it. I have tried various combinations of config file options but I am unable to add the correct client routes to get clients talking to each other. The client-to-client option is specified in server.conf.

The IP addressing is like so:

Users - 10.8.0.0/24

Admins - 10.8.1.0/24 (specified in ccd files)

Windows Server - 10.8.2.1 (specified in its ccd file)

The OpenVPN config is like so:

port 2000
proto tcp
dev tun0
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
client-to-client
server 10.8.0.0 255.255.0.0
route 10.8.1.0 255.255.255.0
route 10.8.2.0 255.255.255.0
ifconfig-pool-persist ipp.txt
#push "dhcp-option DNS 1.1.1.1"
#push "dhcp-option DNS 8.8.8.8"
#push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
tls-crypt tls-crypt.key
crl-verify crl.pem
ca ca.crt
cert server.crt
key server.key
auth SHA256
cipher AES-128-GCM
ncp-ciphers AES-128-GCM
tls-server
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
client-config-dir /etc/openvpn/ccd
status /var/log/openvpn/status.log
log-append /var/log/openvpn/openvpn.log
verb 3

The ccd file for the remote Windows server is like this:

ifconfig-push 10.8.2.1 255.255.255.0
iroute 10.8.2.1 255.255.255.255
push "route 10.8.0.0 255.255.255.0"
push "route 10.8.1.0 255.255.255.0"

The client file for the remote Windows server looks like this:

client
proto tcp-client
remote X.X.X.X 2000
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3

The frustrating thing is that I had this working previously but for reasons not worth going into, the config was lost.

I have found on the Windows server mentioned above, if I manually add a route to 10.8.0.0/24 via 10.8.2.2 once the client connects, that it can ping 10.8.0.1 and other clients can connect to it. However if I do not add the route, it attempts to send traffic to 10.8.0.0 out of it's default gateway, which obviously fails.

At the moment I have worked around this by using a persistent static route, but I would dearly love to understand what I am doing wrong here.

I have also observed the same behaviour for the Admin users on 10.8.1.0/24, but since they need to access lots of subnets on lots of different machines, the persistent static routes are not an option (also this feels super hacky which I want to avoid).

EDIT adding the routing table for further context

This is the routing table from the Windows server:

===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0    12.22.122.193    12.22.122.202    271
         10.8.0.0    255.255.255.0         10.8.0.1         10.8.2.1    257
         10.8.0.0    255.255.255.0         10.8.2.2         10.8.2.1      2
         10.8.1.0    255.255.255.0         10.8.0.1         10.8.2.1    257
         10.8.2.0    255.255.255.0         On-link          10.8.2.1    257
         10.8.2.1  255.255.255.255         On-link          10.8.2.1    257
       10.8.2.255  255.255.255.255         On-link          10.8.2.1    257
    12.22.122.192  255.255.255.192         On-link     12.22.122.202    271
    12.22.122.202  255.255.255.255         On-link     12.22.122.202    271
    12.22.122.255  255.255.255.255         On-link     12.22.122.202    271
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    331
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    331
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    331
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    331
        224.0.0.0        240.0.0.0         On-link          10.8.2.1    257
        224.0.0.0        240.0.0.0         On-link     12.22.122.202    271
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    331
  255.255.255.255  255.255.255.255         On-link          10.8.2.1    257
  255.255.255.255  255.255.255.255         On-link     12.22.122.202    271
===========================================================================
Persistent Routes:
  Network Address          Netmask  Gateway Address  Metric
          0.0.0.0          0.0.0.0    12.22.122.193  Default
         10.8.0.0    255.255.255.0         10.8.2.2       1
===========================================================================

Note there is a persistent route to 10.8.2.0/24 via 10.8.2.2, this works, and was added statically by me. You can see a route to 10.8.1.0/24 via 10.8.2.1 - this was added by the client, and is unreachable, the traffic tries to go via the default gateway.

One other thing of note, it seems that the server logs the following each time one of the non-standard (e.g. outside of 10.8.0.0/24) users connect:

admin1/1.2.6.4:38593 MULTI ERROR: primary virtual IP for admin1/1.2.6.4:38593 (10.8.1.1) violates tunnel network/netmask constraint (10.8.0.0/255.255.255.0)

I can't find much on this in the documentation or online.

Tom Yan avatar
in flag
So have you checked how the routes look like in `route print` / `ip route` (or whether they have been added at all by the OpenVPN program on the clients; also have you checked the client logs)?
us flag
I added some more detail, hopefully this gives a little more insight
Tom Yan avatar
in flag
I suppose you can either add the pushed IP to the pushed `route` as gateway address in each ccd file, or, perhaps even more sensical, just use `/16` (or maybe `/22` or so, depending on your need) as the netmask in the `server` and `ifconfig-push` options, which should eliminate the the need of the `route` option on the server or pushed to the clients. (Note that you are using `/16` in `server`, which means without a CCD or so, "other" clients may not necessarily be getting a 10.8.0.X IP anyway.)
Tom Yan avatar
in flag
There's also the `route-gateway` option which should save the need of specifying the gateway address in every pushed route in a CCD file.
us flag
Thanks these sound like good approaches, can you please give me an example? Say with a client on 10.8.1.1 - what options above would you employ?
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.