167 lines
3.9 KiB
Bash
Executable File
167 lines
3.9 KiB
Bash
Executable File
#!/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
|