Know-How: OpenVPN - Double VPN / Cascading

PP Daniel

Staff member
NOTE: This information is obsolete. Cascading has been built directly into our Windows and MacOS client and can be activated in the GUI. To use cascaded connections with OpenVPN on Linux, we provide a Tutorial here.

We have been asked a few times about cascading VPN connections (connecting to the internet via more than one VPN server). We have implemented this in our servers now; once it will function reliably, we will add according options in the client software. Feel free to test the VPN cascading already.

Technically it works like this: Before connecting to VPN you have the following default route

0.0.0.0/0 -->

Once you connect OpenVPN recognizes this default route and will change it accordingly:

-->

which ensures that the connection to the VPN server will always go through your router. Now OpenVPN adds two more routes:

0.0.0.0/1 -->
128.0.0.1/1 -->

These are the new default routes because they are more specific than the 0.0.0.0/0 route and thus all traffic will go via .

This will not work if you initiate a second tunnel because the second VPN connection will find the 0.0.0.0/0 default route instead of the new default routes. Furthermore, OpenVPN adds the 0.0.0.0/1 and 128.0.0.1/1 routes without metric which means that the first found route will be used. This is always the route created by the first hop, any other hops are being ignored.

What you need to do is not let OpenVPN handle the routes but set them with a IP up/down script.

This is how to achieve it in Windows:

Startmenu -> TAP-Windows -> Utilities -> Add a new TAP virtual ethernet adapter

Do this twice with administrator priviliges to add two more TAP adapters.

Next put the following content in a file calles "updown.bat" and copy it into the OpenVPN configuration folder:
Code:
REM UP/DOWN Script for cascading VPN
REM be aware that you must add the hop number when starting openvpn!
REM start using openvpn.exe --config config.ovpn --script-security 2 --route remote_host hopnumber_0-4 --up updown.bat --down updown.bat --route-noexec

setlocal enableextensions enabledelayedexpansion

REM Dirty hack to get this values in here
set vpn_server_ip=%route_network_1%
set hop_id_tmp=%route_netmask_1%
for /f "tokens=4 delims=." %%G IN ("!hop_id_tmp!") DO set hop_id_tmp1=%%G
for /f "tokens=1 delims= " %%G IN ("!hop_id_tmp1!") DO set hop_id_tmp2=%%G
for /f "tokens=1 delims=    " %%G IN ("!hop_id_tmp2!") DO set hop_id=%%G


IF !script_type! == up GOTO UP
    REM IP DOWN
    if !hop_id! == 1 GOTO DOWN_1
    if !hop_id! == 2 GOTO DOWN_2
    if !hop_id! == 3 GOTO DOWN_3
    if !hop_id! == 4 GOTO DOWN_4

    :DOWN_1
        route delete 0.0.0.0 mask 128.0.0.0
        route delete 128.0.0.0 mask 128.0.0.0
     
    :DOWN_2
        for /l %%x in (0, 64, 223) do (
            route delete %%x.0.0.0 mask 192.0.0.0
        )
     
    :DOWN_3
        for /l %%x in (0, 32, 223) do (
            route delete %%x.0.0.0 mask 224.0.0.0
        )
     
    :DOWN_4
        for /l %%x in (0, 16, 223) do (
            route delete %%x.0.0.0 mask 240.0.0.0
        )
        GOTO DOWN_DEFAULT

    :DOWN_DEFAULT
        route delete %vpn_server_ip% mask 255.255.255.255
        route delete %ifconfig_local% mask 255.255.255.255     
 
    GOTO DONE
 
 
 
:UP
    REM IP UP
    if !hop_id! == 1 GOTO UP_1
    if !hop_id! == 2 GOTO UP_2
    if !hop_id! == 3 GOTO UP_3
    if !hop_id! == 4 GOTO UP_4
    GOTO DONE
 
    :UP_1
        call:FINDGATEWAY 0.0.0.0
        call:UP_DEFAULT
        route add 0.0.0.0 mask 128.0.0.0 %ifconfig_remote%
        route add 128.0.0.0 mask 128.0.0.0 %ifconfig_remote%
        GOTO DONE     
    :UP_2
        call:FINDGATEWAY 128.0.0.0
        call:UP_DEFAULT
        for /l %%x in (0, 64, 223) do (
            route add %%x.0.0.0 mask 192.0.0.0 %ifconfig_remote%
        )
        GOTO DONE
     
    :UP_3
        call:FINDGATEWAY 192.0.0.0
        call:UP_DEFAULT
        for /l %%x in (0, 32, 223) do (
            route add %%x.0.0.0 mask 224.0.0.0 %ifconfig_remote%
        )
        GOTO DONE
     
    :UP_4 
        call:FINDGATEWAY 224.0.0.0
        call:UP_DEFAULT
        for /l %%x in (0, 16, 223) do (
            route add %%x.0.0.0 mask 240.0.0.0 %ifconfig_remote%
        ) 
        GOTO DONE

    :UP_DEFAULT
        route add %vpn_server_ip% mask 255.255.255.255 %default_gw%
        route add %ifconfig_local% mask 255.255.255.255 %ifconfig_remote%
        goto :eof
     
    GOTO DONE
  
:DONE


:FINDGATEWAY
    set findmask=%~1
    route print -4 | findstr "0.0.0.0"  > hops.file
    set /a linecnt=0
    for /f "delims=" %%i in (hops.file) do ( 
        for /f "tokens=1,2,3,4 delims= " %%a in ("%%i") do (
            set ip=%%a
            set netmask=%%b
            set gateway=%%c
            set network=%%d
        )
        if !ip! == 0.0.0.0 (
            if !netmask! == !findmask! (
                set str=empty
                for /f "delims=" %%a in ('echo !network! ^|findstr -r .*\..*\..*\..*') do @set str=%%a
                if NOT !str! == empty (
                    set default_gw=!gateway!
                    goto :eof
                )
            )
        )
    )
  goto :eof


endlocal
Now you can start OpenVPN upto three times if you like:

openvpn.exe --config Amsterdam2.ovpn --script-security 2 --route remote_host 1 --up updown.bat --down updown.bat --route-noexec --route-nopull
openvpn.exe --config Gigabit-Lu.ovpn --script-security 2 --route remote_host 2 --up updown.bat --down updown.bat --route-noexec --route-nopull
openvpn.exe --config Gigabit-NL.ovpn --script-security 2 --route remote_host 3 --up updown.bat --down updown.bat --route-noexec --route-nopull

Please only play around with this if you know what you are doing as this can mess up your routing table and lock you out of the internet. If anything goes wrong:

Startmenu -> TAP-Windows -> Utilities -> Delete all TAP virtual ethernet adapters

to delete all TAP adapters, then:

Startmenu -> TAP-Windows -> Utilities -> "Add a new TAP virtual ethernet adapter"

To add an adapter again.
 
I have some question about "vpn cascading".

1) Does "cascading" lead to chained or nested encryption (nested means a little like in Tor).
With the config: My PC => VPN1=> VPN2, chained encryption that my outgoing traffic is encrypted by VPN1 until it reaches VPN1 server, then decrypted on VPN1 servers, then encrypted by VPN2 until it reaches VPN2 server.
In this case, someone sniffing VPN1 can read my traffic in plain text.

Nested encryption means that my outgoing traffic is first VPN1 AND VPN2 encrypted until it reaches VPN1 server, where it is VPN1-decrypted but remains VPN2 encrypted until it reaches VPN2 server, where it is VPN2-decrypted.
In this case, someone sniffing VPN1 server can't read my traffic; because he sees only VPN2-encrypted datas. So, what means "cascading VPN" exactly ?


2) Is there a simple way eg with Openvpn client software, to "cascade" a PP OpenVPN with an OpenVPN of an other provider ? It is very simple to do with (PPTP or L2TP) + Openvpn: You first start your provider X PPTP or L2TP VPN , then start PP Openvpn, that's all. And in that case cascading means "nested encryption".
But is it possible to do the same with X-Openvpn X and PP-Openvpn, in a simple way (without VM!) ?
 
Hi,

if you cascade multiple OpenVPN connections you end up with a nested encryption type like this: You -> VPN1 -> VPN2 -> VPNn -> Internet.

Surely you may cascade OpenVPN servers of different VPN providers, you'll have to adjust the example code in the first post accordingly - so I'm not sure if this counts as a "simple" solution, but there is no VM needed to cascade OpenVPN connections.
 
Just to update this post to reflect recent additional features in our software:

The current stable version of the Perfect Privacy VPN Manager for Windows supports OpenVPN cascading over up to four hops (additional cascading is possible via proxy server or ssh tunnels). As always, you can get the latest version of our client software in the member area at https://www.perfect-privacy.com/
 
Back
Top