Port forwarding to remote devices (without opening firewall)
Port forwarding lets you access services on a remote device — a web UI, database, or debug port — as if they were running on your laptop. With m87, the device maintains a persistent QUIC connection (UDP port 443) to the make87 platform. You connect to localhost, and m87 handles the rest. No firewall changes. No NAT configuration.
When you want this
You're developing against an edge device and need to hit a service running on it: a web dashboard, a PostgreSQL instance, a debug server. Or the device sits on a LAN with other equipment — IP cameras, PLCs, sensors — and you need to reach those too. Port forwarding gives your local tools direct access without network changes.
How it works
Your browser, IDE, or any client connects to localhost:<port>. The m87 CLI on your laptop tunnels that connection through the device's outbound QUIC stream to the target service. Traffic flows over an already-established channel — no inbound ports on the device, no router configuration, no firewall rules.
Basic usage
Forward a single port
m87 <device> forward 8080
This forwards localhost:8080 on your laptop to port 8080 on the device.
Use a different local port
m87 <device> forward 3000:8080
This forwards localhost:3000 to port 8080 on the device.
Advanced usage
Forward multiple ports
m87 <device> forward 8080 9090 3000
Forward UDP instead of TCP
m87 <device> forward 8080/udp
Access a device on the edge device's LAN
If your edge device can reach another device on its local network:
m87 rpi forward 192.168.1.100:80
This forwards localhost:80 to 192.168.1.100:80 via the edge device — useful for accessing IP cameras, PLCs, or other equipment without direct connectivity.
Combine local port mapping with remote host
m87 rpi forward 8000:192.168.1.100:80
This forwards localhost:8000 to 192.168.1.100:80 via the edge device.
Use cases
Web UI access
Your device runs a web dashboard on port 3000:
m87 rpi forward 3000
# Open http://localhost:3000 in your browser
Database access
Your device runs PostgreSQL on port 5432:
m87 rpi forward 5432
# Connect with: psql -h localhost -p 5432
Debugger attachment
Your Python app runs a debug server on port 5678:
m87 rpi forward 5678
# In VS Code: attach to localhost:5678
IP camera or IoT device
A camera at 192.168.1.50:554 is on the device's network:
m87 rpi forward 8554:192.168.1.50:554
# Access RTSP stream at localhost:8554
ffplay -rtsp_transport tcp rtsp://localhost:8554/stream
How it differs from SSH tunnels
Port forwarding isn't new — what's different is the default assumption:
- No inbound access required: the device connects outbound
- No SSH key distribution: authentication happens through the make87 platform
- No bastion host: you don't maintain jump servers
- Works behind CGNAT: outbound UDP port 443 is the only requirement
Alternatives (and tradeoffs)
SSH tunnels
Pros:
- Standard protocol (RFC 4254) with broad client support across platforms
- Built-in on Linux/macOS; available via OpenSSH on Windows 10+
Cons:
- Requires port 22 open inbound or a bastion host with public IP
- Key management overhead: generation,
authorized_keysdistribution, rotation policies - CGNAT workarounds require a publicly reachable jump host or persistent reverse tunnel (e.g.,
autossh)
VPN (WireGuard / Tailscale)
Pros:
- Layer 3 access — device appears on a virtual subnet, enabling any IP-based protocol
- WireGuard: minimal attack surface (~4000 LOC), fast crypto (ChaCha20-Poly1305)
- Tailscale: NAT traversal via STUN with DERP relay fallback; peer-to-peer when UDP hole punching succeeds
Cons:
- Requires identity provider integration (Tailscale: SSO/OIDC) or manual key exchange (WireGuard)
- Devices remain network members until explicitly removed — no session-scoped access
- WireGuard at scale requires configuration management tooling; Tailscale requires control plane dependency (tailscale.com or self-hosted Headscale)
- Full subnet exposure increases attack surface vs. single-port forwarding
ngrok / cloudflared
Pros:
- Zero firewall config — outbound HTTPS only
- ngrok: instant public URLs for demos/webhooks
- cloudflared: integrates with Cloudflare Access for identity-aware tunnels
Cons:
- Traffic routes through third-party infrastructure (latency and data residency considerations)
- ngrok: TCP/UDP tunnels require paid tier; free limited to HTTP(S)
- cloudflared: requires Cloudflare account and DNS zone integration
- Per-tunnel or bandwidth pricing scales poorly for fleet deployments
FAQ
Do I need to open inbound ports on the device?
No. The device maintains an outbound QUIC connection; forwarded traffic is multiplexed over QUIC streams.
Does this work behind CGNAT?
Yes. Only outbound UDP port 443 is required — works with NAT, CGNAT, and most firewall configurations.
Can I forward multiple ports at once?
Yes. Pass multiple port specifications: m87 <device> forward 8080 9090 3000
Is the traffic encrypted?
Yes. All traffic is encrypted with TLS 1.3 over the QUIC connection.
Can I access other devices on the edge device's LAN?
Yes. Use the format m87 <device> forward [local:]<lan-ip>:<port> to reach devices on the edge device's local network.
Does this support UDP?
Yes. Append /udp to the port specification: m87 <device> forward 8080/udp