Repository navigation
TestingBot Tunnel 5.0 is a major release: a move to Jetty 12 and Java 17, self-contained downloads that need no Java at all, and a set of controls over what the tunnel may reach and how it gets there.
Upgrading from 4.x? Existing command lines keep working, but read Upgrading from 4.x first -- a few defaults changed.
Breaking changes
- Requires Java 17 (was 11). On an older Java the tunnel now says so, instead of failing with "A JNI error has occurred". Or use one of the self-contained downloads below.
- Local listeners bind
127.0.0.1, not every interface: the Selenium relay (--se-port), the local proxy (--localproxy), the metrics port and--web. None of them authenticates, and the relay attaches your account key and secret to everything it forwards. Use--bind-address 0.0.0.0to accept connections from other machines. The Docker image already sets this. - Successful requests no longer log a line.
--log-httpdefaults toerrors;--log-http urlrestores a line per request. The Selenium relay now honours--log-httptoo. /readyzreports ready only after the startup self-test passes, so a half-working tunnel that used to look healthy now returns 503 until it is.
Downloads
| Platform | File |
|---|---|
| Any OS with Java 17+ | TestingBotTunnel-5.0.jar |
| Linux x64 / arm64 | testingbot-tunnel-linux-x64.tar.gz, testingbot-tunnel-linux-arm64.tar.gz |
| macOS Intel / Apple silicon | testingbot-tunnel-macos-x64.tar.gz, testingbot-tunnel-macos-arm64.tar.gz (signed and notarized) |
| Windows x64 | testingbot-tunnel-windows-x64.zip |
The platform archives bundle a trimmed Java runtime, so nothing needs to be installed. Every file has a .sha256 next to it.
- Docker:
docker run -e TESTINGBOT_KEY=... -e TESTINGBOT_SECRET=... testingbot/tunnel:5.0 - Maven Central:
com.testingbot:TestingBotTunnel:5.0
Highlights
Restricting what the tunnel can reach
--allow-hosts: name what the tunnel is for and refuse everything else (*.suffixfor subdomains)--fast-fail-regexpsexceptions with!, e.g..*,!ok\.com--localhost-policy deny: refuse traffic to this machine's loopback, checked on the address actually dialled- All three are enforced on plain HTTP, CONNECT and WebSocket upgrades
Corporate networks and upstream proxies
--pac-local: choose egress per destination from a PAC file, evaluated by a purpose-built restricted interpreter;--pac-testchecks one URL--proxy-auth-scheme negotiate: Kerberos/SPNEGO to the upstream proxy;--krb5-hostsfor intranet sites that use Kerberos--proxy-testingbot: a separate proxy for reaching TestingBot itself--cacert-file: trust an extra CA, for TLS-intercepting proxies- SOCKS5 upstream proxies,
--connect-to,--ws-proxy-mode, multi-server--dns,--http-dial-timeout/--http-idle-timeout
Security
--ssh-host-key/--ssh-host-key-policy require: pin the tunnel server's SSH host key- Upstream proxy credentials are only ever sent to the proxy they were issued for
- Credentials and credential-shaped query values are redacted from logs
Operations and observability
/healthzand/readyzon the metrics port, and--readyfor health checks; the Docker image has aHEALTHCHECK--log-httpper module (proxy:,forwarder:),--log-format json, request-id correlation--configfile, and aTESTINGBOT_*environment alias for every option--header/--response-headerto edit headers on plain HTTP;--nobump-domains- Much more resilient reconnects, and
--doctordiagnoses the configuration actually given
Embedding
- The tunnel runs as a library:
boot(),awaitReady(Duration),stop(). It never exits the JVM and releases everything on stop
Full list: CHANGELOG.