How to use a Linux OpenVPN client host as gateyway for a Windows OpenVPN client host?

I have an environment where I have a OpenVPN server (Linux) and a few OpenVPN clients (both Windows and Linux). All those hosts (server & clients) are connected to the Internet, they are not connected to each other in LAN.

The idea is to have the windows client using the linux client as gateway (and not the OpenVPN server). I want to achieve this by pushing "route-gateway 10.8.0.200" and "redirect-gateway def1" to the windows client. Once SNAT (or MASQUERADE) is enabled on the Linux gateway (10.8.0.200), and the sysctl ip forwarding flag is set to true, it should be able to act as gateway, right?

But I fail to do this. I'll explain in short my setup, and show where it goes wrong.

  • 10.8.0.1: OpenVPN Server (Linux)
  • 10.8.0.200: Gateway, OpenVPN Client (Linux)
  • 10.8.0.2: OpenVPN Client (Windows)
  • Networkmask: 255.255.255.0

Network Layout:

                                       ############                                      
           +---------------------------+ INTERNET +--------------------------+           
           |                           #####+######                          |           
           |                                |                        +-------+-------+   
           |                                |                        |   9.10.11.12  |   
           |                                |                       ++---------------++  
           |                                |                       | DSL Modem Router|  
           |                                |                       +--------+--------+  
           |                                |                                |           
       +---+---+                        +---+---+                        +---+---+       
       |  eth0 |                        |  eth0 |                        |  LAN  |       
   +---+-------+---+                +---+-------+---+                +---+-------+---+   
   |    5.6.7.8    |                |    1.2.3.4    |                |   10.0.2.15   |   
+--+---------------+--+          +--+---------------+--+          +--+---------------+--+
|        Linux        |          |        Linux        |          |       Windows       |
|       OpenVPN       |          |       OpenVPN       |          |       OpenVPN       |
|        Client       |          |        Server       |          |        Client       |
+--+---------------+--+          +--+---------------+--+          +--+---------------+--+
   |   10.8.0.200  |                |    10.8.0.1   |                |    10.8.0.2   |   
   +---+-------+---+                +---+-------+---+                +---+-------+---+   
       |  tun1 |                        |  tun0 |                        |tun/tap|       
       +---+---+                        +---+---+                        +---+---+       
           |                                |                                |           
           +--------------------------------+--------------------------------+           

Network configuration:

10.8.0.1 routes:

[email protected]:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         1.2.3.1         0.0.0.0         UG    0      0        0 eth0
10.8.0.0        *               255.255.255.0   U     0      0        0 tun0
1.2.3.0         *               255.255.254.0   U     0      0        0 eth0

10.8.0.200 routes:

[email protected]:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         5.6.7.1         0.0.0.0         UG    0      0        0 eth0
10.8.0.0        *               255.255.255.0   U     0      0        0 tun1
5.6.7.0         *               255.255.254.0   U     0      0        0 eth0

10.8.0.2 routes:

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0         10.0.2.2        10.0.2.15    266
          0.0.0.0        128.0.0.0       10.8.0.200         10.8.0.2     20
         10.0.2.0    255.255.255.0         On-link         10.0.2.15    266
        10.0.2.15  255.255.255.255         On-link         10.0.2.15    266
       10.0.2.255  255.255.255.255         On-link         10.0.2.15    266
         10.8.0.0    255.255.255.0         On-link          10.8.0.2    276
         10.8.0.2  255.255.255.255         On-link          10.8.0.2    276
       10.8.0.255  255.255.255.255         On-link          10.8.0.2    276
   107.191.51.248  255.255.255.255         10.0.2.2        10.0.2.15     10
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
        128.0.0.0        128.0.0.0       10.8.0.200         10.8.0.2     20
        224.0.0.0        240.0.0.0         On-link         127.0.0.1    306
        224.0.0.0        240.0.0.0         On-link         10.0.2.15    266
        224.0.0.0        240.0.0.0         On-link          10.8.0.2    276
  255.255.255.255  255.255.255.255         On-link         127.0.0.1    306
  255.255.255.255  255.255.255.255         On-link         10.0.2.15    266
  255.255.255.255  255.255.255.255         On-link          10.8.0.2    276
===========================================================================

OpenVPN configurations:

10.8.0.1 (OpenVPN Server) configuration:

/etc/openvpn/server.conf:

mode server
tls-server
topology subnet
push "topology subnet"

dev tun0
local 1.2.3.4
port 1194
proto udp

client-to-client
max-clients 200

ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
tls-auth ta.key 0

ifconfig 10.8.0.1 255.255.255.0
ifconfig-pool 10.8.0.2 10.8.0.199 255.255.255.0
client-config-dir /etc/openvpn/clients

keepalive 10 60

comp-lzo yes
push "comp-lzo yes"

user nobody
group nogroup

persist-key
persist-tun

status status.log
verb 3
mute 20

/etc/openvpn/clients/linclient:

ifconfig-push 10.8.0.200 255.255.255.0

/etc/openvpn/clients/winclient:

push "route-gateway 10.8.0.200"
push "redirect-gateway def1"

10.8.0.200 (OpenVPN Client) configuration:

/etc/openvpn/linclient.conf:

remote 1.2.3.4 1194
client

dev tun1

ca ca.crt
cert linclient.crt
key linclient.key
tls-auth ta.key 1

remote-cert-tls server

comp-lzo

user nobody
group nogroup

persist-key
persist-tun

status status.log
verb 3
mute 20

10.8.0.2 (OpenVPN Client) configuration:

C:\Program Files\OpenVPN\config\winclient\winclient.ovpn:

remote 1.2.3.4 1194
client

dev tun

ca ca.crt
cert winclient.crt
key winclient.key
tls-auth ta.key 1

remote-cert-tls server

comp-lzo

user nobody
group nogroup

persist-key
persist-tun

status status.log
verb 3
mute 20

When I do pings from Windows client to the OpenVPN Server (10.8.0.1):

In windows:

C:\Windows\system32>ping 10.8.0.1

Pinging 10.8.0.1 with 32 bytes of data:
Reply from 10.8.0.1: bytes=32 time=119ms TTL=64
Reply from 10.8.0.1: bytes=32 time=120ms TTL=64
Reply from 10.8.0.1: bytes=32 time=120ms TTL=64
Reply from 10.8.0.1: bytes=32 time=119ms TTL=64

Ping statistics for 10.8.0.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 119ms, Maximum = 120ms, Average = 119ms

On the OpenVPN Server (10.8.0.1):

[email protected]:/# tcpdump -i tun0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
16:46:12.316295 IP 10.8.0.2 > 10.8.0.1: ICMP echo request, id 1, seq 3930, length 40
16:46:12.316316 IP 10.8.0.1 > 10.8.0.2: ICMP echo reply, id 1, seq 3930, length 40
16:46:13.333982 IP 10.8.0.2 > 10.8.0.1: ICMP echo request, id 1, seq 3931, length 40
16:46:13.333994 IP 10.8.0.1 > 10.8.0.2: ICMP echo reply, id 1, seq 3931, length 40
16:46:14.344666 IP 10.8.0.2 > 10.8.0.1: ICMP echo request, id 1, seq 3932, length 40
16:46:14.344678 IP 10.8.0.1 > 10.8.0.2: ICMP echo reply, id 1, seq 3932, length 40
16:46:15.356811 IP 10.8.0.2 > 10.8.0.1: ICMP echo request, id 1, seq 3933, length 40
16:46:15.356824 IP 10.8.0.1 > 10.8.0.2: ICMP echo reply, id 1, seq 3933, length 40

When I do pings from Windows client to the OpenVPN Client, the 'gateway' (10.8.0.200):

In windows:

C:\Windows\system32>ping 10.8.0.200

Pinging 10.8.0.200 with 32 bytes of data:
Reply from 10.8.0.200: bytes=32 time=226ms TTL=64
Reply from 10.8.0.200: bytes=32 time=226ms TTL=64
Reply from 10.8.0.200: bytes=32 time=225ms TTL=64
Reply from 10.8.0.200: bytes=32 time=225ms TTL=64

Ping statistics for 10.8.0.200:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 225ms, Maximum = 226ms, Average = 225ms

On the OpenVPN Client, the 'gateway' (10.8.0.200):

[email protected]:~# tcpdump -i tun1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun1, link-type RAW (Raw IP), capture size 65535 bytes
18:48:13.694836 IP 10.8.0.2 > 10.8.0.200: ICMP echo request, id 1, seq 3934, length 40
18:48:13.694862 IP 10.8.0.200 > 10.8.0.2: ICMP echo reply, id 1, seq 3934, length 40
18:48:14.706081 IP 10.8.0.2 > 10.8.0.200: ICMP echo request, id 1, seq 3935, length 40
18:48:14.706093 IP 10.8.0.200 > 10.8.0.2: ICMP echo reply, id 1, seq 3935, length 40
18:48:15.722542 IP 10.8.0.2 > 10.8.0.200: ICMP echo request, id 1, seq 3936, length 40
18:48:15.722555 IP 10.8.0.200 > 10.8.0.2: ICMP echo reply, id 1, seq 3936, length 40
18:48:16.732037 IP 10.8.0.2 > 10.8.0.200: ICMP echo request, id 1, seq 3937, length 40
18:48:16.732049 IP 10.8.0.200 > 10.8.0.2: ICMP echo reply, id 1, seq 3937, length 40

When I do pings from Windows client to the Internet (8.8.8.8):

In windows:

C:\Windows\system32>ping 8.8.8.8

Pinging 8.8.8.8 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 8.8.8.8:
    Packets: Sent = 3, Received = 0, Lost = 3 (100% loss),
Control-C
^C

On the OpenVPN Server (10.8.0.1):

[email protected]:/# tcpdump -i tun0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
16:49:55.077094 IP 10.8.0.2 > google-public-dns-a.google.com: ICMP echo request, id 1, seq 3938, length 40
16:49:59.844689 IP 10.8.0.2 > google-public-dns-a.google.com: ICMP echo request, id 1, seq 3939, length 40
16:50:04.896020 IP 10.8.0.2 > google-public-dns-a.google.com: ICMP echo request, id 1, seq 3940, length 40
16:50:09.938695 IP 10.8.0.2 > google-public-dns-a.google.com: ICMP echo request, id 1, seq 3941, length 40

On the OpenVPN Client, the 'gateway' (10.8.0.200):

[email protected]:~# tcpdump -i tun1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun1, link-type RAW (Raw IP), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

More settings on 10.8.0.200:

Ip forward:

[email protected]:~# cat /proc/sys/net/ipv4/ip_forward
1

*filter iptables:

[email protected]:~# iptables -L -n -v
Chain INPUT (policy ACCEPT 1752 packets, 142K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 1496 packets, 184K bytes)
 pkts bytes target     prot opt in     out     source               destination

*nat iptables:

[email protected]:~# iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 7 packets, 1603 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0

And lastly, a tracert on windows:

C:\Windows\system32>tracert 10.8.0.1

Tracing route to 10.8.0.1 over a maximum of 30 hops

  1   119 ms   119 ms   120 ms  10.8.0.1

Trace complete.

C:\Windows\system32>tracert 10.8.0.200

Tracing route to 10.8.0.200 over a maximum of 30 hops

  1   226 ms   226 ms   225 ms  10.8.0.200

Trace complete.

C:\Windows\system32>tracert 8.8.8.8

Tracing route to 8.8.8.8 over a maximum of 30 hops

  1   119 ms   119 ms   119 ms  10.8.0.1
  2     *        *        *     Request timed out.
  3     *        *        *     Request timed out.
  4  ^C

My question:

How do I use the Linux OpenVPN client host as gateway for my Windows OpenVPN client host?


Solution 1:

I don't think you can do this easily with tun interfaces.

Using another computer as your gateway works by sending it frames addressed to it in the layer below IP, with these frames containing IP packets addressed to some other destination. The router ("gateway") will then know that it has to forward the IP packets to the real destination.

With tun, there is no layer below IP. There is no way to choose a specific member of a tun-based subnet to receive your IP packet that is not addressed to it. What I think happens is that your OpenVPN server simply doesn't forward the IP packets addressed to 8.8.8.8 to the Linux client, because why should it? It doesn't know that client is special.

It might be possible to do what you want using OpenVPN's "iroute" directive creatively, but I think you'd be better off with one of the following solutions:

  1. Switch from tun to tap everywhere.
  2. Establish a sub-tunnel from 10.8.0.2 to 10.8.0.200 using a separate OpenVPN session (i.e. a tunnel in a tunnel), and set the default route to point through that.