Enhance backtunnel-share with improved desktop integration, port collision checks, and pre-flight validations
This commit is contained in:
@@ -32,6 +32,20 @@ _backtunnel_complete() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# backtunnel-share: after positionals, propose flags incl. invite
|
||||||
|
if [[ ${COMP_WORDS[0]} == backtunnel-share && ${COMP_CWORD} -ge 5 ]]; then
|
||||||
|
local opts="-p --tunnel-port -l --local-ssh-port -i --invite --invite-mount --invite-file --qr -h --help"
|
||||||
|
mapfile -t COMPREPLY < <(compgen -W "${opts}" -- "${cur}")
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# backtunnel-access: after positionals, propose its flags
|
||||||
|
if [[ ${COMP_WORDS[0]} == backtunnel-access && ${COMP_CWORD} -ge 3 ]]; then
|
||||||
|
local opts="-p --port -m --mount-point -h --help"
|
||||||
|
mapfile -t COMPREPLY < <(compgen -W "${opts}" -- "${cur}")
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,18 @@
|
|||||||
Type=Application
|
Type=Application
|
||||||
Name=BackTunnel
|
Name=BackTunnel
|
||||||
Comment=Reverse SSH folder sharing and access
|
Comment=Reverse SSH folder sharing and access
|
||||||
Exec=backtunnel-share %f
|
Exec=bash -lc '
|
||||||
|
FOLDER="%f";
|
||||||
|
REMOTE="$(kdialog --inputbox "Remote (user@host or user:host):" "user@vps.example.com")" || exit 1;
|
||||||
|
DUR="$(kdialog --combobox "Share duration" 30m 2h 6h 1d 2d --editable "2h")" || exit 1;
|
||||||
|
TPORT="$(kdialog --inputbox "Tunnel port on remote:" "2222")" || exit 1;
|
||||||
|
LPORT="$(kdialog --inputbox "Local SSH port to expose:" "22")" || exit 1;
|
||||||
|
if kdialog --yesno "Print invite line for chat?"; then INV="-i"; else INV=""; fi;
|
||||||
|
if kdialog --yesno "Show QR code for the invite?"; then QR="--qr"; else QR=""; fi;
|
||||||
|
MP="$(kdialog --inputbox "Suggested mount point in invite:" "/mnt/remote-rssh")" || exit 1;
|
||||||
|
konsole --noclose -e backtunnel-share "$FOLDER" with "$REMOTE" for "$DUR" \
|
||||||
|
-p "$TPORT" -l "$LPORT" $INV $QR --invite-mount "$MP"
|
||||||
|
'
|
||||||
Icon=network-vpn
|
Icon=network-vpn
|
||||||
Terminal=true
|
Terminal=true
|
||||||
Categories=Network;Utility;
|
Categories=Network;Utility;
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ The sharing ends automatically after the given \fIduration\fR via \fBtimeout\fR.
|
|||||||
With the \fB--invite\fR option, \fBbacktunnel-share\fR prints a ready-to-copy access command for the remote user,
|
With the \fB--invite\fR option, \fBbacktunnel-share\fR prints a ready-to-copy access command for the remote user,
|
||||||
which can be pasted directly into a chat or terminal. The invite can also be rendered as a QR code or written to a file.
|
which can be pasted directly into a chat or terminal. The invite can also be rendered as a QR code or written to a file.
|
||||||
|
|
||||||
\fBbacktunnel-access\fR mounts the shared folder from the remote side using \fBsshfs\fR by connecting to \fBlocalhost:<port>\fR on the remote host (the port exposed by \fBbacktunnel-share\fR).
|
\fBbacktunnel-access\fR mounts the shared folder from the remote side using \fBsshfs\fR by connecting to \fBlocalhost:<port>\fR on the remote host
|
||||||
|
(the port exposed by \fBbacktunnel-share\fR).
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.SS backtunnel-share options
|
.SS backtunnel-share options
|
||||||
@@ -80,7 +81,7 @@ Share for 1 day, using custom ports:
|
|||||||
/home/user/docs with alice:vps.example.com for 1d -p 4422 -l 2222
|
/home/user/docs with alice:vps.example.com for 1d -p 4422 -l 2222
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
Share with invite printed:
|
Share for 2 hours and print an invite:
|
||||||
.B backtunnel-share
|
.B backtunnel-share
|
||||||
/home/user/docs with alice@vps.example.com for 2h -i
|
/home/user/docs with alice@vps.example.com for 2h -i
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2025. LUXIM d.o.o., Slovenia - Matjaž Mozetič.
|
# Copyright (c) 2025. LUXIM d.o.o., Slovenia - Matjaž Mozetič.
|
||||||
|
# Licensed under the GNU GPL v3.0
|
||||||
|
|
||||||
# backtunnel-share: Share a folder using reverse SSH for a limited duration
|
# backtunnel-share: Share a folder using reverse SSH for a limited duration
|
||||||
# Syntax: backtunnel-share /path/to/folder with remoteuser:remotehost for 2h
|
# Syntax: backtunnel-share /path/to/folder with remoteuser:remotehost for 2h
|
||||||
@@ -163,8 +164,23 @@ fi
|
|||||||
|
|
||||||
echo "Tip: On the remote side, mount with:"
|
echo "Tip: On the remote side, mount with:"
|
||||||
echo " backtunnel-access '${FOLDER}' from ${REMOTE_USER}@${REMOTE_HOST} -p ${TUNNEL_PORT}"
|
echo " backtunnel-access '${FOLDER}' from ${REMOTE_USER}@${REMOTE_HOST} -p ${TUNNEL_PORT}"
|
||||||
|
echo "To stop sharing early: press Ctrl+C here."
|
||||||
|
|
||||||
|
# --- optional pre-flight: warn if remote loopback port is already in use (best-effort) ---
|
||||||
|
if ssh -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_USER}@${REMOTE_HOST}" \
|
||||||
|
"command -v nc >/dev/null 2>&1 && nc -z 127.0.0.1 ${TUNNEL_PORT}"; then
|
||||||
|
echo "⚠️ Port ${TUNNEL_PORT} on remote 127.0.0.1 appears in use; choose another with -p." >&2
|
||||||
|
# Uncomment the next line to make it a hard failure:
|
||||||
|
# exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bind reverse to 127.0.0.1 on the REMOTE host (private-by-default).
|
||||||
|
# Keepalive so the tunnel drops on dead links.
|
||||||
|
# Exit fast if the reverse bind fails (e.g., port in use).
|
||||||
timeout "$DURATION" ssh -N \
|
timeout "$DURATION" ssh -N \
|
||||||
|
-o ExitOnForwardFailure=yes \
|
||||||
|
-o ServerAliveInterval=15 \
|
||||||
|
-o ServerAliveCountMax=3 \
|
||||||
-R "${TUNNEL_PORT}:localhost:${LOCAL_SSH_PORT}" \
|
-R "${TUNNEL_PORT}:localhost:${LOCAL_SSH_PORT}" \
|
||||||
-- "${REMOTE_USER}@${REMOTE_HOST}"
|
-- "${REMOTE_USER}@${REMOTE_HOST}"
|
||||||
|
|
||||||
|
|||||||
@@ -44,4 +44,12 @@ if [[ -d /usr/share/applications ]]; then
|
|||||||
sudo install -m 0644 desktop/backtunnel.desktop /usr/share/applications/backtunnel.desktop || true
|
sudo install -m 0644 desktop/backtunnel.desktop /usr/share/applications/backtunnel.desktop || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Refresh desktop DB and KDE service cache (best-effort)
|
||||||
|
command -v update-desktop-database >/dev/null 2>&1 && sudo update-desktop-database -q || true
|
||||||
|
if command -v kbuildsycoca6 >/dev/null 2>&1; then
|
||||||
|
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
|
||||||
|
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
|
||||||
|
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo "✅ BackTunnel installed. You may need to restart your shell and Dolphin."
|
echo "✅ BackTunnel installed. You may need to restart your shell and Dolphin."
|
||||||
|
|||||||
@@ -39,4 +39,12 @@ sudo rm -f /usr/share/kservices5/ServiceMenus/backtunnel_access.desktop || true
|
|||||||
echo "🧹 Removing desktop launcher ..."
|
echo "🧹 Removing desktop launcher ..."
|
||||||
sudo rm -f /usr/share/applications/backtunnel.desktop || true
|
sudo rm -f /usr/share/applications/backtunnel.desktop || true
|
||||||
|
|
||||||
|
# Refresh desktop DB and KDE service cache (best-effort)
|
||||||
|
command -v update-desktop-database >/dev/null 2>&1 && sudo update-desktop-database -q || true
|
||||||
|
if command -v kbuildsycoca6 >/dev/null 2>&1; then
|
||||||
|
kbuildsycoca6 --noincremental >/dev/null 2>&1 || true
|
||||||
|
elif command -v kbuildsycoca5 >/dev/null 2>&1; then
|
||||||
|
kbuildsycoca5 --noincremental >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
echo "✅ Uninstall complete."
|
echo "✅ Uninstall complete."
|
||||||
|
|||||||
Reference in New Issue
Block a user