Initial commit
This commit is contained in:
116
scripts/backtunnel-share
Normal file
116
scripts/backtunnel-share
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2025. LUXIM d.o.o., Slovenia - Matjaž Mozetič.
|
||||
|
||||
# backtunnel-share: Share a folder using reverse SSH for a limited duration
|
||||
# Syntax: backtunnel-share /path/to/folder with remoteuser:remotehost for 2h
|
||||
# Options: -p|--tunnel-port <PORT> -l|--local-ssh-port <PORT> -h|--help
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TUNNEL_PORT=2222 # remote-side port exposed via -R
|
||||
LOCAL_SSH_PORT=22 # local sshd port to forward to
|
||||
DURATION="" # required: e.g. 30m, 2h, 1d
|
||||
|
||||
usage() {
|
||||
cat >&2 <<EOF
|
||||
Usage:
|
||||
$(basename "$0") /path/to/folder with remoteuser:remotehost for <duration> [options]
|
||||
|
||||
Positional (required, in order):
|
||||
/path/to/folder Informational only (the actual folder is mounted by backtunnel-access)
|
||||
with Literal keyword
|
||||
remoteuser:remotehost Or remoteuser@remotehost
|
||||
for Literal keyword
|
||||
<duration> e.g. 30m, 2h, 1d (passed to 'timeout')
|
||||
|
||||
Options:
|
||||
-p, --tunnel-port N Remote tunnel port (default: ${TUNNEL_PORT})
|
||||
-l, --local-ssh-port N Local sshd port to expose (default: ${LOCAL_SSH_PORT})
|
||||
-h, --help Show this help
|
||||
|
||||
Examples:
|
||||
$(basename "$0") ~/projects with alice:vps.example.com for 2h
|
||||
$(basename "$0") ~/projects with alice@vps.example.com for 1d -p 4422 -l 2222
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- basic positional parsing ---
|
||||
[[ $# -lt 5 ]] && usage
|
||||
|
||||
FOLDER=$1
|
||||
KW1=$2
|
||||
REMOTE=$3
|
||||
KW2=$4
|
||||
DURATION=$5
|
||||
shift 5 || true
|
||||
|
||||
[[ "$KW1" != "with" ]] && usage
|
||||
[[ "$KW2" != "for" ]] && usage
|
||||
|
||||
# --- optional flags ---
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-p|--tunnel-port)
|
||||
[[ $# -lt 2 ]] && usage
|
||||
TUNNEL_PORT=$2
|
||||
shift 2
|
||||
;;
|
||||
-l|--local-ssh-port)
|
||||
[[ $# -lt 2 ]] && usage
|
||||
LOCAL_SSH_PORT=$2
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- validate duration (timeout supports s,m,h,d) ---
|
||||
if [[ ! "$DURATION" =~ ^[0-9]+[smhd]$ ]]; then
|
||||
echo "Invalid duration '$DURATION' (use forms like 30m, 2h, 1d)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- split remote user/host ---
|
||||
REMOTE_USER="" REMOTE_HOST=""
|
||||
if [[ "$REMOTE" == *:* ]]; then
|
||||
REMOTE_USER=${REMOTE%%:*}
|
||||
REMOTE_HOST=${REMOTE#*:}
|
||||
elif [[ "$REMOTE" == *"@"* ]]; then
|
||||
REMOTE_USER=${REMOTE%%@*}
|
||||
REMOTE_HOST=${REMOTE#*@}
|
||||
else
|
||||
echo "Invalid remote format. Use remoteuser:remotehost or remoteuser@remotehost" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- deps check ---
|
||||
command -v ssh >/dev/null 2>&1 || { echo "ssh not found."; exit 1; }
|
||||
command -v timeout >/dev/null 2>&1 || { echo "timeout not found."; exit 1; }
|
||||
|
||||
echo "⏳ Sharing '${FOLDER}' via reverse SSH:"
|
||||
echo " local sshd port : ${LOCAL_SSH_PORT}"
|
||||
echo " remote bind port : ${TUNNEL_PORT} (on ${REMOTE_HOST})"
|
||||
echo " remote user : ${REMOTE_USER}"
|
||||
echo " duration : ${DURATION}"
|
||||
echo
|
||||
echo "Tip: On the remote side, mount with:"
|
||||
echo " backtunnel-access '${FOLDER}' from ${REMOTE_USER}@${REMOTE_HOST} -p ${TUNNEL_PORT}"
|
||||
|
||||
timeout "$DURATION" ssh -N \
|
||||
-R "${TUNNEL_PORT}:localhost:${LOCAL_SSH_PORT}" \
|
||||
-- "${REMOTE_USER}@${REMOTE_HOST}"
|
||||
|
||||
rc=$?
|
||||
if [[ $rc -eq 124 ]]; then
|
||||
echo "⏹️ Sharing ended: reached duration (${DURATION})."
|
||||
exit 0
|
||||
fi
|
||||
exit "$rc"
|
||||
Reference in New Issue
Block a user