Skip to content

Instantly share code, notes, and snippets.

@pedro0311
Created April 10, 2025 21:42
Show Gist options
  • Select an option

  • Save pedro0311/548622f1700460b2de8814942e9acbfa to your computer and use it in GitHub Desktop.

Select an option

Save pedro0311/548622f1700460b2de8814942e9acbfa to your computer and use it in GitHub Desktop.
This script will create the configuration for your wireguard site-to-site full mesh VPN
#!/bin/sh
# wg.sh ver 1.22 - rs232 - 03/23
# DO NOT EDIT THIS FILE!
# All the config is placed in the wg0.conf and you can produce this automatically via "wg.sh makeconf"
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/home/root
PID=$$
black="\033[0;40m"
grey="\033[0;5;238m"
green="\033[48;2;32m"
alias logw='logger -p WARN -t wg-sh[$PID]'
DIR=$(dirname "$0")
cd $DIR; DIR=$(pwd)
int=wg0
checkmin=$(grep 'checkmin=' ${DIR}/${int}.conf | cut -d= -f2)
port=$(grep 'ListenPort' ${DIR}/${int}.conf | awk '{print $3}')
vnet=$(grep 'vnet=' ${DIR}/${int}.conf | cut -d= -f2)
rnet=$(grep -Ev '^($|#|\[)' ${DIR}/${int}.conf | grep -Eo '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/..' | grep -v .*/32$)
[ $# -gt 0 ] && {
[ $1 == "stop" ] && {
iptables -t mangle -nvL PREROUTING | grep -q '.*MARK.*all.*wg0.*0x1/0x7' && iptables -t mangle -D PREROUTING -i $int -j MARK --set-mark 0x01/0x7
iptables -nvL INPUT | grep -q ".*ACCEPT.*udp.dpt.${port}$" && iptables -D INPUT -p udp --dport $port -j ACCEPT
iptables -nvL INPUT | grep -q ".*ACCEPT.*all.*$int" && iptables -D INPUT -i $int -j ACCEPT
iptables -nvL FORWARD | grep -q ".*ACCEPT.*all.*$int" && iptables -D FORWARD -i $int -j ACCEPT
ip route | grep -Eo ".*dev.$int.*" | while read line; do ip route del $(echo $line | awk '{print $1}'); done
ifconfig $int down 2>/dev/null
ip link del dev $int 2>/dev/null
rmmod wireguard 2>/dev/null
cru l | grep -q '#wireguard-check#' && cru d wireguard-check
echo stopped.
exit
}
[ $1 == "check" -a $(wg | wc -l) -gt 3 ] && {
echo $rnet | tr " " "\n" | while read line; do
rsite=$(echo $line | cut -d. -f3 | grep -Eo '^[0-9]{0,3}')
sitesup=$(echo $vnet | cut -d. -f0-3)
sitehop=$(echo ${sitesup}.${rsite})
ip route | grep -q "^${line}.*dev.${int}" && {
ping -4 -I ${int} -c3 -A -q ${sitehop} &>/dev/null && echo "$line via ${sitehop} = still reachable" || { echo "$line via ${sitehop} = is now unreachable - removing from routing table" ; logw "$line via ${sitehop} = is now unreachable - removing from routing table" ; ip route del $(echo $line | awk '{print $1}') ;}
} || {
ping -4 -I ${int} -c3 -A -q ${sitehop} &>/dev/null && { echo "$line via ${sitehop} = is now reachable + adding to routing table" ; logw "$line via ${sitehop} = is now reachable + adding to routing table" ; ip route add $line dev $int ;} || echo "$line via ${sitehop} = still unreachable"
}
done
exit
}
[ $1 == "help" ] && {
echo -e "
┌────────────────── FreshTomato ────────────────────┐
wireguard
Usage:
help this screen
[empty] loads the script
stop to unload the config
check to verify VPN enpoint reachability
makeconf a wizard to create multisite config
The script can be run from anywhere but expects
a wg0.conf file to be present in the same folder.
makeconf is a good starting point.
└───────────────────────────────────────────────────┘
"
exit
}
[ $1 == "makeconf" ] && {
SCRIPT_PATH=$(dirname "$0")
d="/tmp/wireguard"
rm -fr $d &>/dev/null
mkdir $d
echo -e "
┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ This script will create the configuration for your wireguard site-to-site full mesh VPN. │
│ Please follow carefully the instructions and beware: you will need to keep to hand the │
▌ LAN subnet used by each site (/24) and define a brand new privately (rfc1918) addressed ▐
▌ subnet /24 of choice to dedicate to the inter-VPN connectivity. The configurationis fully▐
▌ automated including key generation, just make sure you answer the questions correctly. ▐
│ If any issue just re-run the makeconf. When finished you will just need to upload each │
│ site-specific-config to the relevant router │
└──────────────────────────────────────────────────────────────────────────────────────────┘"
read -p "
┌──────┐ ┌──────┐
│ rtrA │ │ rtrB │
└──────┘\ /└──────┘
*------------------*
| 192.168.253.0/24 |
*------------------*
┌──────┐/ \┌──────┐
│ rtrC │ │ rtrN │
└──────┘ └──────┘
Private /24 subnet to dedicate to the VPN interconnectivity in format X.X.X.0/24
(empty uses 192.168.253.0/24) : " vpnnet
[ -z $vpnnet ] && vpnnet=192.168.253.0/24
echo "vnet=$vpnnet" > $d/wireguard.TCONF
read -p "Port number to be used for wireguard communication
(empty uses default 51820) : " vpnport
[ -z $vpnport ] && vpnport=51280
echo "port=$vpnport
" >> $d/wireguard.TCONF
read -p "How many sites do you want to interconnect?
(default 2) : " vpnsites
[ -z $vpnsites ] && vpnsites=2
read -p "
How often do you want to check the status of wg? If any issue it will try to recover.
(0 to disable, 15 default) 0-60min : " ansp
[ -z $ansp ] && ansp=15
echo "
We will now enter the site specific section of the configuration."
i=1
while [ $i -le $vpnsites ]; do
read -p "
┌────────────────────
│ Site $i
├────────────────────
│ port= $vpnport
│ FQDN= ?
Name (FQDN) of the device : " ansa
read -p "
┌────────────────────
│ Site $i
├────────────────────
│ port= $vpnport
│ FQDN= $ansa
│ LAN= ?
LAN Subnet at this site (in format X.X.X.0/24) : " ansb
site=$(echo $ansb | grep -Eo '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/..' | grep .*/24$ | cut -d. -f3)
vpnip=$(echo $(echo $vpnnet | cut -d. -f1-3).${site}/24)
read -p "
┌────────────────────
│ Site $i
├────────────────────
│ port= $vpnport
│ FQDN= $ansa
│ LAN= $ansb
│ SiteRef= $site
│ VPNIP= $vpnip
│ port-in= ?
Is port $vpnport inbound from Internet possible on this site (e.g. WAN its a public IP or a port-fowarding for $vpnport)?
(default yes) y/n : " ansc
[ -z $ansc ] && ansc=y
# read -p "[Site $i] If this site subject to high packet loss e.g. WAN is 4G?
# (default no) y/n : " ansd
# [ -z $ansd ] && ansd=n
echo -e "${green}
┌────────────────────
│ Site $i
├────────────────────
│ port= $vpnport
│ FQDN= $ansa
│ LAN= $ansb
│ SiteRef= $site
│ VPNIP= $vpnip
│ port-in= $ansc
└────────────────────
${black}"
mkdir -p $d/$ansa
wg genkey > $d/${ansa}/privateKey 2>/dev/null
wg pubkey < $d/${ansa}/privateKey > $d/${ansa}/publicKey 2>/dev/null
echo "[interface]
PrivateKey = $(cat $d/$ansa/privateKey)
ListenPort = $vpnport
#vnet=$vpnip
#checkmin=$ansp
"> $d/${ansa}/$int.conf
echo "[peer] #$ansa
EndPoint = $ansa
PublicKey = $(cat $d/$ansa/publicKey)
AllowedIPs = $vpnip, $ansb
$([ $ansc == "n" ] && echo 'PersistentKeepalive = 25')
" > $d/${ansa}.TEMPO
i=$((i+1))
done
ls -p $d | grep .*/$ | cut -d/ -f1 | while read folder; do
cd $d/$folder
ls -1 ../*.TEMPO | grep -v "$folder" | while read line; do cat $line >> $int.conf
echo "************ 2 $d/$folder ****************"
cp -f $SCRIPT_PATH/wg.sh ./wg.sh
done
done
echo -e "
┌────────────────────────────────────────────────────────────────────────────────────────┐
▌ ${grey}Configuration completed.${black} ▐
└────────────────────────────────────────────────────────────────────────────────────────┘
Find the each site relevant ${green}wg.sh${black} and ${green}$int.conf${black} files in:${green}
$(ls -l $d | grep ^d | awk '{print "/tmp/wireguard/"$9"/"}')${black}
Copy each wg.sh & $int.conf on the permanent storage of target router e.g. /jffs.
Place them both in the same folder. Bring the VPN up calling /whateverpath/wg.sh
NOTEs:
- do not edit the wg.sh or $int.conf they are ready to be used as they are
- remember to ${green}chmod +x wg.sh${black} on the target device.
- to autostart you could use something like this in the Administration/script/firewall:
${green}/jffs/wg.sh${black}
"
find $d -name '*.TCONF' -exec rm {} + &>/dev/null
find $d -name '*.TEMPO' -exec rm {} + &>/dev/null
find $d -name '*Key' -exec rm {} + &>/dev/null
exit
}
}
ifconfig $int down 2>/dev/null
ip link del dev $int 2>/dev/null
rmmod wireguard 2>/dev/null
modprobe wireguard
ip link add dev $int type wireguard
ip address add dev $int $vnet
wg setconf $int $DIR/$int.conf
sleep 1
ifconfig $int up
# bypass CTF for wireguard
[ $(nvram get ctf_disable) -eq 0 ] && {
iptables -t mangle -nvL PREROUTING | grep -q '.*MARK.*all.*wg0.*0x1/0x7' || iptables -t mangle -I PREROUTING -i $int -j MARK --set-mark 0x01/0x7
}
# open WireGuard port
iptables -nvL INPUT | grep -q ".*ACCEPT.*udp.dpt.${port}$" || iptables -A INPUT -p udp --dport $port -j ACCEPT
# accept packets from WireGuard internal subnet
iptables -nvL INPUT | grep -q ".*ACCEPT.*all.*$int" || iptables -A INPUT -i $int -j ACCEPT
# set up forwarding
iptables -nvL FORWARD | grep -q ".*ACCEPT.*all.*$int" || iptables -A FORWARD -i $int -j ACCEPT
rnet=$(grep -Ev '^($|#|\[)' ${DIR}/${int}.conf | grep -Eo '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/..' | grep -v .*/32$)
# add routes to opposite lan
echo $rnet | tr " " "\n" | while read line; do ip route | grep -q "^${line}.*dev.$int.*" || ip route add $line dev $int; done
# add periodic checks
[ $checkmin -ne 0 ] && cru l | grep -q '#wireguard-check#' || cru a wireguard-check "*/${checkmin} * * * * ${DIR}/wg.sh check"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment