a tunneling solution built with go
expose local services to the internet through websocket connections
perfect for development, testing, and demonstration purposes
β οΈ disclaimer: this tunneling solution is intended for development and testing purposes. while functional, it may not include all security features required for production environments. use at your own discretion and implement additional security measures as needed for production deployments.
one line install script:
curl -sSfL https://raw.githubusercontent.com/karol-broda/funnel/master/scripts/install.sh | bashπ¦ installation options
the recommended way to install funnel is with the installer script. it automatically detects your platform, downloads the correct binary, and installs it on your system.
by default, the script installs funnel to $HOME/.local/bin. this is the recommended method as it does not require sudo.
the script provides several flags to customize the installation:
-
global install: use the
--globalflag to installfunnelto/usr/local/bin, making it available to all users. this requiressudo.curl -sSfL https://.../install.sh | bash -s -- --global -
custom directory: use
-bor--bin-dirto specify a custom installation directory.curl -sSfL https://.../install.sh | bash -s -- -b /path/to/your/bin -
specific version: use
-vto install a specific version offunnel.curl -sSfL https://.../install.sh | bash -s -- -v v0.0.4 -
list versions: use
-lto see a list of available versions.curl -sSfL https://.../install.sh | bash -s -- -l
π¨ building from source
git clone https://github.com/karol-broda/funnel.git
cd funnel
make dev-setup
make buildβ‘ basic usage
-
start the server:
./bin/funnel-server # or: ./bin/funnel-server -port 9000 -
connect your local service:
funnel http 3000 --server http://localhost:8080 # or with custom id: funnel http 3000 --server http://localhost:8080 --id my-tunnel -
access your service:
curl http://your-tunnel-id.localhost:8080
π― complete example
# terminal 1: start a local service
python3 -m http.server 3000
# terminal 2: start funnel server
make run-server
# terminal 3: connect funnel client
funnel http 3000 --server http://localhost:8080 --id demo
# terminal 4: test the tunnel
curl http://demo.localhost:8080graph LR
A["local app<br/>:3000"] --> B["funnel client"]
B -.websocket.-> C["funnel server<br/>:8080"]
D["browser/curl"] --> E["tunnel-id.localhost:8080"]
E --> C
C -.-> B
B --> A
style A fill:#b7bdf8,color:#24273a
style B fill:#f5bde6,color:#24273a
style C fill:#8bd5ca,color:#24273a
style D fill:#a6da95,color:#24273a
style E fill:#91d7e3,color:#24273a
- funnel client: connects to server via websocket, forwards requests to local app
- funnel server: accepts websocket connections, routes external http requests to clients
- local app: your application running locally (e.g., web server, api)
- requests to
tunnel-id.server:portget routed through websocket to your local app
# start server (default port 8080)
./bin/funnel-server
# specify custom port
./bin/funnel-server -port 9000
# show version info
./bin/funnel-server version# tunnel using port only (connects to localhost:PORT)
funnel http 3000 --server http://localhost:8080
# tunnel using full address
funnel http localhost:3000 --server http://localhost:8080
funnel http 0.0.0.0:8080 --server http://localhost:8080
# use custom tunnel id
funnel http 3000 --server http://localhost:8080 --id my-custom-tunnel
# show version info
funnel versionuse funnel-server --help and funnel --help for current options
π¨ building
# build both client and server
make build
# build individual components
make build-client
make build-server
# show available commands
make helpπ§ͺ testing
# run all tests
make test
# verbose test output
make test-verbose
# test with coverage
make test-coverage
# test with race detection
make test-raceπ¦ dependency management
# fix go.mod files and ide errors
make tidy
# complete dependency setup (fresh install)
make deps-install
# show all modules
make list-modulesmake tidy- quick dependency cleanup, fixes ide linting errorsmake deps-install- complete setup for fresh installations, downloads everything- use
tidyfor regular maintenance,deps-installfor first-time setup
π release process
# create release binaries for all platforms
make release
# platforms: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64
# output: dist/ directoryπ§Ή maintenance
# format code
make fmt
# run linter
make lint
# clean build artifacts
make clean
# show version info
make version- client establishes websocket connection to
/wsendpoint with tunnel id - server creates subdomain routing (
tunnel-id.server:port) - http requests to subdomain are proxied through websocket to client
- client forwards requests to local app and returns responses
- 3-63 characters long
- lowercase letters, numbers, and hyphens only
- cannot start or end with hyphen
- auto-generated ids use domain-safe alphabet
- β http tunneling - expose local web services through websocket tunnels
- β custom tunnel ids - use your own subdomain names or auto-generate them
- β auto-reconnection - clients automatically reconnect with exponential backoff
- β cross-platform support - builds for linux, macos, windows (amd64/arm64)
- β custom domains - works with any domain, not just localhost
- β server api - comprehensive rest api for tunnel management and monitoring
- β tunnel statistics - detailed metrics, historical data, and performance monitoring
- β openapi documentation - interactive api docs with swagger ui integration
- π client authentication - api key-based authentication for secure access
- π web dashboard - browser-based tunnel monitoring and control interface
- π client api - programmatic client control and configuration sdk
- π https by default - automatic tls for all tunnel endpoints
- π oauth integration - secure tunnels with tokens generated via oauth
- π tcp forwarding - tunnel any tcp service, not just http
- π multiple tunnels per client - run multiple services through single client
- β completed - ready to use
- π in progress - actively being developed
- π planned - scheduled for development
contributions welcome! please:
- fork the repository
- create feature branch:
git checkout -b feature/your-awesome-feature - set up development:
make dev-setup - make changes and test:
make build && make test - format and lint:
make fmt && make lint - commit changes:
git commit -m "description" - push and create pull request
licensed under the mit license