wgs.conf

Configuration Server

# Server configuration
[Interface]
PrivateKey = +KA+NRsgSkKOzNybnLT88XPwGH24fpPGxMweh8eiV3o=
ListenPort = 51820

[Peer]     # PC/Notebook alice
PublicKey  = /PUx7ewV8gi/hHtNk9EaIWJSx1HnAue3HZPJMbKYnUs=
AllowedIPs = 198.16.0.2/32, 198.18.1.2/32, fd00:dead:beef::1:2/128, 0.0.0.0/0, ::/0, 0.0.0.0/0
PersistentKeepAlive = 25

[Peer]     # Smartphone, only IPv4
PublicKey  = F2TWiR3Ff9U56j4adhe8iv+9p4VGGk5Jvt1kD4EW6Ag=
AllowedIPs = 198.18.0.3/32

Im [Peer] Bereich sind die Adressen des Clients (x.x.x.x/32) einzutragen.

Sie sind Routing Informationen für der Server.

0.0.0.0/0, ::/0, 0.0.0.0/0 geben an aus welcher Adressenvereich Daten akzeptiert werden.

PersistentKeepAlive für ein Smartphone einzutragen ist eine ausgezeichnete Idee, damit das Akku schnell entladen wird. Also wird es nichtgesetzt.

wgs.conf

Configuration Client

# Client
[Interface]
PrivateKey = oPQktI+RwAAMPgFIqERvo4wAjnLeWUdlOc2xjcdD5Wk=

[Peer]# Server
PublicKey = oydqi7LriLZUqceIzZKJtZXoejHXfIdEOibB89XG2ic=
Endpoint = 192.0.2.123:51820
AllowedIPs = 0.0.0.0/0, ::/0, 0.0.0.0/0
PersistentKeepAlive = 25

Hier sind unter AllowedIPs nur die erlaubten Quellr angegeben. Die interne Adresse des Routers sollte vom Startscript bekannt sein, ist für wireguard selbst nicht von Belang.

smartphone.conf

# Smartphone configuration file
[Interface]
PrivateKey = UAlnpCh5q2WAUU1uJUQKgEL2Rs1NxvvqXc9fbGx2bUw=

[Peer] # Server
PublicKey = oydqi7LriLZUqceIzZKJtZXoejHXfIdEOibB89XG2ic=
Endpoint = 192.0.2.123:51820
AllowedIPs = 0.0.0.0/0

wgs.sh

Server Script

#!/bin/sh
# Server Script
# All traffic may be passed to our server.

USERSPACE=false
CNF=/etc/wireguard/wgs.conf

WG=wg0
MTU=1280 # shall not be lower if we want IPv6
# LAN Address
IP=198.18.0.1
IPNAT=198.18.1.1
IP6=fd00:dead:beaf::1:1
# Upstream DNS Server Address if we have to spann our DNS relay (DODNS=true)
DNS=192.168.178.1
DODNS=true # for disabling set to false

### End configuration

GWDEV=`ip r g 1.1.1.1 | awk '{print $5;exit}'`

case $1 in
start|up)
        if [ "$USERSPACE" == "true" ]
        then
                wireguard-go $WG
        else
                ip l add dev $WG type wireguard
        fi
        sysctl net.ipv4.conf.all.forwarding=1
        sysctl -w net.ipv4.ip_forward=1
        sysctl net.ipv6.conf.all.forwarding=1
        wg setconf $WG $CNF
        ip -6 a a $IP6/72 dev $WG
        ip -4 a a $IP/24 dev $WG
        ip a a $IPNAT/24 dev $WG
        ip link set mtu $MTU up dev $WG
        iptables -A FORWARD ! -s $IP/24 -j ACCEPT
        iptables -t nat -A POSTROUTING ! -s $IP/24 -o $GWDEV -j MASQUERADE
        ip6tables -A FORWARD -i $WG -j ACCEPT
        ip6tables -t nat -A POSTROUTING -o $GWDEV -j MASQUERADE
        $DODNS && dnsmasq -a $IP -S $DNS -h -R -k &
        ;;
stop|down)
        if [ "$USERSPACE" == "true" ]
        then
                pkill wireguard-go
        else
                ip link del dev $WG
        fi
        iptables -t nat -D POSTROUTING ! -s $IP/24 -o $GWDEV -j MASQUERADE
        iptables -D FORWARD  ! -s $IP/24 -j ACCEPT
        ip6tables -D FORWARD -i $WG -j ACCEPT
        ip6tables -t nat -D POSTROUTING -o $GWDEV -j MASQUERADE
        $DODNS && kill `cat /var/run/dnsmasq.pid`
        ;;
esac

Am Anfang des Scripts sind einige Variable anzupassen. Siehe kommentare

Sollte auf der Server ip6tables für NAT nicht vorhanden sein, kann eine Prefix delegation angefordert werden. Nachstehen ein Beispiel für Synology NAS System, Script /opt/etc/init.d/s64iapd

#!/bin/sh

ENABLED=yes
PROCS=dhclient6
ARGS="-6 -P ovs_eth1 -pf /tmp/dhclient-iapd.pid"
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

. /opt/etc/init.d/rc.func

###### COMMENT
# You will have to create first under /opt/bin the link
# cd /opt/bin
# ln -s /sbin/dhclient dhclient6
# You cann shown for the delegated prefix within the file:
# /var/db/dhclient6.leases
# at the end you may look for iaprefix or extract them with
# grep iaprefix /var/db/dhclient6.leases | tail -n 1 |\
# awk '{print $2}' | sed 's@/.*@@'
####################################################

##### For Raspberry PI which use dhcpcd you may set:
# interface eth0
# ia_pd 1 eth0/1 in the file /etc/dhcpcd
#
# and get the subnet with:
# dhcpcd -6 -U wlan0 |  sed -n -e "s/dhcp6_ia_pd1_prefix1='\(.*\)'/\1/p"
#
#####################################################

Auf der Fritz!Box ist zusätzlich eine IPv6 Route zu setzen

wgc.sh

Client Script

#!/bin/sh
# Client script
# all requests may pass through our tunnel

########################
# Tunnel Configuration #
########################

CNF=/etc/wireguard/wgc.conf # for test you may set this to an other location

# our IP for the client
IP0=198.18.0.2 # Tunnel addr mo NAT
IP1=198.18.1.2 # Tunnel addr NAT
IP6=fd00:dead:beef::1:2 # For accessing IPv6 through our tunnel

# Endpoint addresses
IP4EP=192.0.2.123       # IPv4
IP6EP=2a01:db8::1       # IPv6

# IP/Domain for the LAN
DNS=198.18.0.1          # DNS server at home
IPR=192.168.178.1       # LAN Address for our home router
DOMAIN="fritz.box"      # Search domain for address resolution of our LAN device

# Tunnnel mode
USEV6=false             # allow IPv6 access throung our tunnel
PASSTHROUGH=false       # All request shall pass through our tunnel

USERSPACE=false         # Use Kernel module (false), user space app. (true)

# MTU and interface name
MTU=1280                # The MTU shall not be less than 1280, the default value
                        # 1420 may be to big and disallow traffic
WG=wg0                  # May be set to an other name, only usefull if we use
                        # the kermel modules which allow to create more than 1 device

getDevGwSrc() {
        GATEWAY=`ip r get 1.1.1.1 | grep -v cache | awk '{print $3;exit}'`
        DEV=`ip r get 1.1.1.1 |  grep -v cache | awk '{print $5;exit}'`
        SRC=`ip r get 1.1.1.1 |  grep -v cache | awk '{print $7;exit}'`
        IPFE=`ip -6 r | grep default | awk '{print $3;exit}'`
}

epRoute() {
        $USEV6 && ip r $1 $IP6EP via $IPFE dev $DEV  # IPv6
        ip r $1 $IP4EP via $GATEWAY dev $DEV src $SRC # IPv4
}

delEpRoute() {
        RT=`ip r | grep $IP4EP`
        ip r d $RT
        RT=`ip r | grep $IP6EP`
        ip r d $RT
}

IP4PR=`echo $IPR | awk -F '.' '{printf("%s.%s.%s.0/24", $1,$2,$3)}'`

set -x
case $1 in
start|up)
        getDevGwSrc
        if [ "$USERSPACE" == "true" ]
        then
                wireguard-go $WG
        else
                ip l add dev $WG type wireguard
        fi
        $USERSPACE && wireguard-go $WG ||
        wg setconf $WG $CNF
        ip link set mtu $MTU up dev $WG
        if [ "$DNS" != "" ]
        then
                echo nameserver $DNS | resolvconf -a $WG -m 0 -x
                resolvectl  default-route $DEV 0
        fi
        ip a a $IP0/24 dev $WG
        ip a a $IP1/24 dev $WG
        ip r a $IP4PR via $IP1 dev $WG
        $USEV6 && ip a a $IP6/56 dev $WG

        if [ "$PASSTHROUGH" == "true" ]
        then
                ip r a 8000::/1 dev $WG
                ip r a 0000::/1 dev $WG
                ip r a 0.0.0.0/1 dev $WG src $IP1
                ip r a 128.0.0.0/1 dev $WG src $IP1
        fi
        epRoute add
        if [ "$GATEWAY" == "$IPR" ]
        then
                ip r a $GATEWAY dev $DEV
        fi
        resolvectl domain $WG $DOMAIN
        resolvectl default-route $WG
        ;;
stop|down)
        if [ "$USERSPACE" == "true" ]
        then
                pkill wireguard-go
        else
                ip link del dev $WG
        fi
        getDevGwSrc
        if [ "$GATEWAY" == "$IPR" ]
        then
                ip r d $GATEWAY dev $DEV
        fi
        if [ "$DNS" != "" ]
        then
                resolvectl  default-route $DEV 1
        fi
        epRoute del
        ;;
delrt)
        delEpRoute
        ;;
esac

Hier sind aus einige Variablen anzupassen.

USEV6 erlaubt es IPv6 Nachrichte über den Tunnel zu senden/empfangen.

PASSTHROUGH sorgt dafür dass den gesamten Verkehr des clients durch den Tunnel geleitet wird. In dem Fall muss USEV6 ebenfalls auf true gesetzt sein Als Gateway ist die IPv6 Adresse des NAS Gerätes einzusetzen.

In den Wireguard Konfigurations Dateien sind die Adressen, entsprechend delegierten Präfix einzutragen.

lwg.sh

Starter Script for the Desktop

#!/bin/sh
# Set the variables below

WG=wg0
SCRIPT=$HOME/bin/wgc.sh # Startscript für den Tunnel
SETICON=$HOME/bin/setwgicon.sh # Script zum Setzen der Starter Icon.

###
ip l sh $WG >/dev/null 2>&1
if [ $? -eq 1 ]
then
        TEXT="Start"
        CMD="up"
else
        TEXT="Stop"
        CMD="down"
fi
while true; do
        PASS=`zenity  --forms --add-password=Passwort --text="$TEXT Wireguard" --title Wireguard`
        if [ $? -eq 1 ]; then exit; fi
        if [ "$PASS" != ""  ]; then break; fi
done

sudo -k -S $SCRIPT $CMD <<!
$PASS
!

if [ $? -ne 0 ]
then
        zenity --error --text "$TEXT Gescheitert" --title Wireguard;
fi
if [ -f $SETICON ]
then
        $SETICON
fi

# Alternativ mit yad
# PWD=$(yad --title Wireguard --no-escape \
#       --text="$TEXT Wireguard" \
#       --image="dialog-password" \
#       --form  \
#       --field="Passwort":H | tr -d '|')
# oder
# PWD=$(yad --title Wireguard --no-escape \
#       --text="$TEXT Wireguard" \
#       --image="dialog-password" \
#       --entry="Passort" --hide-text)

# Fehlerbox mit Yad
# yad --title wireguard \
#       --image="dialog-error" \
#               --text="<b>$TEXT Gescheitert</b>" \

setwgicon.sh

Setzen des Starter Icons

#!/bin/sh
# Set the Path and file name according to your starter desktop file
DT=~/.config/.../*.desktop

# Make shure that the svg are copied to the right location
ICU=~/.local/share/icons/wireguard/wg-up.svg
ICD=~/.local/share/icons/wireguard/wg-down.svg

ACT=`ip l sh | grep wg`

case $? in
0) IC=$ICU;;
*) IC=$ICD;;
esac

sed -i -e "s@Icon.*@Icon=$IC@" $DT

/etc/NetworkManager/dispatcher.d/processwg.sh

#!bin/sh

# if the main interface state change correct the route for accessing our
# wireguard server

# we assume that the script ist located under:
# /home/$USR/bin
USR=`w | tail -n 1 | awk '{print $1}'`

# find which inferface we use for connection to the WAN
IF=`ip r | grep default | awk '{print $5}'`

if [ "$1" == "$IF" && ]
then
        ip l sh wg0 >/dev/null 2>&1
        if [ $? -eq 0 ]
        then
                case $2 in
                down)
                        /home/$USR/bin/wgc.sh delrt;;
                up)
                        /home/$USR/bin/wgc.sh stop
                        /home/$USR/bin/wgc.sh start
                esac
        fi
fi

Nur wenn das Gerät als Client laufen soll!

Falls ein Wechsel der Adresse vorhanden ist (Verbindung mit ein andere Netz) Route zum globale Internet ändern.

setWgEp.sh

#!/bin/sh
WGCNF=/etc/wireguard/wgc.conf
WG=wg0
IP4=192.0.2.123
IP6=2a01:db8::1
IPTS=198.18.0.1

PORT=`sed -n -e '/Endpoint/p' $WGCNF | sed -e  's/.*://'`
KEY=`sed -n -e '/PublicKey/p' $WGCNF | tr -d ' ' | sed 's/PublicKey=//'`

# Test if this will work via IPv6 Address

# Configure wireguard enpoint for IPv6
wg set $WG peer "$KEY" endpoint "[$IP6]:$PORT"

ping -q -c1 -W1  $IPTS >/dev/null 2>&1
if [ $? -eq 1 ]
then
        # IPv6 connection don't work
        # Set enpoint again to IPv4
        wg set $WG peer "$KEY" endpoint "$IP4:$PORT"
        # and test
        ping -q -c1 -W1  $IPTS >/dev/null 2>&1
        if [ $? -eq 1 ]
        then
                # IPv6 and IPv4 connections don't work
                exit 1
        fi
fi
exit 0

Das Script ändert das Endpunkt auf der IPv6 Adresse des Servers, testet ob die Kommunikation mit den Server funktioniert.

Erfolgt keine Kommunikation mit der Server wird das Endpunkt erneut auf IPv4 gestellt.

mkconf.sh

#!/bin/sh
# Build wireguard for all systems which may coonect via our tunnel

# IPv4 Endpoint for our wireguard server
EP4=192.0.2.123

# Port on which the server listen
PORT=51820

# Our internal IPv4/v6 Addresses without the last part
IP0=198.18.0.
IP1=198.18.1.
IP6=2a01:db8:affe:cafe:ad::1:

# We expect to find the datas within the file configdata.txt
# which content the data necessary to build the configurations file
# The first entry shall be the server, the next are for the client-
# The first word is the name of the device the second tell
# if we had to set PersistentKeepAlive.
# The script preserve the allready configured data.

# Example:
#####################################
# server     s
# smartphone m # This is a mobile device put "Address = "x.x.x.x/32"
# notebook   1 # Put "PersistentKeepAlive = 25" to the configuration file
# pc         0
# alice      0
# bob        0
######################################

I=0;
SERVER=

mkKey() {
        if [ ! -d $1 ]
        then
                umask 0077
                mkdir $1
                umask 0662
        fi
        if [  -e $1 ]
        then
                umask 0077
                wg genkey > $1/privkey
                umask 0002
                wg pubkey < $1/privkey > $1/pubkey
                umask 0002
        fi #2>/dev/null
}

cat configdata.txt | while read name alive rest
do
        if [ "$name" == "" ]
        then
                break;
        fi
        let I+=1
        mkKey $name
        if [ "$alive" == "s" ]
        then
                SERVER=$name;
                {
                        echo "[Interface] # $name"
                        echo "PrivateKey = " `cat $name/privkey`
                        echo "ListenPort = $PORT"
                        echo
                } >$SERVER/wg0.conf
        else
                {
                        echo "[Interface] # $name"
                        echo "PrivateKey = " `cat $name/privkey`
                        if [ "$alive" == "m" ]
                        then
                                echo "Address = $IP0$I/24"
                        fi
                        echo
                        echo "[Peer] # Server"
                        echo "PublicKey  = " `cat $SERVER/pubkey`
                        echo "AllowedIPs = 0.0.0.0/0, ::/0"
                        echo "EndPoint   = $EP4:$PORT"
                        if [ "$alive" == "1" ]
                        then
                                echo "PersistentKeepAlive = 25"
                        fi

                } > $name/wg0.conf
                {
                        echo "[Peer] # $name"
                        echo "PublicKey  =" `cat $name/pubkey`
                        echo "AllowedIPs = $IP0$I/32, $IP1$I/32, $IP6$I/128, 0.0.0.0/0, ::/0"
                        echo
                } >> $SERVER/wg0.conf
                qrencode -t png -s 6 -o $name/$name.png -r $name/wg0.conf
                # For decoding use zbarimg -q --raw path-to-file.png
        fi
done