Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Wireguard interface questions
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Networking & Security
View previous topic :: View next topic  
Author Message
krumpf
Apprentice
Apprentice


Joined: 15 Jul 2018
Posts: 191

PostPosted: Wed Nov 20, 2024 3:53 pm    Post subject: Wireguard interface questions Reply with quote

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 :D

Thanks for reading
_________________
Dragon Princess Music Games Heroes and villains
Back to top
View user's profile Send private message
nicop
Tux's lil' helper
Tux's lil' helper


Joined: 10 Apr 2014
Posts: 103

PostPosted: Wed Nov 20, 2024 4:49 pm    Post subject: Reply with quote

You should consult config from wiki : https://wiki.gentoo.org/wiki/WireGuard#Network_management_methods and comment lines that set default route.

To use VPN only for an app, the simpliest method is to run that app with a specific user and set an ip rule with uidrange.
Back to top
View user's profile Send private message
krumpf
Apprentice
Apprentice


Joined: 15 Jul 2018
Posts: 191

PostPosted: Wed Nov 20, 2024 6:53 pm    Post subject: Reply with quote

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
View user's profile Send private message
flexibeast
Guru
Guru


Joined: 04 Apr 2022
Posts: 473
Location: Naarm/Melbourne, Australia

PostPosted: Wed Nov 20, 2024 10:58 pm    Post subject: Reply with quote

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
View user's profile Send private message
Hu
Administrator
Administrator


Joined: 06 Mar 2007
Posts: 22876

PostPosted: Wed Nov 20, 2024 11:17 pm    Post subject: Reply with quote

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
View user's profile Send private message
flexibeast
Guru
Guru


Joined: 04 Apr 2022
Posts: 473
Location: Naarm/Melbourne, Australia

PostPosted: Wed Nov 20, 2024 11:42 pm    Post subject: Reply with quote

Hu wrote:
Use of eval. Any script using eval requires closer scrutiny to determine its safety.

Greg Wooledge's FullBashFAQ has a good entry on eval's security issues.

The use of backticks instead of $(...) made me uneasy, but i couldn't explain why; the FullBashFAQ covers that too.
_________________
https://wiki.gentoo.org/wiki/User:Flexibeast
Back to top
View user's profile Send private message
krumpf
Apprentice
Apprentice


Joined: 15 Jul 2018
Posts: 191

PostPosted: Thu Nov 21, 2024 2:26 pm    Post subject: Reply with quote

Thanks for your answers ! Guess I'll have to study a bit more the wireguard wiki page, until I get a better understanding of all that. I'll update thread should I need help to understand something too obscure for my brain :lol:
_________________
Dragon Princess Music Games Heroes and villains
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Networking & Security All times are GMT
Page 1 of 1

 
Jump to:  
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