View previous topic :: View next topic |
Author |
Message |
krumpf Apprentice
Joined: 15 Jul 2018 Posts: 190
|
Posted: Wed Nov 20, 2024 3:53 pm Post subject: Wireguard interface questions |
|
|
Hi. For a while, my goal was to use my VPN connection only for torrenting while using my real IP for net browsing. Recently, I've found this script that creates and setups a wgclient network interface without setting it as default gateway for net access.
Script source
Code: | #!/bin/bash
CFG_FILE=$1
ALIAS_IDX=$2
IP_TABLE=4421${ALIAS_IDX}
# address aliases if needed
# not used unless ALIAS_IDX is set
ALIAS_V4=10.44.${ALIAS_IDX}.2
ALIAS_V6=fc00:44:${ALIAS_IDX}::2
DEV=wgclient${ALIAS_IDX}
NFT_TABLE=wgclient${ALIAS_IDX}
echo === using $CFG_FILE
echo === creating wireguard device ...
sudo ip link add $DEV type wireguard
echo === setting VPN addresses for device ...
#cat $CFG_FILE | grep "^ *Address *= *"
ADDRESSES=`cat $CFG_FILE | grep "^ *Address *= *" | sed -e "s@ @@" | sed -e "s@Address=@@" | sed -e "s@,@ @"`
echo ADDRESSES=$ADDRESSES
for a in $ADDRESSES; do
proto=4
if echo $a | grep -q ":"; then
proto=6;
fi
if [ $proto == 4 ]; then
LOCAL_V4_PREF=$a
LOCAL_V4=`echo $LOCAL_V4_PREF | sed -e "s@/[0-9]*@@"`
echo === LOCAL_V4=$LOCAL_V4
echo === adding IPv4 address $LOCAL_V4_PREF ...
sudo ip -4 addr add $LOCAL_V4_PREF dev $DEV
else
LOCAL_V6_PREF=$a
LOCAL_V6=`echo $LOCAL_V6_PREF | sed -e "s@/[0-9]*@@"`
echo === LOCAL_V6=$LOCAL_V6
echo === adding IPv6 address $LOCAL_V6_PREF ...
sudo ip -6 addr add $LOCAL_V6_PREF dev $DEV
fi
done
echo === configuring wireguard for device ...
TMP_DIR=/tmp/wireguard_exe_up
mkdir -p $TMP_DIR
TMP_CFG=$TMP_DIR/$DEV.conf
cat $CFG_FILE > $TMP_CFG
chmod o-r $TMP_CFG
wg-quick strip $TMP_CFG | sudo wg setconf $DEV /dev/stdin
rm $TMP_CFG
rmdir $TMP_DIR
#wg-quick strip $CFG_FILE | sudo wg setconf $DEV /dev/stdin
#sudo wg showconf $DEV
echo === starting device ...
sudo ip link set $DEV up
echo === showing device
ip link show dev $DEV
echo === showing device addresses
ip addr show dev $DEV
echo === showing wireguard status for device
#sudo wg showconf $DEV
sudo wg show $DEV
# retrieve info for route to Wireguard server
SERVER_IP=$(sudo wg showconf $DEV | grep "^ *Endpoint *= *" | \
sed -e "s@ @@g" | sed -e "s@Endpoint=@@" | sed -e "s@:[0-9]*\$@@" | sed -e "s@^\[@@" | sed -e "s@\]\$@@")
echo SERVER_IP=$SERVER_IP
SERVER_PROTO=4
if echo $SERVER_IP | grep -q ":"; then
SERVER_PROTO=6;
fi
echo SERVER_PROTO=$SERVER_PROTO
ROUTE=`ip -${SERVER_PROTO} route show default`
#echo ROUTE=$ROUTE
token () {
N=$1
shift
eval echo \$${N}
}
SERVER_GW=`token 3 $ROUTE`
echo SERVER_GW=$SERVER_GW
SERVER_IF=`token 5 $ROUTE`
echo SERVER_IF=$SERVER_IF
###########################################################
if [ "$LOCAL_V4" != "" ]; then
echo === adding IPV4 default route for table $IP_TABLE ...
sudo ip -4 route add default dev $DEV table $IP_TABLE
if [ "$SERVER_PROTO" == "4" ]; then
echo === adding IPV4 route for server for table $IP_TABLE ...
sudo ip -4 route add $SERVER_IP via $SERVER_GW dev $SERVER_IF table $IP_TABLE
fi
#sudo ip -4 route show table $IP_TABLE
if [ "$ALIAS_IDX" == "" ]; then
echo === adding IPV4 rule for VPN address $LOCAL_V4 for table $IP_TABLE ...
#sudo ip -4 rule del from $LOCAL_V4
sudo ip -4 rule add from $LOCAL_V4 table $IP_TABLE
#sudo ip -4 rule list
fi
if [ "$ALIAS_IDX" != "" ]; then
# set up IPv4 address alias
echo === using $ALIAS_V4 as IPv4 address alias ...
echo === adding IPv4 alias address ${ALIAS_V4} for device ...
sudo ip -4 addr add ${ALIAS_V4} dev $DEV
echo === adding IPV4 rule for address alias $ALIAS_V4 for table $IP_TABLE ...
#sudo ip -4 rule del from $ALIAS_V4
sudo ip -4 rule add from $ALIAS_V4 table $IP_TABLE
#sudo ip -4 rule list
echo === creating IPv4 nft table ...
sudo nft add table ip $NFT_TABLE
sudo nft flush table ip $NFT_TABLE
#sudo nft -a list ruleset
echo === setting up SNAT for IPV4 address alias ...
sudo nft create chain ip $NFT_TABLE nat_postrouting { type nat hook postrouting priority 0 \; }
sudo nft insert rule ip $NFT_TABLE nat_postrouting oifname "$DEV" ip saddr $ALIAS_V4 snat to $LOCAL_V4
#sudo nft -a list table ip $NFT_TABLE
echo === setting up DNAT for IPV4 address alias ...
sudo nft create chain ip $NFT_TABLE nat_prerouting {type nat hook prerouting priority 0 \; }
sudo nft add rule ip $NFT_TABLE nat_prerouting iifname "$DEV" dnat to $ALIAS_V4
#sudo nft -a list table ip $NFT_TABLE
echo === showing IPv4 nft rules
sudo nft -a list table ip $NFT_TABLE
fi # IPv4 address alias
echo === showing IPv4 rules for table $IP_TABLE
ip -4 rule list | grep $IP_TABLE
echo === showing IPv4 routing table for table $IP_TABLE
ip -4 route show table all | grep $IP_TABLE
fi # IPv4
###########################################################
if [ "$LOCAL_V6" != "" ]; then
echo === adding IPV6 default route for table $IP_TABLE ...
sudo ip -6 route add default dev $DEV table $IP_TABLE
if [ "$SERVER_PROTO" == "6" ]; then
echo === adding IPV6 route for server for table $IP_TABLE ...
sudo ip -6 route add $SERVER_IP via $SERVER_GW dev $SERVER_IF table $IP_TABLE
fi
#sudo ip -6 route show table $IP_TABLE
if [ "$ALIAS_IDX" == "" ]; then
echo === adding IPV6 rule for VPN address $LOCAL_V6 for table $IP_TABLE ...
#sudo ip -6 rule del from $LOCAL_V6
sudo ip -6 rule add from $LOCAL_V6 table $IP_TABLE
#sudo ip -6 rule list
fi
if [ "$ALIAS_IDX" != "" ]; then
# set up IPv6 address alias
echo === using $ALIAS_V6 as IPv6 address alias ...
echo === adding IPv6 alias address ${ALIAS_V6} for device ...
sudo ip -6 addr add ${ALIAS_V6} dev $DEV
echo === adding IPV6 rule for address alias $ALIAS_V6 for table $IP_TABLE ...
#sudo ip -6 rule del from $ALIAS_V6
sudo ip -6 rule add from $ALIAS_V6 table $IP_TABLE
#sudo ip -6 rule list
echo === creating IPv6 nft table ...
sudo nft add table ip6 $NFT_TABLE
sudo nft flush table ip6 $NFT_TABLE
#sudo nft -a list ruleset
echo === setting up SNAT for IPV6 address alias ...
sudo nft create chain ip6 $NFT_TABLE nat_postrouting { type nat hook postrouting priority 0 \; }
sudo nft insert rule ip6 $NFT_TABLE nat_postrouting oifname "$DEV" ip6 saddr $ALIAS_V6 snat to $LOCAL_V6
#sudo nft -a list table ip6 $NFT_TABLE
echo === setting up DNAT for IPV6 address alias ...
sudo nft create chain ip6 $NFT_TABLE nat_prerouting {type nat hook prerouting priority 0 \; }
sudo nft add rule ip6 $NFT_TABLE nat_prerouting iifname "$DEV" dnat to $ALIAS_V6
#sudo nft -a list table ip6 $NFT_TABLE
echo === showing IPv6 nft rules
sudo nft -a list table ip6 $NFT_TABLE
fi # IPv6 address alias
echo === showing IPv6 rules for table $IP_TABLE
ip -6 rule list | grep $IP_TABLE
echo === showing IPv6 routing table for table $IP_TABLE
ip -6 route show table all | grep $IP_TABLE
fi # IPv6
echo === |
Script is called using sh script arg1 arg2, arg1 being path to a wireguard config file, arg2 is ALIAS_IDX, which I don't know what it does (script works if it is omitted), so first question to network/bash gurus, it this script safe ?
Second question, what's the purpose of the ALIAS_IDX variable ?
Third question, with modifications (removing the sudo command, and maybe the parts that use ALIAS_IDX variable) could that script be used as an openrc service in place of wgquick service (the code I posted is to set up the wireguard interface, there's also a second script to properly shut it down, check the source link) ? Or maybe launch the script as a local service ?
Fourth question, the script source page gives a 3rd script to use with net-proxy/squid, allowing to use the vpn connection through a http proxy for apps that support it - as I get it, I could use webbrowser1 with my real IP, while webbrowser2 goes through the proxy. But I don't get how to use it Quote: | "To run this on a remote server and access SQUID there from home, you would need to set up an ssh tunnel to forward the listening port. " |
I have no clue about how to use ssh command to do that. Explanation for dummies is welcome
Thanks for reading _________________ Dragon Princess Music Games Heroes and villains |
|
Back to top |
|
|
nicop Tux's lil' helper
Joined: 10 Apr 2014 Posts: 97
|
|
Back to top |
|
|
krumpf Apprentice
Joined: 15 Jul 2018 Posts: 190
|
Posted: Wed Nov 20, 2024 6:53 pm Post subject: |
|
|
Hmm... The Wiki page changed since last time I read it, a namespace tutorial has been added, but tbh, it's beyond my understanding. Script I posted is easier for me to comprehend. _________________ Dragon Princess Music Games Heroes and villains |
|
Back to top |
|
|
flexibeast Guru
Joined: 04 Apr 2022 Posts: 457 Location: Naarm/Melbourne, Australia
|
Posted: Wed Nov 20, 2024 10:58 pm Post subject: |
|
|
krumpf wrote: | Script I posted is easier for me to comprehend. |
Okay, but one issue you might then end up facing is that it will be more difficult to get help with your setup, because you're not using standard Gentoo tools that experienced Gentoo users are familiar with.
On top of that, shell scripting is full of subtleties - i know enough to know how much i don't know, and i've been putting together the "Shell/Scripting" page to try to document some of the issues involved.
On top of that, the specific script you shared is large enough that it's not necessarily simple to review, even by experts (who can often be time-pressed due to their expertise resulting in lots of things on their plate).
That said, one issue i can immediately see in the script is the lack of double-quotes around file-related variables, e.g. CFG_FILE, which will cause problems if the script is passed a path with one or more spaces in it.
Overall, though, i would recommend asking questions about things on the wiki page that you don't understand, which might be more likely to get you answers, and also might help us improve the information provided.
krumpf wrote: | I have no clue about how to use ssh command to do that. |
This, on the other hand, is straightforward. :-) Refer to the -L option of ssh(1):
Quote: | -L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
Specifies that connections to the given TCP port or Unix socket
on the local (client) host are to be forwarded to the given host
and port, or Unix socket, on the remote side. This works by
allocating a socket to listen to either a TCP port on the local
side, optionally bound to the specified bind_address, or to a
Unix socket. Whenever a connection is made to the local port or
socket, the connection is forwarded over the secure channel, and
a connection is made to either host port hostport, or the Unix
socket remote_socket, from the remote machine.
Port forwardings can also be specified in the configuration file.
Only the superuser can forward privileged ports. IPv6 addresses
can be specified by enclosing the address in square brackets.
By default, the local port is bound in accordance with the
GatewayPorts setting. However, an explicit bind_address may be
used to bind the connection to a specific address. The
bind_address of “localhost” indicates that the listening port be
bound for local use only, while an empty address or ‘*’ indicates
that the port should be available from all interfaces. |
You'd also need to make sure that the AllowTcpForwarding option on the host you're connecting to is set appropriately; refer to the sshd_config(5) man page for details.
So what you'd do is something like (note this being done as superuser):
Code: | # ssh -L3128:remote_host:3128 remote_host |
which will connect to remote_host and forward Local port 3128 to remote_host port 3128 (i.e. the port that Squid listens on by default). _________________ https://wiki.gentoo.org/wiki/User:Flexibeast |
|
Back to top |
|
|
Hu Administrator
Joined: 06 Mar 2007 Posts: 22694
|
Posted: Wed Nov 20, 2024 11:17 pm Post subject: |
|
|
I did not read the script in enough detail to pronounce it safe or unsafe, but from a quick read, I will pronounce it as messy and poorly written. If I were to do a code review on it, I would at a minimum flag:- Rampant use of sudo is a sign of poor design. If it needs root this much, run it as root.
- Useless Use Of Cat.
- Useless Use of grep
- Poor use of sed.
- Quoting issues, as flexibeast mentioned
- It is specified to use bash (rather than sh), but seems not to make good use of bash-isms that would simplify the code. If it is meant to be portable, run it with sh. If it is meant to require bash, then make use of bash features to simplify the code.
- Dangerous use of a predictable path in /tmp
- Insufficient error checking
- Improper racy use of chmod
- Use of eval. Any script using eval requires closer scrutiny to determine its safety.
- From what I can see, it doesn't even need eval here. It could get equivalent results without eval.
- Sloppy use of ip rule list
|
|
Back to top |
|
|
flexibeast Guru
Joined: 04 Apr 2022 Posts: 457 Location: Naarm/Melbourne, Australia
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|