Last active
September 5, 2025 16:43
-
-
Save brettowe/4d9d7b24baa5f974c998fa45fadd53a4 to your computer and use it in GitHub Desktop.
wireguard namespace script, based off the script found here https://www.wireguard.com/netns/, made more automatic for pulling info from wg-quick configs and deal with a system using NetworkManager
This file contains hidden or 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 | |
# based off the basic script idea found here: https://www.wireguard.com/netns/ | |
set -ex | |
# namespace name | |
ns=physical | |
# ethernet type device list, seperated by spaces | |
physeth="enp1s0" | |
# wifi devices | |
physwifi="wlp2s0" | |
# list of phy devices that iw needs to touch | |
phywifi="phy0" | |
# wireguard device to use | |
wgdev=wg0 | |
# assumes wg-quick style file | |
wgcfg=/etc/wireguard/wg0.conf | |
[[ $UID != 0 ]] && exec sudo -E "$(readlink -f "$0")" "$@" | |
up() { | |
wgip=$(grep Address ${wgcfg} | tr -d ' ' | cut -d '=' -f 2) | |
nsresolvconfdir="/etc/netns/${ns}" | |
nsresolvconf="${nsresolvconfdir}/resolv.conf" | |
wgresolvconf="/etc/resolv.conf" | |
wgip=$(grep Address ${wgcfg} | tr -d ' ' | cut -d '=' -f 2) | |
EPHN=$(grep Endpoint ${wgcfg} | tr -d ' ' | cut -d '=' -f 2 | cut -d ':' -f 1 | cut -d ' ' -f 1) | |
# use getent to resolve wireguard endpoint dns names to IP since wg will fail when it runs trying | |
# to resolve the dns since open dns requests are outside the namespace it attempts to connect with | |
EPIP=$(getent hosts ${EPHN} | tr -s ' ' | cut -d ' ' -f 1) | |
DNSIP=$(grep DNS ${wgcfg} | tr -d ' ' | cut -d '=' -f 2) | |
wgtmpcfg=$(mktemp) | |
if [ -d ${nsresolvconfdir} ]; then | |
mkdir -p ${nsresolvconfdir} | |
fi | |
# copy previous resolvconf into namespace conf space | |
# dhcp might overwrite it immediately but better than nothing existing | |
cp ${wgresolvconf} ${nsresolvconf} | |
# then modify previous copy for the namespace wg is in | |
sed --in-place -e "s/nameserver .*/nameserver ${DNSIP}/" ${wgresolvconf} | |
sed -e "/Address/d; /DNS/d; s/${EPHN}/${EPIP}/" ${wgcfg} > ${wgtmpcfg} | |
systemctl stop NetworkManager || true | |
ip netns add ${ns} | |
ip -n ${ns} link add ${wgdev} type wireguard | |
ip -n ${ns} link set ${wgdev} netns 1 | |
wg setconf ${wgdev} ${wgtmpcfg} | |
ip addr add ${wgip} dev ${wgdev} | |
for pd in ${physeth}; do | |
ip link set ${pd} down | |
ip link set ${pd} netns ${ns} | |
done | |
for pd in ${physwifi}; do | |
ip link set ${pd} down | |
done | |
for pd in ${phywifi}; do | |
iw phy ${pd} set netns name ${ns} | |
done | |
# would like to just use network manager to manage the interfaces but it needs more than just itself | |
#ip netns exec ${ns} NetworkManager | |
ip link set ${wgdev} up | |
ip route add default dev ${wgdev} | |
rm ${wgtmpcfg} | |
} | |
down() { | |
#systemctl stop NetworkManager || true | |
#killall -KILL NetworkManager || true | |
killall -KILL dhcpcd || true | |
ip link del ${wgdev} || true | |
for pd in ${physeth}; do | |
ip -n ${ns} link set ${pd} down | |
ip -n ${ns} link set ${pd} netns 1 | |
done | |
for pd in ${physwifi}; do | |
ip -n ${ns} link set ${pd} down | |
done | |
for pd in ${phywifi}; do | |
ip netns exec ${ns} iw phy ${pd} set netns 1 | |
done | |
ip netns del ${ns} | |
systemctl start NetworkManager | |
} | |
execi() { | |
exec ip netns exec ${ns} sudo -E -u \#${SUDO_UID:-$(id -u)} -g \#${SUDO_GID:-$(id -g)} -- "$@" | |
} | |
command="$1" | |
shift | |
case "$command" in | |
up) up "$@" ;; | |
down) down "$@" ;; | |
exec) execi "$@" ;; | |
*) echo "Usage: $0 up|down|exec" >&2; exit 1 ;; | |
esac | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment