vpnerator/vpnerator.sh

200 lines
4.3 KiB
Bash
Raw Normal View History

2020-12-30 15:00:14 -07:00
#!/bin/bash
# Configures a temporary VPN tunnel (using single-use keys) to a remote host
# using WireGuard: https://www.wireguard.com/
#
# Author: Matt Low <matt@mlow.ca>
#
HOST=$1
HOST_ADDR=$(echo ${HOST} | awk -F '@' '{ print $NF }')
RAND=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 8 | head -1)
INTERFACE_NAME=tun-${RAND}
2020-12-30 15:00:14 -07:00
SERVER_ADDR=10.99.255.1/24
CLIENT_ADDR=10.99.255.2/32
DNS=8.8.8.8
echo "Generating keys..."
SERVER_KEY=$(wg genkey)
CLIENT_KEY=$(wg genkey)
SERVER_PUB=$(wg pubkey <<< ${SERVER_KEY})
CLIENT_PUB=$(wg pubkey <<< ${CLIENT_KEY})
PSK=$(wg genpsk)
echo " Server pubkey: ${SERVER_PUB}"
echo " Client pubkey: ${CLIENT_PUB}"
SERVER_LIB=$(cat << END
DEFAULT_IFACE=\$(awk '\$2 == 00000000 { print \$1 }' /proc/net/route)
exec_sudo() {
echo "[#] \$@"
sudo \$@ 2>/dev/null
}
deps() {
if ! type -p wg iptables >/dev/null ; then
echo "wireguard-tools or iptables missing, installing..."
sudo apt install -y wireguard-tools iptables 2>/dev/null \
|| sudo pacman -S --noconfirm wireguard-tools iptables 2>/dev/null \
|| sudo dnf install -y wireguard-tools iptables 2>/dev/null
if [ "\$?" -ne 0 ] ; then
echo "Could not install wireguard-tools and/or iptables. Aborting."
return 1
fi
fi
return 0
}
enable_forwarding() {
if sysctl net.ipv4.ip_forward | grep -q 0 ; then
sudo sysctl -wq net.ipv4.ip_forward=1
touch /tmp/vpnerator-ipfwd
fi
}
remove_interface() {
exec_sudo iptables -D FORWARD -i \$1 -j ACCEPT
exec_sudo iptables -D FORWARD -o \$1 -j ACCEPT
exec_sudo iptables -t nat -D POSTROUTING -s "${CLIENT_ADDR}" -o \${DEFAULT_IFACE} -j MASQUERADE
exec_sudo ip link del dev \$1
}
cleanup() {
if [ -f '/tmp/vpnerator-ipfwd' ] ; then
sudo sysctl -wq net.ipv4.ip_forward=0
rm /tmp/vpnerator-ipfwd
fi
EXIST_INTERFACE=\$(ip addr show to ${SERVER_ADDR} | head -1 | awk '{ print \$2 }' | cut -d':' -f1)
if [ ! -z "\${EXIST_INTERFACE}" ] ; then
if [ -z "\$(ip link show "\${EXIST_INTERFACE}" type wireguard)" ] ; then
# bail if the existing interface isn't of type wireguard
return 2
fi
remove_interface \${EXIST_INTERFACE}
return 0
elif ip link show ${INTERFACE_NAME} type wireguard > /dev/null 2>&1 ; then
remove_interface ${INTERFACE_NAME}
return 0
fi
return 1
}
END
)
setup_server() {
echo "Starting server..."
ssh -T ${HOST} /bin/bash <<- END
# include SERVER_LIB
${SERVER_LIB}
# Check/install depends
deps || exit 1
# Cleanup previous tunnel
cleanup
if [ "\$?" -eq 2 ] ; then
echo "$SERVER_ADDR is already being used on the server."
echo "Please choose another address."
exit 1
fi
2021-01-01 09:10:11 -07:00
umask 0177
TMP=\$(mktemp)
cat << EOF > \${TMP}
[Interface]
ListenPort = 51820
PrivateKey = ${SERVER_KEY}
2020-12-30 15:00:14 -07:00
[Peer]
# foo
PublicKey = ${CLIENT_PUB}
PresharedKey = ${PSK}
AllowedIPs = ${CLIENT_ADDR}
EOF
2020-12-30 15:00:14 -07:00
exec_sudo ip link add "${INTERFACE_NAME}" type wireguard
exec_sudo wg setconf "${INTERFACE_NAME}" "\${TMP}"
rm "\${TMP}"
2020-12-30 15:00:14 -07:00
exec_sudo ip addr add "${SERVER_ADDR}" dev "${INTERFACE_NAME}"
exec_sudo ip link set mtu 1420 up dev "${INTERFACE_NAME}"
exec_sudo iptables -A FORWARD -i "${INTERFACE_NAME}" -j ACCEPT
exec_sudo iptables -A FORWARD -o "${INTERFACE_NAME}" -j ACCEPT
exec_sudo iptables -t nat -A POSTROUTING -s "${CLIENT_ADDR}" -o "\${DEFAULT_IFACE}" -j MASQUERADE
enable_forwarding
2020-12-30 15:00:14 -07:00
echo
sudo wg show "$INTERFACE_NAME"
END
}
setup_client() {
umask 0177
FILE="/tmp/${INTERFACE_NAME}.conf"
cat <<- CONF > "${FILE}"
[Interface]
Address = ${CLIENT_ADDR}
PrivateKey = ${CLIENT_KEY}
DNS = ${DNS}
[Peer]
PublicKey = ${SERVER_PUB}
PresharedKey = ${PSK}
Endpoint = ${HOST_ADDR}:51820
AllowedIPs = 0.0.0.0/0, ::/0
CONF
echo "Starting client..."
sudo wg-quick up "${FILE}"
RESULT=$?
sleep 1
echo
sudo wg show "${INTERFACE_NAME}"
return $RESULT
}
2020-12-30 15:00:14 -07:00
cleanup() {
set -e
echo
echo "Stopping client..."
sudo wg-quick down ${FILE}
rm ${FILE}
2020-12-30 15:00:14 -07:00
echo
echo "Stopping server..."
ssh -T ${HOST} /bin/bash <<- END
${SERVER_LIB}
cleanup || echo "Server was already shut down."
2020-12-30 15:00:14 -07:00
END
echo
echo "Bye!"
exit
}
clear_env() {
# clear sensitive variables from memory
unset PSK
unset CLIENT_KEY
unset SERVER_KEY
}
echo
setup_server || { echo "Error starting server, aborting."; exit 1; }
echo
setup_client || { echo "Error starting client, cleaning up..."; cleanup; exit 1; }
clear_env
echo -e "\nConnected! SIGINT or Enter to disconnect and stop server."
2020-12-30 15:00:14 -07:00
trap cleanup INT TERM
read var
cleanup