No thanks, I've already figured it out.
After some extensive research I was able to verify the legitimacy of that code myself.
To anyone else who may find themselves in a similar situation, simply make sure that you use --route-noexec or a pull-filter from within your client config to ignore the server pushed routes, don't forget --setenv for the previous hop's gateway and definitely be mindful of including paths for /usr/sbin/ & /usr/bin on Ubuntu >20.4. You can pretty much use any of the currently available cascading scripts on github, but in my opinion loeken's contrib has the most online/forum presence and appears to be one of the cleanest and easiest work with, considering that the majority of other maintainers have simply forked his script. If you have ipv6 disabled, you'll need to remove/comment lines 127 - 129, otherwise ipv6 routes will be erroneously assigned and it exits. As it is, this script produces hops
in series, i.e chained. If you specifically want them to be
nested, you'll have to choose one of the many other options, however this is apparently not advisable from a security standpoint.
.
#!/bin/bash
#
# This script called updown.sh can be used to create a cascading connection to multiple vpn servers
# You basically start a vpn connection to multiple servers and this script will create routes so it will create a
# proxy chain for you
#
#
# Example:
# 1:
# sudo openvpn --config eu.fr1.cdn.internetz.me.ovpn --script-security 2 --route remote_host --persist-tun --up updown.sh --down updown.sh --route-noexec
#
# 2 ( script nr 1 will output this command for you
# sudo openvpn --config eu.fr4.cdn.internetz.me.ovpn --script-security 2 --route remote_host --persist-tun --up updown.sh --down updown.sh --route-noexec --setenv hopid 2 --setenv prevgw 10.9.1.1
#
# 3
# sudo openvpn --config am.us4.cdn.internetz.me.ovpn --script-security 2 --route remote_host --persist-tun --up updown.sh --down updown.sh --route-noexec --setenv hopid 3 --setenv prevgw 10.9
# save the name of this script to a variable ( intended name updown.sh )
script_name=$0
# maximum number of hops
# be careful: number of additional routes per hop: 2^($hopid) + 1
MAX_HOPID=5
# disabling resolveconf cause most users are on systems such as kali
disable_resolvconf=1
# all messages from this script start with ##
# print $1 with prefix to STDOUT
function updown_output {
echo "## updown.sh: $1"
}
# all messages from this script start with ##
# print $1 with prefix to STDERR
function updown_output_error {
echo "## updown.sh: ERROR: $1">&2
}
# check whether $1 is an IPv4 address (exit on error)
# $1: the IP address to check
# $2: the environment variable name for error message
function check_ipv4_regex {
regex_255="([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])" # 0-255
regex_ipv4="^($regex_255.){3}$regex_255$"
if ! [[ $1 =~ $regex_ipv4 ]]
then
updown_output_error "$2 ('$1') is not an IPv4 address"
updown_output "ABORT"
exit 1
fi
}
updown_output "STARTED"
updown_output "hop id: $hopid (default: 1)"
updown_output "gateway of last hop: $prevgw (default: local gateway)"
updown_output "local gateway: $route_net_gateway"
updown_output "VPN: local IP address: $ifconfig_local"
updown_output "VPN: local netmask: $ifconfig_netmask"
updown_output "VPN: local gateway: $route_vpn_gateway"
updown_output "VPN: vpn IP address: $route_network_1"
# if hopid is not set, assume it to be 1
if [[ ${hopid} == "" ]]
then
updown_output "Notice: You didn't set 'hopid'. Assuming this to be the first hop (hopid=1)."
hopid=1
fi
# check whether environment variable hopid is a number
regex_number="^[0-9]+$"
if ! [[ ${hopid} =~ $regex_number ]]
then
updown_output_error "hopid ('$hopid') is not a number!"
updown_output_error "See updown.sh for the usage of this script."
updown_output "ABORT"
exit 1
fi
# check whether hopid <= MAX_HOPID
if [[ ${hopid} -gt ${MAX_HOPID} ]]
then
updown_output_error "Do not use more than $MAX_HOPID hops."
updown_output "ABORT"
exit 1
fi
# check whether all environment variables needed are IPv4 addresses
check_ipv4_regex ${route_vpn_gateway} "route_vpn_gateway"
check_ipv4_regex ${route_network_1} "route_network_1"
vpn_server_ip=${route_network_1}
# make sure we have a valid gateway
# (prevgw is the route_vpn_gateway from the previous hop)
if [[ ${prevgw} == "" ]]
then
if [[ ${hopid} -eq 1 ]]
then
# for the first hop, use the local gateway
updown_output "Notice: You didn't set the previous gateway. The gateway of your local network ('$route_net_gateway') will be used."
prevgw=${route_net_gateway}
else
updown_output_error "You didn't set the previous gateway."
updown_output_error "See updown.sh for the usage of this script."
fi
fi
check_ipv4_regex ${prevgw} "prevgw"
# determine whether to add or del our routes
if [[ "$script_type" == "up" ]]
then
add_del="add"
elif [[ "$script_type" == "down" ]]
then
add_del="delete"
else
updown_output_error "script_type is not 'up' or 'down'!"
updown_output_error "See updown.sh for the usage of this script."
updown_output "ABORT"
exit 1
fi
# add route to (next) vpn server via previous gateway
IP=$(which ip)
route_cmd="$IP route $add_del $vpn_server_ip via $prevgw"
updown_output "executing: '$route_cmd'"
eval ${route_cmd}
# calculate and execute routes
for (( i=0; i < $((2 ** $hopid)); i++ ))
do
net="$(( $i << $((8 - $hopid)) )).0.0.0"
route_cmd="$IP route $add_del $net/$hopid via $route_vpn_gateway"
updown_output "executing: '$route_cmd'"
eval ${route_cmd}
done
# print hint for the next connection (on up)
if [[ "$script_type" == "up" ]]
then
if [[ ${hopid} -le ${MAX_HOPID} ]]
then
next_hop_number=$((hopid+1))
next_gateway=${route_vpn_gateway}
updown_output "HINT: For the next hop, start openvpn with the following options:"
updown_output "HINT: openvpn --config <config.ovpn> --script-security 2 --route remote_host --persist-tun --up $script_name --down $script_name --route-noexec --setenv hopid $next_hop_number --setenv prevgw $next_gateway"
else
updown_output "Notice: Maximum numbers of hops reached. Don't start another connection."
fi
fi
# update DNS settings
if ! [ "$disable_resolvconf" ]
then
resolvconf_cmd="/etc/openvpn/update-resolv-conf"
updown_output "execuding: '$resolvconf_cmd'"
eval ${resolvconf_cmd}
fi
updown_output "FINISHED"
https://github.com/loeken/CascadingOpenvpnConnect
Respectfully, I understand the position you're in, given that you unconditionally and gratuitously offer 24/7 support to any lazy dummy who could probably answer their own question faster and more effectively with a 1 min google search, however in this particular case I believe a subtle hint, that the script is not only perfectly fine, but also the universally accepted method to achieve cascading with OpenVPN, could have been made without this rather aggressive ploy for compensation.
It's an open source issue, raised on an open source platform, received by an open source specialist.
The second you saw this, you already knew that the script was more than adequate. I think in the spirit of open source, it would have been more appropriate to leave a few words, at least indicative of the solution, as you usually do, instead of depicting this as an issue far too advanced for the forums, only to be solved privately and in exchange for a fee.
I am doing this whole project out of the goodness of my heart and because I truly believe information should be free. It is exactly this ideal, that our entire community is predicated upon. This advanced and delicate knowledge of surfing the web unencumbered may not mean much to us, but to people in less progressive countries it is a crucial means to and literal manifestation of freedom.
I would have happily made a donation to your github page or whatever project you are currently working on, for the simple fact that you are obviously extremely knowledgeable and helpful to so many countless people on here.
Just a little disappointed by the way this was handled.