OpenVPN Modify incoming traffic or payload with custom script

Solution 1:

Your idea is infeasible for several reasons:

1)

As far as I remember there is not a feature in OpenVPN itself to pipe data from a VPN connection into a custom process, before forwarding.

For quick reference: Check out where TCP/IP is being used in the OSI stack.

OpenVPN resides on layer 3 of the OSI stack (Network layer), while TCP packages belongs on layer 4 (Transport layer).

Your question is for this reason alone outside of scope of what OpenVPN wants to achieve.

The only thing you can manipulate with is what happens when a client connects to the server or disconnects.

Those situations can be defined in your server configuration file through the following settings:

# client connected to VPN server
client-connect "/script/client_connect.sh"

# client disconnected from VPN server
client-disconnect "/script/client_disconnect.sh"

All the environmental variables that are available to your custom script is available here:

https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/#scripting-and-environmental-variables

But in essence the only information you can monitor is which client certificate was used to connect to the server and which ip address was assigned to the client and then make some custom logic on server depending on who connects and what to do when they disconnect again.

One typical setup could be to implement a dynamic DNS server side or do some custom routing, like fail-over routing depending on which VPN connection is up.

2)

Referring to this diagram of a IPv4 packet from WikiPedia:

Schematics of a IPv4 packet

In essense what you want todo is to manipulate the data field, depending on source or destination address.

This is also known as the man-in-the-middle attack.

As you have found out it hard todo it by listening on the OpenVPN interface as all content is encryptet. What happens is that IPv4 packet destined for the Internet is encapsulated in another IPv4 packet, which is destined for the OpenVPN server.

The encapsulated IPv4 packet is stored in the data field in the above diagram.

It is the decapsulated packet that is forwarded to the Internet from the VPN server.

However there is a caveat:

I presume the VPN client does not have a public ip address. This means NAT translation is envolved and the source address is rewritten to be that of the VPN server before any host is contacted on the Internet.

Likewise when the host reply back with an answer the we have the destination IPv4 address is the same as the VPN server.

This means that in order to manipulate with the data field we need to keep track of which ports are being used in the network address translation table (aka the NAT).

The ports used is normally dynamic in nature as more than one VPN client can connect to Internet via VPN and NAT and every TCP session (mail, web, ssh whatever) uses a diffrent port.

So if you want manipulate the decrypted TCP packet it has to happen after decryption, but before it is translated in the NAT.

In theory you can intercept the packet using iptables, but it is non-trivial when VPN and NAT resides on the same machine.

Another approach is to attack the encrypted OpenVPN traffic directly, since you control the OpenVPN server means you also control which certificates and private keys are being used on both server and client.

This is doable as a strait-up classic man-in-the-middle attack. I don't know how this is done though. :-)

... but this leads me my last argument:

3)

Most traffic on the Internet is TLS encryptet.

So even after you have decryptet the OpenVPN traffic there is another layer of encryption you have to beat in order to manipulate the content of the data field.

This part is even harder to attack than just attacking the encrypted OpenVPN traffic as you not in control of the encryption keys used for the session.

Even if you tried to decrypt the TLS traffic and reencrypt the content so it looks like for the end user that the encrypted traffic did indeed originate from YouTube or whatever then it would still be futile, since certificate you use to encrypt the https traffic is not trusted by the browsers on the end users computers.

This alone renders your man-in-the-middle attack futile.

Now this is as close to a complete answer to your question.

There are other angles to attack a TCP session, but now we are going it an advanced field that belongs in a forum full of security experts.

That part is WAY beyond my qualifications. :-)