reverse-ssh
A Rust library for creating reverse SSH tunnels using the russh crate.
What is Reverse SSH?
Reverse SSH (also called remote port forwarding) allows you to:
- Make a service behind a firewall/NAT accessible from outside
- Connect from a restricted network to an external SSH server
- Have the SSH server forward connections back to your local service
This is particularly useful for:
- Accessing services on machines behind NAT
- Bypassing firewall restrictions
- Remote debugging and development
- IoT device management
How It Works
Internet -> SSH Server:8080 -> [SSH Tunnel] -> Your Local Service:3000
- Your local client connects to an SSH server
- Client requests the SSH server to listen on a port (e.g., 8080)
- When someone connects to the SSH server's port 8080, the connection is forwarded through the SSH tunnel
- Your client receives the connection and proxies it to a local service (e.g., localhost:3000)
Quick Start
The fastest way to try reverse SSH tunneling:
# 1. Clone and build
# 2. Start the test server
# 3. In another terminal, test with localhost.run
That's it! You'll get a public URL that forwards to your local server.
Installation
Add this to your Cargo.toml:
[]
= "0.1.0"
Usage
Basic Example
use ;
async
Configuration Options
server_addr: SSH server hostname or IPserver_port: SSH server port (usually 22)username: SSH usernamekey_path: Path to private key (for key-based auth)password: Password (for password-based auth)remote_port: Port on SSH server to listen onlocal_addr: Local address to forward to (usually 127.0.0.1)local_port: Local port to forward to
Authentication
You can use either key-based or password authentication:
// Key-based authentication
let config = ReverseSshConfig ;
// Password authentication
let config = ReverseSshConfig ;
SSH Server Configuration
For reverse port forwarding to work, your SSH server must allow it. Add this to /etc/ssh/sshd_config:
GatewayPorts yes
AllowTcpForwarding yes
Then restart the SSH service:
Examples
This library includes several examples to help you get started:
1. Simple Test Server
Start a local HTTP server to test your tunnel:
This runs a web server on localhost:8080 that displays connection information. Perfect for testing!
2. localhost.run Integration
Expose your local service to the internet using localhost.run:
# First, start the test server
# In another terminal, create the tunnel (default: port 8080, ~/.ssh/id_rsa)
# Or specify custom SSH key and port
# Or use environment variables
SSH_KEY=/.ssh/my_key LOCAL_PORT=3000
# See all options
Command-line Options:
--key, -k <path>- Path to SSH private key (default:~/.ssh/id_rsa)--port, -p <port>- Local port to forward (default:8080)--help, -h- Show help message
Environment Variables:
SSH_KEY- Path to SSH private keyLOCAL_PORT- Local port to forward
localhost.run is a free SSH tunneling service (similar to ngrok) that requires no registration.
How it works:
Internet SSH Tunnel Your Machine
↓ ↓ ↓
http://xxx.localhost.run → ssh.localhost.run:22 → localhost:8080
Automatic Features:
- SSH Key Generation - The example will automatically detect if you don't have an SSH key and offer to generate one:
⚠ SSH key not found: /home/user/.ssh/id_rsa
Would you like to generate a new SSH keypair?
This will create /home/user/.ssh/id_rsa and /home/user/.ssh/id_rsa.pub [Y/n]:
Just press Enter or type 'Y' to generate a keypair automatically.
- URL Capture & Display - The tunnel URL is automatically captured from the server and displayed prominently:
How it works:
- Captures messages from both stdout and stderr
- Opens a shell session to receive welcome messages
- Automatically extracts URLs from server messages
- Displays all server messages with emoji indicators:
- 🔗 Messages containing URLs
- ⚠️ Error or warning messages
- 📨 Regular informational messages
╔══════════════════════════════════════════════════════╗
║ 🌐 TUNNEL ACTIVE 🌐 ║
╠══════════════════════════════════════════════════════╣
║ Your local service is now accessible at: ║
║ ║
║ https://abc123def456.localhost.run ║
║ ║
║ Local: http://127.0.0.1:8080 ║
║ Connected in: 2s ║
╚══════════════════════════════════════════════════════╝
The example automatically parses server messages to extract and display your public URL!
Alternative: You can also use the traditional SSH command for comparison:
3. Local Testing with Your Own Server
Test with your own SSH server:
This example:
- Starts a built-in HTTP server on port 8080
- Connects to your SSH server
- Sets up reverse forwarding from port 9999 to localhost:8080
- Access it at:
http://your-server.com:9999
4. Basic Example
Minimal example showing the library usage:
# Edit examples/basic.rs with your SSH server details
Use Cases
- Web Development: Expose a local web server for testing
- Remote Access: Access a service behind a firewall
- IoT Devices: Allow devices behind NAT to be accessible
- CI/CD: Connect build agents in restricted networks
Security Considerations
- Always use key-based authentication in production
- Verify SSH server public keys (currently accepts any key - update for production)
- Use strong passwords if using password authentication
- Consider using a dedicated SSH server for tunneling
- Monitor and log all connections
- Implement rate limiting if needed
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.