Jump to content


MastaG

Member Since 16 May 2009
Offline Last Active 22 Jun 2022 15:23
*****

Topics I've Started

Tunnel everything through Wireguard

20 June 2022 - 17:05

I'm running a Wireguard server on my home router and I'd like to tunnel everything on my enigma2 receiver through it. (e.g. Kodi with Netflix)

However I had a bit of trouble getting the default method working: /etc/wireguard/wg0.conf

[Interface]
Address = 10.10.0.2/24
PrivateKey = xx

[Peer]
PublicKey = yy
AllowedIPs = 0.0.0.0/0
Endpoint = my_wg_server.com:zzz
PersistentKeepalive = 25

This is because setting 0.0.0.0/0 for AllowedIPs will require some kernel module which is missing for my receiver.

 

After googling around a bit I figured I could also set: AllowedIPs = 0.0.0.0/1,128.0.0.0/1

This basically covers the whole internet.

But it didn't work for me.

Reason for this, is that it also tries to tunnel the default gateway of my internet connection (and thus the route to the wireguard server) when using these ranges.

 

So I figured I could just add a manual route to the wireguard server's endpoint using the default gateway after the tunnel has been setup.

In my case the default gateway would be 192.168.0.1, so basically after the tunnel has been setup I only have to do:

ip route add <wg_server_endpoint_ip> via 192.168.0.1

 

Now in order to automate this, I've hacked into an existing wireguard initscript: /etc/init.d/wireguard

#! /bin/bash

# Copyright (c) 2021 Karol Babioch <karol@babioch.de>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# LSBInitScript for Wireguard: This is a leightweight init script for
# Wireguard. While Wireguard itself requires only minimal overhead to setup and
# start, it still requires some script invocations (e.g. during boot).
#
# Most distributions are using systemd by now, and as such can use
# wg-quick@.service. However some distributions / images / Linux appliances
# are not (yet) using systemd. In such cases, this init script could be used
# to (re)start and/or stop Wireguard.
#
# It can handle all configured Wireguard interfaces (within /etc/wireguard)
# globally and/or individual interfaces, e.g. (/etc/init.d/wireguard start wg0).
#
# It relies on wg(8) and wg-quick(8) in the background.

### BEGIN INIT INFO
# Provides:          wireguard
# Required-Start:    $network $syslog
# Required-Stop:     $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts Wireguard interfaces
# Description:       Sets up Wireguard interfaces (by means of wg-quick).
### END INIT INFO

CONFIG_DIR=/etc/wireguard

function get_active_wg_interfaces() {
  INTERFACES=$(wg | grep "interface:" | sed 's/interface: /\1/')
  echo "$INTERFACES"
}

function set_default_gw_for_endpoints() {
  GATEWAY="$(ip r | grep default | cut -d ' ' -f3)"
  if [ ! "${GATEWAY}" == "" ]
  then
    wg | sed -n '/0.0.0.0\/1, 128.0.0.0\/1/{x;p;d;}; x' | sed -e 's/^[ \t]*//' | cut -d' ' -f2 | cut -d':' -f1 | while read line
    do
      echo "Setting default gateway: ${GATEWAY} for endpoint ${line}"
      ip route add ${line} via ${GATEWAY}
    done
  else
    echo "Could not determine default gateway on this system!"
    echo "Not setting it for endpoints!"
  fi
}

function remove_default_gw_for_endpoints() {                                                      
  GATEWAY="$(ip r | grep default | cut -d ' ' -f3)"                                            
  if [ ! "${GATEWAY}" == "" ]                                                                  
  then                                                                                         
    wg | sed -n '/0.0.0.0\/1, 128.0.0.0\/1/{x;p;d;}; x' | sed -e 's/^[ \t]*//' | cut -d' ' -f2 | cut -d':' -f1 | while read line
    do                                                                                         
      echo "Removing default gateway: ${GATEWAY} for endpoint ${line}"                          
      ip route del ${line} via ${GATEWAY}                                                      
    done                                                                                       
  else                                                                                         
    echo "Could not determine default gateway on this system!"                               
  fi                                                                                           
}

# This is required for wg-quick(1) to work correctly, i.e. for process
# substitution (`<()`) to work in Bash. If missing, wg-quick will fail with a
# "fopen: No such file or directory" error.
[ -e /dev/fd ] || ln -sf /proc/self/fd /dev/fd

case "$1" in

  start)
    if [ -z "$2" ]; then
      echo "Starting all configured Wireguard interfaces"
      for CONFIG in $(cd $CONFIG_DIR; ls *.conf); do
        wg-quick up ${CONFIG%%.conf}
      done
    else
      echo "Starting Wireguard interface: $2"
      wg-quick up "$2"
    fi
    set_default_gw_for_endpoints
    ;;

  stop)
    remove_default_gw_for_endpoints
    if [ -z "$2" ]; then
      echo "Stopping all active Wireguard interfaces"
      INTERFACES=$(get_active_wg_interfaces)
      for INTERFACE in $INTERFACES; do
        wg-quick down "$INTERFACE"
      done
    else
      echo "Stopping Wireguard interface: $2"
      wg-quick down "$2"
    fi
    ;;

  reload|force-reload)
    remove_default_gw_for_endpoints
    if [ -z "$2" ]; then
      echo "Reloading configuration for all active Wireguard interfaces"
      INTERFACES=$(get_active_wg_interfaces)
      for INTERFACE in $INTERFACES; do
        wg syncconf "$INTERFACE" <(wg-quick strip "$INTERFACE")
      done
    else
      echo "Reloading configuration for Wireguard interface: $2"
      wg syncconf "$2" <(wg-quick strip "$2")
    fi
    set_default_gw_for_endpoints
    ;;

  restart)
    $0 stop "$2"
    sleep 1
    $0 start "$2"
    ;;

  status)
    # TODO Check exit codes and align them with LSB requirements
    if [ -z "$2" ]; then
      INTERFACES=$(get_active_wg_interfaces)
      for INTERFACE in $INTERFACES; do
        wg show $INTERFACE
      done
    else
      wg show "$2"
    fi
    ;;

  *)
    echo "Usage: $0 { start | stop | restart | reload | force-reload | status } [INTERFACE]"
    exit 1
    ;;

esac

It's a bit hacky but it does the job.

It will add a route the wireguard's server using your routrer's default gateway, but only for endpoints which have : AllowedIPs = 0.0.0.0/1,128.0.0.0/1 set.

 

Hope it help anybody out struggling with a full wireguard tunnel :)