Real openVPN client ip showing on NGINX running on same server

I have openVPN running on a server which is also hosting a NGINX server.

When connecting and running via openVPN it will show the server's ip everywhere just fine, but when connecting to a domain that is running on NGINX on the same server it will show the real external ip of the client that is connected via openVPN.

I would like it to also route the traffic incoming to nginx to be routed via the server and then in a NGINX access log showing like either 127.0.0.1 or 10.x.x.x

I am using the following settings.

local 136.x.x.x   
port 1194
proto tcp
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 local def1 ipv6 bypass-dhcp"
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
verb 3
crl-verify crl.pem

Solution 1:

You can't - at least not with the method you're using.

The problem is that you're playing with the traditional routing tables of operating systems - and they're not designed for this specific scenario.

When OpenVPN connects and is told to redirect 0.0.0.0/0 over the VPN, it has to add a route to reach the VPN server. This route is /32 with next hop the local gateway, the most specific possible route.

A specific route always wins over a less specific route, so all traffic destined for will use this route.

There's broadly speaking two ways to solve this issue:

  1. Provide split horizon DNS, so that users of your VPN gets a RFC1918-IP for the webserver, and thus goes over the tunnel.
  2. Use some sort of policy based routing on the client. On Linux this can be namespaces for instance.