Client setup for tools and runtimes
Proxy and certificate settings you can paste for curl, Node, Python, Ruby, Go, Rust, Java, PHP, .NET, Docker, Electron, React Native and Flutter.
Apps that use the macOS system proxy are captured as soon as WireLens runs with the This Mac scope. Command line tools, language runtimes, containers and some frameworks ignore the system proxy, keep their own certificate store, or both. This page gets each of them into WireLens without ever turning certificate verification off.
Tools ▸ Client Setup in the app has every recipe below with the real paths for your Mac filled in. It lists the runtimes you have installed first, and it can open a shell with the variables already set (Open with env), launch Electron with the right switches, or run keytool for you.
The two values every client needs#
- Proxy:
http://127.0.0.1:9090, the default listener. Check Settings ▸ Capture if you changed the port. - Root certificate: your WireLens root as a PEM file, at
~/Library/Application Support/WireLens/ca/wirelens-root.pem.
The examples below use them through two shell variables:
export WL_PROXY=http://127.0.0.1:9090
export WL_CA="$HOME/Library/Application Support/WireLens/ca/wirelens-root.pem"
curl and HTTPie#
curl --proxy "$WL_PROXY" --cacert "$WL_CA" https://example.com
# HTTPie takes scheme:host:port for --proxy
http --proxy=http:"$WL_PROXY" --verify="$WL_CA" https://example.com
# or for the whole shell session
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY" CURL_CA_BUNDLE="$WL_CA"
Node.js#
export NODE_EXTRA_CA_CERTS="$WL_CA"
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY"
node app.js
NODE_EXTRA_CA_CERTS adds the WireLens root to Node's bundled store rather than replacing it. Node's own http and https modules ignore proxy variables; axios, got and node-fetch with an agent read them, and the built-in fetch (undici) needs a ProxyAgent.
Python#
export SSL_CERT_FILE="$WL_CA" REQUESTS_CA_BUNDLE="$WL_CA"
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY"
python3 app.py
requests reads REQUESTS_CA_BUNDLE; httpx, urllib and aiohttp read SSL_CERT_FILE.
Ruby#
export SSL_CERT_FILE="$WL_CA"
export https_proxy="$WL_PROXY" http_proxy="$WL_PROXY"
ruby app.rb
Go#
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY"
go run .
On macOS, Go verifies certificates against the keychain and ignores SSL_CERT_FILE, so trust the root in the keychain (Certificate ▸ Install for All Users… or wirelens cert install).
Rust#
export HTTPS_PROXY="$WL_PROXY" ALL_PROXY="$WL_PROXY" SSL_CERT_FILE="$WL_CA"
cargo run
SSL_CERT_FILE covers the OpenSSL and native-tls backends. With rustls, add the root explicitly, which also works everywhere else:
let pem = std::fs::read(ca_path)?;
let client = reqwest::Client::builder()
.proxy(reqwest::Proxy::all("http://127.0.0.1:9090")?)
.add_root_certificate(reqwest::Certificate::from_pem(&pem)?)
.build()?;
Java and the JVM#
The JVM keeps its own truststore. Import the root into a named truststore, not the JDK's cacerts in place, then point the JVM at it:
TS="$HOME/Library/Application Support/WireLens/java-truststore/cacerts"
mkdir -p "$(dirname "$TS")"
cp "$JAVA_HOME/lib/security/cacerts" "$TS"
keytool -importcert -noprompt -trustcacerts -alias wirelens \
-file "$WL_CA" -keystore "$TS" -storepass changeit
java -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=9090 \
-Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=9090 \
-Djavax.net.ssl.trustStore="$TS" \
-Djavax.net.ssl.trustStorePassword=changeit \
-jar your-app.jar
changeit is the JDK's stock truststore password, not a placeholder. Tools ▸ Client Setup ▸ Import CA with keytool runs the import for you.
PHP#
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY"
php -d curl.cainfo="$WL_CA" -d openssl.cafile="$WL_CA" your-script.php
PHP's OpenSSL does not use the macOS keychain. Set both options: file_get_contents reads openssl.cafile and ignores curl.cainfo. With Guzzle you can pass 'proxy' and 'verify' per client instead.
.NET#
export HTTPS_PROXY="$WL_PROXY" HTTP_PROXY="$WL_PROXY" NO_PROXY=localhost,127.0.0.1
dotnet run
On macOS, .NET validates against the system trust store, so trust the root in the keychain, like Go. In a Linux container it reads SSL_CERT_FILE instead. A handler that sets Proxy explicitly ignores the environment, so set one or the other.
Docker#
Inside a container, localhost is the container. Your Mac is host.docker.internal:
docker run --rm \
-e HTTPS_PROXY=http://host.docker.internal:9090 \
-e HTTP_PROXY=http://host.docker.internal:9090 \
-e NO_PROXY=localhost,127.0.0.1 \
-v "$WL_CA":/usr/local/share/ca-certificates/wirelens.crt:ro \
your-image sh -c "update-ca-certificates && your-command"
In Compose, add the same environment and volume, plus extra_hosts: ["host.docker.internal:host-gateway"] if you also run it on Linux. Alpine images need the ca-certificates package before update-ca-certificates exists.
Electron#
export NODE_EXTRA_CA_CERTS="$WL_CA"
electron . --proxy-server=127.0.0.1:9090
The main process is Node, so NODE_EXTRA_CA_CERTS covers it. Renderer traffic goes through Chromium, which takes --proxy-server and trusts roots from the keychain, so install the root there too. Tools ▸ Client Setup ▸ Launch Electron does both.
React Native and Flutter#
- iOS Simulator shares your Mac's network, so system capture already covers it. Install the root into the simulator:
xcrun simctl keychain booted add-root-cert "$WL_CA". - Android emulator: the host is
10.0.2.2, and app traffic on Android 7 and later needs a debug network security config. See Capture other devices. - Flutter: Dart's
HttpClientdoes not read proxy variables. SetfindProxytoPROXY 127.0.0.1:9090and add the root withSecurityContext.setTrustedCertificates, or install a debugHttpOverrides.global. Tools ▸ Client Setup ▸ Copy Dart override puts one on the pasteboard.
Proving it works#
Every recipe in the app comes with a one-line verify command. Run it and look for the request in the traffic list. If it succeeds but no row appears, the client went direct: the proxy variable was not read.
Something here is unclear, or wrong for your setup? Contact support or write to support@wirelens.app.