@emdzej/stm-tunnel
v0.3.0
Published
WebSocket bridge for the STM web serial monitor — exposes a serial port (or a PTY-hosted command) to a browser.
Readme
@emdzej/stm-tunnel
Small Node CLI that bridges a local serial port to a WebSocket, so browsers without Web Serial (Firefox, Safari, iOS) can talk to the STM web app.
stm-tunnel --port /dev/ttyUSB0 --baud 115200
STM_TUNNEL_TOKEN=<secret> stm-tunnel --port COM3 --listen 0.0.0.0:8787 --allowed-origin https://stm.example.com
stm-tunnel --port /dev/ttyACM0 --tls-cert cert.pem --tls-key key.pem
stm-tunnel --exec "bash -i" --clean-envOne port per process.
Security model
- A token is always required. If you don't give one (
--tokenor theSTM_TUNNEL_TOKENenv var), a random token is generated and printed at startup. The web client sends it in theSec-WebSocket-Protocolheader, so it never appears in URLs or access logs. - Origin allowlist. Browser connections are only accepted from
https://stm.emdzej.plandhttp://localhost:*/127.0.0.1:*/[::1]:*. Browsers don't apply CORS to WebSockets, so without this any website you had open could reach the tunnel.--allowed-originreplaces the list and can be repeated;scheme://host:*matches any port,*matches anything. Clients that send noOriginheader (non-browser tools) are allowed. --no-authis only accepted for loopback binds in--portmode.--execgives a shell to whoever connects. It always needs a token; add--clean-envso the child doesn't inherit your credentials.- Binding a non-loopback address without TLS prints a warning: the token travels in cleartext.
- One client at a time. Inbound frames are capped at 1 MiB, the device is paused while the client falls behind (backpressure), and clients that miss a 30 s heartbeat are dropped.
