#!/bin/bash function showHelp() { echo "mtm-ssh-vpn [args] command cmd_args" echo "" echo "args :" echo " --help Show help" echo "command :" echo " status" echo " connect profile" echo " disconnect profile" echo " disconnect-all" echo "cmd_args :" echo " profile Name of the profile (~/.config/mtm-ssh-proxy/*)" } if [ "${1}" == "" ]; then showHelp exit 1 fi case ${1} in "--help") showHelp exit 0 ;; "status" | "disconnect-all");; "connect" | "disconnect") if [ "${2}" == "" ] || [[ "${2}" == */* ]]; then showHelp exit 1 fi ;; *) showHelp exit 1 ;; esac declare -r CONFIG_DIR=~/.config/mtm-ssh-proxy declare -r TMP_DIR=/tmp/mtm-ssh-proxy-"${USER}/vpn" read_config() { declare -r FILE=${1} declare -r KEYNAME=${2} declare -r DEFAULT=${3} if [ -f "${FILE}" ]; then if grep -v "#" "${FILE}" | grep -q "${KEYNAME}="; then VALUE=$(grep -v "#" "${FILE}" | grep "^${KEYNAME}=" | sed 's/'"${KEYNAME}"'=//') echo "${VALUE}" return 0 fi fi echo "${DEFAULT}" } status() { if [ -d "${TMP_DIR}" ] && [ "$(find "${TMP_DIR}" -maxdepth 0 -empty -exec echo 1 \;)" == "" ]; then for FILE in "${TMP_DIR}"/*; do PROFILE=$(basename "${FILE}") PROXY=$(grep 'PROXY=' "${FILE}" | sed 's/PROXY=//') echo -e "${PROFILE}\t${PROXY}" done else echo "No vpn open" fi } connect() { declare -r CONFIG=${CONFIG_DIR}/config declare -r FILE=${CONFIG_DIR}/profiles/${1} if [ ! -f "${FILE}" ]; then echo "Error: Profile not found" >&2 exit 1 fi declare -r PROFILE=${1} if [ -f "${TMP_DIR}/${PROFILE}" ]; then echo "Error: VPN already start" >&2 exit 1 fi declare PROXY="" declare SUBNETS="0.0.0.0/0" declare EXCLUDE_SUBNETS="" declare REDIRECT_DNS=1 SUBNETS=$(read_config "${CONFIG}" "SUBNETS" "${SUBNETS}") EXCLUDE_SUBNETS=$(read_config "${CONFIG}" "EXCLUDE_SUBNETS" "${EXCLUDE_SUBNETS}") REDIRECT_DNS=$(read_config "${CONFIG}" "REDIRECT_DNS" "${REDIRECT_DNS}") PROXY=$(read_config "${FILE}" "PROXY" "${PROXY}") SUBNETS=$(read_config "${FILE}" "SUBNETS" "${SUBNETS}") EXCLUDE_SUBNETS=$(read_config "${FILE}" "EXCLUDE_SUBNETS" "${EXCLUDE_SUBNETS}") REDIRECT_DNS=$(read_config "${FILE}" "REDIRECT_DNS" "${REDIRECT_DNS}") echo "Connecting to ${PROFILE}" echo "PROXY : ${PROXY}" echo "SUBNETS : ${SUBNETS}" echo "EXCLUDE_SUBNETS : ${EXCLUDE_SUBNETS}" echo "REDIRECT_DNS : ${REDIRECT_DNS}" declare -r PIDFILE=$(mktemp -u) CMD="sshuttle --user ${USER} -D --pidfile ${PIDFILE} -r ${PROXY}" if [ "${REDIRECT_DNS}" == 1 ]; then CMD+=" --dns" fi # shellcheck disable=SC2206 EXCLUDE_SUBNETS=(${EXCLUDE_SUBNETS}) for EXCLUDE_SUBNET in "${EXCLUDE_SUBNETS[@]}"; do CMD+=" -x ${EXCLUDE_SUBNET}" done # shellcheck disable=SC2206 SUBNETS=(${SUBNETS}) for SUBNET in "${SUBNETS[@]}"; do CMD+=" ${SUBNET}" done if [ ! -d "${TMP_DIR}" ]; then mkdir -p "${TMP_DIR}" fi eval "${CMD}" { echo "PROXY=${PROXY}" echo "SUBNETS=${SUBNETS[*]}" echo "EXCLUDE_SUBNETS=${EXCLUDE_SUBNETS[*]}" echo "REDIRECT_DNS=${REDIRECT_DNS}" echo "PID=$(cat "${PIDFILE}")" } > "${TMP_DIR}/${PROFILE}" } disconnect() { declare ERROR=0 if [ -d "${TMP_DIR}" ] && [ "$(find "${TMP_DIR}" -maxdepth 0 -empty -exec echo 1 \;)" == "" ]; then declare -r FILE=${TMP_DIR}/${1} PROFILE=$(basename "${FILE}") PID=$(grep 'PID=' "${FILE}" | sed 's/PID=//') if ! kill "${PID}"; then echo "Error: disconnecting vpn ${PROFILE}" >&2 ERROR=1 fi rm "${TMP_DIR}/${PROFILE}" fi return "${ERROR}" } disconnect_all() { declare ERROR=0 if [ -d "${TMP_DIR}" ] && [ "$(find "${TMP_DIR}" -maxdepth 0 -empty -exec echo 1 \;)" == "" ]; then for FILE in "${TMP_DIR}"/*; do PROFILE=$(basename "${FILE}") if [ "$(disconnect "${PROFILE}")" == "1" ]; then ERROR=1 fi done fi return "${ERROR}" } case ${1} in "status") status;; "connect") connect "${2}";; "disconnect") if [ "$(disconnect "${2}")" == "1" ]; then exit 1 fi ;; "disconnect-all") if [ "$(disconnect_all)" == "1" ]; then exit 1 fi ;; *) exit 1;; esac