From 5684cd3a54a845693b065d19eb21a72712650c4a Mon Sep 17 00:00:00 2001 From: MatMoul Date: Mon, 25 Aug 2025 02:55:30 +0200 Subject: [PATCH] Add VPN code --- bin/mtm-ssh-proxy | 3 + bin/mtm-ssh-vpn | 166 +++++++++++++++++++++++++++++++++ completions/bash/mtm-ssh-proxy | 2 + completions/bash/mtm-ssh-vpn | 49 ++++++++++ config/config | 5 + config/profiles/profile | 11 +++ makerelease.sh | 32 +++++++ 7 files changed, 268 insertions(+) create mode 100755 bin/mtm-ssh-proxy create mode 100755 bin/mtm-ssh-vpn create mode 100644 completions/bash/mtm-ssh-proxy create mode 100644 completions/bash/mtm-ssh-vpn create mode 100644 config/config create mode 100644 config/profiles/profile create mode 100755 makerelease.sh diff --git a/bin/mtm-ssh-proxy b/bin/mtm-ssh-proxy new file mode 100755 index 0000000..8abe2b9 --- /dev/null +++ b/bin/mtm-ssh-proxy @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "Not implemented" \ No newline at end of file diff --git a/bin/mtm-ssh-vpn b/bin/mtm-ssh-vpn new file mode 100755 index 0000000..d6c25e8 --- /dev/null +++ b/bin/mtm-ssh-vpn @@ -0,0 +1,166 @@ +#!/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 diff --git a/completions/bash/mtm-ssh-proxy b/completions/bash/mtm-ssh-proxy new file mode 100644 index 0000000..05a7907 --- /dev/null +++ b/completions/bash/mtm-ssh-proxy @@ -0,0 +1,2 @@ +#!/bin/bash + diff --git a/completions/bash/mtm-ssh-vpn b/completions/bash/mtm-ssh-vpn new file mode 100644 index 0000000..e2be6bc --- /dev/null +++ b/completions/bash/mtm-ssh-vpn @@ -0,0 +1,49 @@ +#!/bin/bash + +_mtm-ssh-vpn() { + # shellcheck disable=SC2034 + local cur prev words cword args + _init_completion || return + + local -r CNF_ARGS="--help" + local -r CMD_ARGS="status connect disconnect disconnect-all" + local -r PROFILE_DIR=~/.config/mtm-ssh-proxy + local -r TMP_DIR="/tmp/mtm-ssh-proxy-${USER}/vpn" + + if [[ ${COMP_WORDS[*]} == *"--help"* ]]; then + return + fi + + args=${CMD_ARGS} + for arg in ${CNF_ARGS}; do + if [[ ${COMP_WORDS[*]} != *"${arg}"* ]]; then + args+=" ${arg}" + fi + done + for arg in ${CMD_ARGS}; do + if [[ ${COMP_WORDS[*]} == *" ${arg} "* ]]; then + args="" + fi + done + + case $prev in + --help | status | disconnect_all) return;; + connect) + local -r PROFILELIST=$(\ls "${PROFILE_DIR}") + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${PROFILELIST}" -- "${COMP_WORDS[COMP_CWORD]}")) + return + ;; + disconnect) + local -r PROFILELIST=$(\ls "${TMP_DIR}") + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${PROFILELIST}" -- "${COMP_WORDS[COMP_CWORD]}")) + return + ;; + *) + # shellcheck disable=SC2207 + COMPREPLY=($(compgen -W "${args}" -- "${COMP_WORDS[COMP_CWORD]}")) + return + ;; + esac +} && complete -F _mtm-ssh-vpn mtm-ssh-vpn \ No newline at end of file diff --git a/config/config b/config/config new file mode 100644 index 0000000..38e0325 --- /dev/null +++ b/config/config @@ -0,0 +1,5 @@ +# VPN default settings +SUBNETS=0.0.0.0/0 +#SUBNETS=192.168.0.0/24 192.168.1.0/24 +#EXCLUDE_SUBNETS=10.0.0.0/24 10.0.1.0/24 +#REDIRECT_DNS=0|no|false diff --git a/config/profiles/profile b/config/profiles/profile new file mode 100644 index 0000000..e13aa02 --- /dev/null +++ b/config/profiles/profile @@ -0,0 +1,11 @@ +# Main +PROXY=[user@]server[:port] + +# Proxy settings +PROXY_LOCAL_PORT=30501 + +# VPN settings +#SUBNETS=0.0.0.0/0 +#SUBNETS=192.168.0.0/24 192.168.1.0/24 +#EXCLUDE_SUBNETS=10.0.0.0/24 10.0.1.0/24 +#REDIRECT_DNS=0|no|false diff --git a/makerelease.sh b/makerelease.sh new file mode 100755 index 0000000..b0d6b33 --- /dev/null +++ b/makerelease.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +declare -r VERSION=${1} +declare -r MESSAGE=${2} +declare -r TAGBRANCH=main +declare CURRENTBRANCH="" + +showHelp() { + echo makerelease version +} + +if [ "${VERSION}" == "" ]; then + showHelp + echo "" + echo "no version provided!" + exit 1 +fi + +CURRENTBRANCH=$(git rev-parse --abbrev-ref HEAD) + +if [ ! "${CURRENTBRANCH}" == "dev" ]; then + echo "You are not in dev branch!" + echo "Use dev branch to make a release!" + exit 1 +fi + +git checkout "${TAGBRANCH}" +git merge "${CURRENTBRANCH}" +git push +git tag -a "${VERSION}" -m "${MESSAGE}" +git push --tags +git checkout "${CURRENTBRANCH}"