2025-09-20 10:58:02 +02:00
|
|
|
|
# BackTunnel – Secure Reverse SSH Folder Sharing Toolkit
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
**BackTunnel** is a lightweight toolkit to share and mount folders between Linux machines behind NAT or firewalls using **reverse SSH tunnels**.
|
|
|
|
|
|
No third-party relay, no cloud dependency – just peer-to-peer, temporary, SSH-based access.
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
---
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
## ⚡ Quick Start
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
### 1. Accessor: Prepare your key (one-time)
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-keys print
|
|
|
|
|
|
```
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
Send the printed public key to the sharer.
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
### 2. Sharer: Start sharing and authorize the accessor
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-share ~/Documents with alice@remotehost for 2h -i --allow-key ./alice.pub
|
|
|
|
|
|
```
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
This injects a **temporary, restricted SFTP-only key** and prints an invite.
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
### 3. Accessor: Mount the shared folder
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-access '/home/sharer/Documents' from alice@remotehost -p 2222 -m ~/remote-rssh
|
|
|
|
|
|
```
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
Unmount with:
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-14 11:29:21 +02:00
|
|
|
|
```bash
|
2025-09-21 18:56:15 +02:00
|
|
|
|
backtunnel-umount ~/remote-rssh
|
2025-09-14 11:29:21 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-09-14 12:54:06 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
## ✨ Features
|
2025-09-14 19:44:37 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
- **NAT/firewall friendly**: works without port forwarding.
|
|
|
|
|
|
- **Temporary by design**: shares auto-expire after a set duration.
|
|
|
|
|
|
- **Invite workflow**: sharer sends a one-liner or QR code to accessor.
|
2025-09-21 18:56:15 +02:00
|
|
|
|
- **Restricted keys**: accessor keys are usable only for SFTP via the reverse tunnel and can be auto-added for the session.
|
|
|
|
|
|
- **Profiles**: save defaults and common remotes in profiles.ini.
|
|
|
|
|
|
- **Host key policy**: configurable StrictHostKeyChecking via BACKTUNNEL_HOSTKEY_POLICY.
|
|
|
|
|
|
- **Desktop integration**: Dolphin (KDE) service menus for GUI/TUI sharing and access.
|
|
|
|
|
|
- **Convenient TUIs/GUI**: guided prompts for sharer/accessor; terminal opener detects installed terminals.
|
|
|
|
|
|
- **Bash completion**: contextual completion for both CLI commands and TUIs.
|
|
|
|
|
|
- **Logs with rotation**: servicemenu invocations write logs and keep the last 10 entries.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🧠 Roles and Flow
|
|
|
|
|
|
|
|
|
|
|
|
- Sharer: exposes a local SSH service back to a remote host for a limited time. Runs backtunnel-share.
|
|
|
|
|
|
- Accessor: connects to the sharer via the remote host’s `127.0.0.1:PORT` and mounts a folder with sshfs. Runs backtunnel-access.
|
|
|
|
|
|
- Reverse tunnel: the sharer’s ssh -R binds `127.0.0.1:PORT` on the remote host and forwards back to the sharer’s sshd.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ✅ Requirements
|
|
|
|
|
|
|
|
|
|
|
|
- Linux with Bash
|
|
|
|
|
|
- OpenSSH client (ssh, sftp)
|
|
|
|
|
|
- sshfs (FUSE) on the accessor machine
|
|
|
|
|
|
- Optional:
|
|
|
|
|
|
- qrencode (for QR code invites)
|
|
|
|
|
|
- A terminal emulator for service menu helpers (e.g., konsole, gnome-terminal, wezterm, kitty, etc.)
|
2025-09-14 19:44:37 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
## 🔑 Commands
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
### Sharer side
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-share
|
|
|
|
|
|
- Start a time-bounded reverse SSH tunnel and optionally print an invite.
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-share /path/to/folder with user@host for <duration> [options]
|
|
|
|
|
|
```
|
|
|
|
|
|
- Duration: 10m, 30m, 1h, 2h, 6h, 12h, 1d, 2d (single unit e.g., 30m, 2h, 1d)
|
|
|
|
|
|
- Options:
|
|
|
|
|
|
- -p, --tunnel-port N: Remote bind port (default: 2222)
|
|
|
|
|
|
- -l, --local-ssh-port N: Local sshd port to forward to (default: 22)
|
|
|
|
|
|
- -i, --invite: Print a one-liner invite for the accessor
|
|
|
|
|
|
- --invite-mount PATH: Suggested mount point in the invite (default: $HOME/remote-rssh)
|
|
|
|
|
|
- --invite-file FILE: Save the invite text (with unmount hint) to a file
|
|
|
|
|
|
- --qr: Also show a QR code for the invite (requires qrencode)
|
|
|
|
|
|
- --allow-key FILE: Temporarily authorize an accessor public key for this session
|
|
|
|
|
|
- --allow-known NAME: Authorize a stored key (~/.config/backtunnel/authorized/NAME.pub)
|
|
|
|
|
|
- -h, --help: Show usage
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-share-tui
|
|
|
|
|
|
- Minimal TUI wrapper prompting for remote, duration, ports, and invite options, then runs backtunnel-share.
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-share-tui <folder>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-authorize
|
|
|
|
|
|
- Store a named accessor public key for --allow-known usage.
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-authorize <name> <pubkey-file>
|
|
|
|
|
|
```
|
|
|
|
|
|
- Stores at: `${XDG_CONFIG_HOME:-$HOME/.config}/backtunnel/authorized/<name>.pub`
|
|
|
|
|
|
|
|
|
|
|
|
### Accessor side
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-access
|
|
|
|
|
|
- Mount a folder over SFTP via the reverse tunnel’s `127.0.0.1:PORT`.
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-access /remote/folder from user@host [-p PORT] [-m MOUNTPOINT]
|
|
|
|
|
|
```
|
|
|
|
|
|
- Options:
|
|
|
|
|
|
- -p, --port N: Tunnel port on the remote host (default: 2222)
|
|
|
|
|
|
- -m, --mount-point PATH: Local mount point (default: $HOME/remote-rssh)
|
|
|
|
|
|
- -h, --help: Show usage
|
|
|
|
|
|
- Behavior:
|
|
|
|
|
|
- Checks mount point readiness and warns if not empty.
|
|
|
|
|
|
- Tries passwordless auth via a dedicated identity if present (~/.ssh/id_ed25519_backtunnel).
|
|
|
|
|
|
- Performs a quick SFTP visibility check of the target folder.
|
|
|
|
|
|
- Mounts with reconnect/keepalives.
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-access-tui
|
|
|
|
|
|
- Minimal TUI wrapper prompting for remote, tunnel port, remote folder, and mount point.
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-access-tui <selected-dir>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-keys
|
|
|
|
|
|
- Manage the accessor-side dedicated key pair (~/.ssh/id_ed25519_backtunnel).
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-keys print # emit public key (generate if missing)
|
|
|
|
|
|
backtunnel-keys path # show key paths
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-auth-setup
|
|
|
|
|
|
- Initialize a tunnel-only, SFTP-only authorized_keys entry on the remote (via the tunnel).
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-auth-setup [-p PORT] user@localhost
|
|
|
|
|
|
```
|
|
|
|
|
|
- Installs a restricted entry:
|
|
|
|
|
|
from="127.0.0.1",command="internal-sftp",restrict <pubkey>
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-umount
|
|
|
|
|
|
- Portable unmount helper (prefers fusermount3, then fusermount, then umount).
|
|
|
|
|
|
- Syntax:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-umount <mountpoint>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- backtunnel-open-term
|
|
|
|
|
|
- Launch a command in an available terminal emulator; logs output with simple rotation.
|
|
|
|
|
|
- Automatically detects terminals (prefers konsole on KDE; supports wezterm, kitty, alacritty, gnome-terminal, kgx, tilix, xfce4-terminal, xterm).
|
|
|
|
|
|
- Used by service menus/GUI wrappers.
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
## 🔒 Security Model
|
|
|
|
|
|
|
|
|
|
|
|
- Reverse tunnel bind: remote side binds on `127.0.0.1:PORT` (loopback only).
|
|
|
|
|
|
- Access is SFTP-based:
|
|
|
|
|
|
- Invite flow can be paired with a restricted authorized_keys entry:
|
|
|
|
|
|
- from="127.0.0.1",command="internal-sftp",restrict
|
|
|
|
|
|
- This limits usage to SFTP over the reverse tunnel only; no shell or port forwarding.
|
|
|
|
|
|
- Temporary authorization:
|
|
|
|
|
|
- Sharer can temporarily add an accessor public key for the session; it’s removed on exit.
|
|
|
|
|
|
- Host key policy:
|
|
|
|
|
|
- Controlled via the environment variable BACKTUNNEL_HOSTKEY_POLICY with values:
|
|
|
|
|
|
- accept-new (default), yes, no, ask
|
|
|
|
|
|
- Applied to ssh, sftp, and the ssh command used by sshfs.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🧩 Profiles
|
|
|
|
|
|
|
|
|
|
|
|
- Config locations (higher precedence first):
|
|
|
|
|
|
- `${XDG_CONFIG_HOME:-$HOME/.config}/backtunnel/profiles.ini`
|
|
|
|
|
|
- /etc/backtunnel/profiles.ini
|
|
|
|
|
|
- /usr/share/backtunnel/profiles.ini
|
|
|
|
|
|
- Example:
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```ini
|
|
|
|
|
|
[default]
|
2025-09-20 17:17:26 +02:00
|
|
|
|
tunnel_port=2222
|
2025-09-21 18:56:15 +02:00
|
|
|
|
local_ssh_port=22
|
2025-09-20 17:17:26 +02:00
|
|
|
|
invite_mount=$HOME/remote-rssh
|
2025-09-21 18:56:15 +02:00
|
|
|
|
invite=true
|
|
|
|
|
|
qr=false
|
2025-09-20 10:58:02 +02:00
|
|
|
|
|
|
|
|
|
|
[work]
|
|
|
|
|
|
user=alice
|
|
|
|
|
|
host=vps.example.com
|
2025-09-20 17:17:26 +02:00
|
|
|
|
tunnel_port=4422
|
2025-09-14 22:02:48 +02:00
|
|
|
|
```
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
|
|
|
|
|
- Usage with @profile:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-share ~/reports with @work for 6h -i --allow-known alice
|
|
|
|
|
|
```
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
---
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
## 🧭 Bash Completion
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
- Source completions/backtunnel.bash or install it via your system’s completion.d directory.
|
|
|
|
|
|
- Provides:
|
|
|
|
|
|
- Keyword scaffolding (with/from/for)
|
|
|
|
|
|
- @profile expansion
|
|
|
|
|
|
- Suggestions for durations and ports
|
|
|
|
|
|
- Key name/file completion for --allow-known/--allow-key
|
|
|
|
|
|
- Path completion for the first positional and mount path options
|
|
|
|
|
|
- Includes minimal completion for TUIs (first positional directory).
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🖥️ Desktop Integration (KDE Dolphin)
|
|
|
|
|
|
|
|
|
|
|
|
- Right-click in a folder:
|
|
|
|
|
|
- “Share via BackTunnel…” → opens a GUI/TUI flow for the sharer.
|
|
|
|
|
|
- “Access via BackTunnel (mount here)…” → opens a GUI/TUI flow for the accessor.
|
|
|
|
|
|
- Logs:
|
|
|
|
|
|
```
|
|
|
|
|
|
~/.local/state/backtunnel/servicemenu.*.log
|
|
|
|
|
|
```
|
|
|
|
|
|
The launcher keeps the last 10 logs (simple rotation).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🌐 Environment Variables
|
|
|
|
|
|
|
|
|
|
|
|
- BACKTUNNEL_HOSTKEY_POLICY
|
|
|
|
|
|
- Controls StrictHostKeyChecking for ssh/sftp/sshfs:
|
|
|
|
|
|
- Values: accept-new (default), yes, no, ask
|
|
|
|
|
|
- Example:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
BACKTUNNEL_HOSTKEY_POLICY=strict # alias for 'yes' in many contexts
|
|
|
|
|
|
BACKTUNNEL_HOSTKEY_POLICY=accept-new
|
|
|
|
|
|
```
|
2025-09-14 22:02:48 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
## 🛠️ Installation
|
2025-09-14 11:29:21 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
### From source
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```bash
|
|
|
|
|
|
sudo bash scripts/install.sh
|
|
|
|
|
|
make init # copy example profiles.ini
|
|
|
|
|
|
```
|
2025-09-19 15:30:41 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
### Arch Linux
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```bash
|
2025-09-20 17:17:26 +02:00
|
|
|
|
makepkg -si
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```
|
2025-09-19 15:30:41 +02:00
|
|
|
|
|
2025-09-20 17:17:26 +02:00
|
|
|
|
Uninstall:
|
2025-09-21 18:56:15 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```bash
|
2025-09-20 17:17:26 +02:00
|
|
|
|
sudo bash scripts/uninstall.sh
|
|
|
|
|
|
# or with purge of defaults
|
|
|
|
|
|
sudo PURGE=1 bash scripts/uninstall.sh
|
2025-09-20 10:58:02 +02:00
|
|
|
|
```
|
2025-09-14 14:34:46 +02:00
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
---
|
2025-09-14 14:34:46 +02:00
|
|
|
|
|
2025-09-21 18:56:15 +02:00
|
|
|
|
## 🔍 Troubleshooting
|
|
|
|
|
|
|
|
|
|
|
|
- Port already in use on remote:
|
|
|
|
|
|
- backtunnel-share warns if `127.0.0.1:PORT` is busy; choose another with -p.
|
|
|
|
|
|
- Missing sshfs:
|
|
|
|
|
|
- Install sshfs on the accessor machine; ensure FUSE is available.
|
|
|
|
|
|
- SFTP path is not listable:
|
|
|
|
|
|
- backtunnel-access warns if SFTP cannot list the path. Verify folder existence and permissions.
|
|
|
|
|
|
- Passwordless auth isn't set:
|
|
|
|
|
|
- Try:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-auth-setup -p <PORT> <user>@localhost
|
|
|
|
|
|
```
|
|
|
|
|
|
- Unmount fails:
|
|
|
|
|
|
- Use the portable helper:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
backtunnel-umount <mountpoint>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 🧪 Testing
|
|
|
|
|
|
|
|
|
|
|
|
- Bats scaffolds are provided to extend:
|
|
|
|
|
|
- tests/test-umount.bats
|
|
|
|
|
|
- tests/test-hostkey-policy.bats
|
|
|
|
|
|
|
|
|
|
|
|
Run tests (example):
|
|
|
|
|
|
|
2025-09-14 14:34:46 +02:00
|
|
|
|
```bash
|
2025-09-21 18:56:15 +02:00
|
|
|
|
bats tests
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 📖 Man Page
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2025-09-20 10:58:02 +02:00
|
|
|
|
man backtunnel
|
2025-09-14 14:34:46 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-09-14 12:54:06 +02:00
|
|
|
|
---
|
|
|
|
|
|
|
2025-09-20 10:58:02 +02:00
|
|
|
|
## 🧾 License
|
2025-09-20 17:17:26 +02:00
|
|
|
|
GNU GPL v3.0
|
2025-09-20 10:58:02 +02:00
|
|
|
|
© 2025 LUXIM d.o.o., Slovenia – Matjaž Mozetič
|