Build your own tunnel in Rust: Expose local sites to the Web with blazing performance
These articles are AI-generated summaries. Please check the original sources for full details.
Build your own tunnel in Rust: Expose local sites to the Web with blazing performance
Tauri applications leverage Cloudflare’s cloudflared to create outbound tunnels, bypassing inbound firewall restrictions. The tool uses QUIC for low-latency connections, falling back to HTTP/2 if needed.
Why This Matters
Traditional inbound firewall rules block external access to local services, requiring complex port forwarding. This approach eliminates that barrier by using outbound-only connections. However, improper process management can leave orphaned cloudflared instances, consuming system resources and exposing unintended services.
Key Insights
- “QUIC protocol (UDP) with HTTP/2 fallback for reliability”: Cloudflare docs
- “Sidecar pattern for external binaries”: Tauri documentation
- “cloudflared used by Spot Serve GUI”: GitHub repo
Working Example
{
"tauri": {
"bundle": {
"externalBin": ["binaries/cloudflared"]
},
"allowlist": {
"shell": {
"all": false,
"execute": true,
"sidecar": true
}
}
}
}
use std::sync::Mutex;
use tauri::command;
use tauri::api::process::{Command, CommandEvent};
pub struct TunnelState {
pub child_process: Mutex<Option<tauri::api::process::CommandChild>>,
}
impl Default for TunnelState {
fn default() -> Self {
Self {
child_process: Mutex::new(None),
}
}
}
#[command]
pub fn start_tunnel(
app_handle: tauri::AppHandle,
port: u16,
state: tauri::State<TunnelState>,
) -> Result<(), String> {
let mut state_guard = state.child_process.lock().map_err(|_| "Failed to lock state")?;
if state_guard.is_some() {
return Err("Tunnel is already running".into());
}
let (mut rx, child) = Command::new_sidecar("cloudflared")
.map_err(|e| format!("Failed to create sidecar command: {}", e))?
.args(&["tunnel", "--url", &format!("http://localhost:{}", port)])
.spawn()
.map_err(|e| format!("Failed to spawn sidecar: {}", e))?;
*state_guard = Some(child);
tauri::async_runtime::spawn(async move {
let url_regex = regex::Regex::new(r"https://[a-zA-Z0-9-]+\.trycloudflare\.com").unwrap();
while let Some(event) = rx.recv().await {
match event {
CommandEvent::Stderr(line) | CommandEvent::Stdout(line) => {
println!("[cloudflared]: {}", line);
if let Some(mat) = url_regex.find(&line) {
let public_url = mat.as_str().to_string();
app_handle.emit_all("tunnel-url", public_url).unwrap();
}
}
CommandEvent::Terminated(_) => break,
_ => {}
}
}
});
Ok(())
}
Practical Applications
- Use Case: Exposing local development servers to the internet for collaboration
- Pitfall: Forgetting to terminate
cloudflaredprocesses causes memory leaks and potential security exposure
References:
- https://dev.to/explicit-logic/build-your-own-tunnel-in-rust-expose-local-sites-to-the-web-with-blazing-performance-1218
- https://github.com/explicit-logic/spot-serve-gui
Continue reading
Next article
From determinants to hill climbing algorithms—how I turned academic math into an interactive learning platform
Related Content
How Cloudflare’s tokio-quiche Makes QUIC and HTTP/3 a First Class Citizen in Rust Backends
Cloudflare’s tokio-quiche library enables efficient HTTP/3 implementation in Rust, handling millions of requests per second in production environments.
Amnosia: A Rust-Based CLI for Terminal-Integrated Task Management
Gennaro Biondi develops Amnosia, a Rust CLI tool that automates task visibility by integrating directly into the terminal shell startup.
Your Deployments Are Stuck in the Past: The Lost Art of the Hot Restart
Rediscovering zero-downtime deployments through internalized service management with the Hyperlane Rust framework, eliminating reliance on external tools.