#!/usr/bin/env bash # exit if a command fails set -o errexit # display last non-zero exit code in a failed pipeline set -o pipefail # exit if required variables are not set set -o nounset # this script should be run as root if [[ ${EUID} -ne 0 ]]; then echo "This script must be run as root" exit 1 fi # make sure the correct number of arguments are passed; if not, output syntax and exit if [ "$#" -ne 3 ]; then echo -e "\\nUsage: namespace.sh \\n" exit 1 fi # assign arguments to variables WIREGUARD_INTERFACE="$1" DOCKER_CONTAINER="$2" IP_ADDRESS="$3" # exit if container is using non-bridged networking NETWORK_MODE="$(docker inspect "${DOCKER_CONTAINER}" | jq '.[0] | .HostConfig | .NetworkMode' | sed 's/\"//g')" if [ "${NETWORK_MODE}" == "host" ] || [ "${NETWORK_MODE}" == "overlay" ] || [ "${NETWORK_MODE}" == "macvlan" ]; then echo "This script should only be used with bridged networking. Exiting." exit 1 fi # retrieve container pid and id CONTAINER_PID="$(docker inspect "${DOCKER_CONTAINER}" | jq '.[0] | .State | .Pid')" CONTAINER_ID="$(docker inspect "${DOCKER_CONTAINER}" | jq '.[0] | .Config | .Hostname' | sed 's/\"//g')" # exit if container id or pid does not exist if [[ "${CONTAINER_PID}" == "*null*" ]] || [[ "${CONTAINER_ID}" == "*null*" ]]; then echo "Container ID or PID is null. Exiting." exit 1 fi # stop pipelining errors set +o pipefail # softlink docker container network namespace to host mkdir -p /var/run/netns ln -sfT /proc/"${CONTAINER_PID}"/ns/net /var/run/netns/"${CONTAINER_ID}" # create wireguard interface echo "Adding Wireguard interface ${WIREGUARD_INTERFACE}." ip link add "${WIREGUARD_INTERFACE}" type wireguard || true # move wireguard interface into container namespace echo "Moving ${WIREGUARD_INTERFACE} into network namespace for container ${CONTAINER_ID}." ip link set "${WIREGUARD_INTERFACE}" netns "${CONTAINER_ID}" # add an ip address to wireguard interface echo "Adding IP address $IP_ADDRESS to ${WIREGUARD_INTERFACE}." ip -n "${CONTAINER_ID}" addr add "$IP_ADDRESS"/32 dev "${WIREGUARD_INTERFACE}" # set the wireguard config echo "Applying Wireguard config to ${WIREGUARD_INTERFACE}." ip netns exec "${CONTAINER_ID}" wg setconf "${WIREGUARD_INTERFACE}" /etc/wireguard/"${WIREGUARD_INTERFACE}".conf # bring up the wireguard link echo "Bringing up ${WIREGUARD_INTERFACE}." ip -n "${CONTAINER_ID}" link set "${WIREGUARD_INTERFACE}" up # set the default route over wireguard echo "Replacing default route." ip -n "${CONTAINER_ID}" route del default ip -n "${CONTAINER_ID}" route add default dev "${WIREGUARD_INTERFACE}"