Last active
April 26, 2024 07:03
-
-
Save andrew-aladjev/441d201db80e87d954e672c4b3d2dc28 to your computer and use it in GitHub Desktop.
Route for multiple wireguard clients
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
set -o pipefail | |
WG_ROUTING_TABLE="$1" | |
WG_INTERFACE="$2" | |
# Removing IPV4 routing table. | |
ip -4 route flush dev "$WG_INTERFACE" table "$WG_ROUTING_TABLE" || : | |
# Removing IPV6 routing table. | |
ip -6 route flush dev "$WG_INTERFACE" table "$WG_ROUTING_TABLE" || : |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
set -o pipefail | |
DIR=$(dirname "${BASH_SOURCE[0]}") | |
WG_ROUTING_TABLE="$1" | |
WG_INTERFACE="$2" | |
IPV4_NETWORK="$3" | |
IPV6_NETWORK="$4" | |
METRIC="$5" | |
# Routing IPV4 network. | |
ip -4 route add "$IPV4_NETWORK" dev "$WG_INTERFACE" metric "$METRIC" table "$WG_ROUTING_TABLE" || : | |
# Routing IPV6 network. | |
ip -6 route add "$IPV6_NETWORK" dev "$WG_INTERFACE" metric "$METRIC" table "$WG_ROUTING_TABLE" || : | |
# Getting hosts from wg endpoints. | |
readarray -t WG_HOSTS <<< $( | |
cat "${DIR}/"wg*.conf | | |
{ grep -i "endpoint\s*=" || :; } | | |
sed "s/.*endpoint\s*=\s*//gi" | | |
sed "s/:.*//g" || : | |
) | |
# Collecting IPs from hosts. | |
WG_IPSV4=() | |
WG_IPSV6=() | |
for WG_HOST in "${WG_HOSTS[@]}"; do | |
WG_HOST_IPSV4=$(getent ahostsv4 "$WG_HOST" | grep "STREAM" | cut -d " " -f 1 || :) | |
for WG_HOST_IPV4 in "${WG_HOST_IPSV4[@]}"; do | |
if [ ! -z "$WG_HOST_IPV4" ]; then | |
WG_IPSV4+=("$WG_HOST_IPV4") | |
fi | |
done | |
WG_HOST_IPSV6=$(getent ahostsv6 "$WG_HOST" | grep "STREAM" | cut -d " " -f 1 || :) | |
for WG_HOST_IPV6 in "${WG_HOST_IPSV6[@]}"; do | |
if [ ! -z "$WG_HOST_IPV6" ]; then | |
WG_IPSV6+=("$WG_HOST_IPV6") | |
fi | |
done | |
done | |
# Getting networks from wg addresses. | |
readarray -t WG_NETWORKS <<< $( | |
cat "${DIR}/"wg*.conf | | |
{ grep -i "address\s*=" || :; } | | |
sed "s/.*address\s*=\s*//gi" | | |
sed "s/\s*,\s*/,/g" || : | |
) | |
# Collecting IPs from networks. | |
for WG_NETWORK in "${WG_NETWORKS[@]}"; do | |
readarray -t WG_NETWORK_IPS <<< $(tr "," "\n" <<< "$WG_NETWORK" || :) | |
for WG_NETWORK_IP in "${WG_NETWORK_IPS[@]}"; do | |
if [ ! -z "$WG_NETWORK_IP" ]; then | |
if [[ "$WG_NETWORK_IP" =~ ":" ]]; then | |
WG_IPSV6+=("$WG_NETWORK_IP") | |
else | |
WG_IPSV4+=("$WG_NETWORK_IP") | |
fi | |
fi | |
done | |
done | |
# Getting IPV4 networks from main routing table. | |
readarray -t WG_IPV4_NETWORKS <<< $(ip -4 route show table main | cut -d " " -f 1 || :) | |
for WG_IPV4_NETWORK in "${WG_IPV4_NETWORKS[@]}"; do | |
if [ "$WG_IPV4_NETWORK" != "default" ]; then | |
WG_IPSV4+=("$WG_IPV4_NETWORK") | |
fi | |
done | |
# Getting IPV6 networks from main routing table. | |
readarray -t WG_IPV6_NETWORKS <<< $(ip -6 route show table main | cut -d " " -f 1 || :) | |
for WG_IPV6_NETWORK in "${WG_IPV6_NETWORKS[@]}"; do | |
if [ "$WG_IPV6_NETWORK" != "default" ]; then | |
WG_IPSV6+=("$WG_IPV6_NETWORK") | |
fi | |
done | |
# Getting sorted and unique IPs. | |
readarray -t WG_IPSV4 <<< $(printf "%s\n" "${WG_IPSV4[@]}" | sort -u) | |
readarray -t WG_IPSV6 <<< $(printf "%s\n" "${WG_IPSV6[@]}" | sort -u) | |
# Calculating IP patterns. | |
function join_by { | |
local d=${1-} f=${2-} | |
if shift 2; then | |
printf %s "$f" "${@/#/$d}" | |
fi | |
} | |
WG_IPV4_PATTERN=$(join_by "," "${WG_IPSV4[@]}") | |
WG_IPV6_PATTERN=$(join_by "," "${WG_IPSV6[@]}") | |
# Excluding IP patterns from default networks. | |
readarray -t WG_DEFAULT_IPV4_NETWORKS <<< $(python3 "${DIR}/WireGuard_Excluded_IPs.py" "0.0.0.0/0" "$WG_IPV4_PATTERN" || :) | |
readarray -t WG_DEFAULT_IPV6_NETWORKS <<< $(python3 "${DIR}/WireGuard_Excluded_IPs.py" "::/0" "$WG_IPV6_PATTERN" || :) | |
# Adding IPV4 default network routes. | |
for WG_DEFAULT_IPV4_NETWORK in "${WG_DEFAULT_IPV4_NETWORKS[@]}"; do | |
ip -4 route add "$WG_DEFAULT_IPV4_NETWORK" dev "$WG_INTERFACE" metric "$METRIC" table "$WG_ROUTING_TABLE" || : | |
done | |
# Adding IPV6 default network routes. | |
for WG_DEFAULT_IPV6_NETWORK in "${WG_DEFAULT_IPV6_NETWORKS[@]}"; do | |
ip -6 route add "$WG_DEFAULT_IPV6_NETWORK" dev "$WG_INTERFACE" metric "$METRIC" table "$WG_ROUTING_TABLE" || : | |
done | |
# Adding rule for IPV4 routing table. | |
IPV4_RULES=$(ip -4 rule list table "$WG_ROUTING_TABLE") | |
if [ -z "$IPV4_RULES" ]; then | |
ip -4 rule add table "$WG_ROUTING_TABLE" || : | |
fi | |
# Adding rule for IPV6 routing table. | |
IPV6_RULES=$(ip -6 rule list table "$WG_ROUTING_TABLE") | |
if [ -z "$IPV6_RULES" ]; then | |
ip -6 rule add table "$WG_ROUTING_TABLE" || : | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Interface] | |
PrivateKey = <key> | |
Address = 10.20.3.2/32, fd10:20:3::2/128 | |
Table = off | |
PostUp = /etc/wireguard/route-up.client.sh 51820 wg0 10.20.3.0/24 fd10:20:3::/64 10 | |
PreDown = /etc/wireguard/route-down.client.sh 51820 wg0 | |
[Peer] | |
PublicKey = <key> | |
# Address = 10.20.3.1/24, fd10:20:3::1/64 | |
AllowedIPs = 0.0.0.0/0, ::/0 | |
Endpoint = <domain>:<port> | |
PersistentKeepalive = 25 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Excluder script is here. You can have as many wireguards on the client as you want. Please be aware that you need to use the same table number 51820 for all wgs.