Connecting your apps

Once a port is open, point any tool that supports a proxy at it. This page shows the proxy address format and ready-to-use examples for browsers, curl, and code.

The proxy address

Each open port is a standard proxy on your local machine. Use the host where BlankTrail Proxy runs (127.0.0.1 for a local install) and the port number from the dashboard. A port is either SOCKS5 or HTTP, as chosen when you opened it.

socks5://127.0.0.1:20134
http://127.0.0.1:20250
TipThe Overview tab has a one-click copy button on each port that copies the full proxy address for you.

There is nowhere to enter the port in an application that cannot use a proxy at all. Interception exists for that case: the chosen programs' traffic is diverted to the port by the system, and the profile applies to them just the same — see Dashboard → System traffic interception.

Trust the certificate

For HTTPS to work without errors, the device or tool must trust the BlankTrail Proxy root certificate (see Installation → Root certificate). Some HTTP clients let you point at the certificate file directly instead of installing it system-wide.

Browsers & anti-detect browsers

Set the port as the browser's HTTP/SOCKS proxy (or, in an anti-detect browser, as the upstream proxy for a profile). For driving a real browser, open the port with the Browser preset so its fingerprint is matched and normalized.

It works as a drop-in local proxy for ZennoPoster, BAS, Puppeteer, Playwright, Selenium and any tool that supports an HTTP/HTTPS or SOCKS5 proxy — no code changes to your scripts.

DoH endpoint on the port

Through the proxy the browser hands site names to the port, and the port's resolver resolves them through the same exit as the traffic. But some names the browser resolves on its own, bypassing the proxy: STUN and TURN server names for WebRTC, names inside ICE candidates, requests of its own services. Those go to your computer's DNS, and a detector finds your real resolver or subnet in them. The DoH endpoint closes this leak: the port itself answers DNS-over-HTTPS, and a browser pointed at it resolves all of its names with the same resolver as the port's traffic.

  • The endpoint is off by default. The Browser preset in the dashboard turns it on together with HTTP/3. Over the API: doh: true when opening the port or in PUT /api/v1/port/{port}/config, or preset: browser when opening it (see API — Ports & traffic → Open a port).
  • The endpoint address is doh_url in the port card (DoH address) and in GET /api/v1/ports. Its host is the machine's external address: the External address of this machine field in Settings (in Docker, the BT_PUBLIC_HOST variable), otherwise the IP the dashboard was opened at, otherwise the public address the machine detects itself while LAN access is on; with none of them it is 127.0.0.1. The endpoint's certificate names all of these addresses, the address the connection arrived at and, for a client from a private network, every address of its /24, so behind Docker's NAT or a router there is nothing else to set up.
  • The endpoint's certificate is issued by the same BlankTrail Proxy root certificate (CA) as HTTPS through the port, so the client must trust it (see Trust the certificate). Without that trust the endpoint won't come up, and in secure mode those names won't resolve: no leak, but no answer either.
  • Whether the endpoint is in use shows in the DoH queries counter (doh_queries) in the port card: it grows after the browser visits a site. Zero means the browser is not using DoH (see the limitations below).

ZennoPoster

In a C# action of the project, set the proxy and DoH in one call. NetworkSettings applies only to the Chromium browser; true turns on secure mode, with no fallback to the system DNS.

instance.SetProxy(new ProxySettings("http://127.0.0.1:20250"),
    new NetworkSettings(true, "https://127.0.0.1:20250/dns-query"));

To reset DoH: instance.SetProxy(null, new NetworkSettings()).

Chrome and Chromium

In Chrome's security settings, turn on Use secure DNS, choose a custom provider and enter the endpoint address. A Chrome launched with this port as its proxy still sends DoH directly, bypassing the proxy, so nothing else needs configuring.

Chromium-based anti-detect browsers can behave differently: they send DoH through the profile's proxy, that is, through this same port. The port recognises such a tunnel to its own DoH endpoint and answers it itself — nothing needs configuring, and the proxy log records each such tunnel. In builds 1.3.13 and older this request was refused: the log shows “leak-guard: blocked private target” lines with the endpoint address, and the browser rejects the DoH address (“Please verify…”). Until you update, turn off secure DNS in the browser profile: with a proxy set, the port resolves site names anyway.

On managed machines, set the same with policies:

DnsOverHttpsMode = secure
DnsOverHttpsTemplates = https://127.0.0.1:20250/dns-query

Firefox

Set three preferences in about:config. Mode 3 means DoH only, with no fallback to the system DNS; the third preference makes Firefox trust the system root certificates, where the BlankTrail Proxy CA is installed (or import the CA into Firefox manually).

network.trr.mode = 3
network.trr.uri = https://127.0.0.1:20250/dns-query
security.enterprise_roots.enabled = true

curl

curl can query DoH itself. The command below resolves the name through the port (doh_queries grows) but then connects to the site directly: it checks the endpoint, it does not route traffic through the proxy.

curl --doh-url https://127.0.0.1:20250/dns-query https://example.com

curl for Windows takes root certificates from the system store, where the BlankTrail Proxy CA is installed. On Linux and macOS, --cacert applies both to the DoH request and to the site itself, so for this check add the CA to the system store.

macOS

  • Local Network, macOS 15 Sequoia and newer: a browser reaches an address in your local network only with the permission in System Settings → Privacy & Security → Local Network. Without it Chrome answers “Please verify that this is a valid provider” when the DoH address is saved, and in secure mode sites don't open, while curl in Terminal gets through. The permission is per app: Chrome and the browser of an anti-detect tool (for example, SunBrowser in AdsPower) each need their own. macOS 14 Sonoma and older have no such section and need nothing, and the public address of a remote server needs no permission on any version.
  • System proxy: if the browser goes through the macOS system proxy (System Settings → Network → the connection → Details → Proxies), turn on both Web proxy (HTTP) and Secure web proxy (HTTPS), or a SOCKS proxy. With only HTTP on, HTTPS sites open directly: the site sees your real address while names resolve through the port's DoH, and a detector reports a client subnet that contradicts the connection address. What Chrome actually uses is shown at chrome://net-internals/#proxy.
  • WebRTC over UDP bypasses the system proxy too — see the UDP limitation below.

Checking the endpoint

If the browser refuses the address, ask the endpoint directly from the same computer, bypassing the proxy. For ports with a login use the address from the port card, with the token; blanktrail-ca.pem is the root certificate (see Trust the certificate).

curl -v --noproxy "*" --cacert blanktrail-ca.pem "https://ADDRESS:PORT/dns-query?dns=AAABAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE"
  • A certificate verification error (for example, “unable to get local issuer certificate”) — the root certificate isn't trusted, or --cacert points to another file.
  • “no alternative certificate subject name matches target host name” — the address is not in the endpoint's certificate: fill in the External address of this machine field or open the dashboard at this IP (builds before 1.3.12 — see the limitations).
  • HTTP 401 — the ports have a login, and the address carries no token: copy doh_url from the port card again.
  • HTTP 200 with content-type: application/dns-message — the endpoint is fine; look at the browser: its policies (chrome://net-internals/#dns), its proxy and, on macOS 15 and newer, its Local Network permission.

Limitations

  • Ports with a login (proxy authorization in Settings): browsers do not send a login to a DoH server, so doh_url then ends with a token — https://ADDRESS:PORT/dns-query/TOKEN. The token is derived from the login and password and changes with the password: copy the address from the port card again. The endpoint also accepts the login itself (the Authorization or Proxy-Authorization header, Basic scheme) from clients that can send it.
  • Builds before 1.3.12: there is no token, so on ports with a login Chromium and ZennoPoster don't use DoH; and for an address with an IP instead of a host name the certificate names only the address the connection arrived at — behind Docker's NAT that is the container's address, and Chrome answers “Please verify that this is a valid provider”. The workaround for such builds is a host name instead of the IP in the DoH address: the certificate is then issued for that name.
  • Chromium silently turns off DoH set in its settings if the machine has any Chrome policy or is joined to a domain: names go to the system DNS again. The sign is that doh_queries does not grow; the DNS mode is shown at chrome://net-internals/#dns. In that case set DoH with policies.
  • DoH closes the DNS leak but not UDP: STUN requests over UDP bypass the proxy. For those, use WebRTC emulation in ZennoPoster (emulateWebrtc in ProxySettings) or the Chrome policy WebRtcIPHandling = disable_non_proxied_udp.
  • A port opened to the local network or in Docker answers DoH for anyone who can reach it, that is, it becomes a resolver through its exit.
  • The answer deadline per question is 6 seconds, and up to 10 seconds for an explicitly chosen resolver strategy (isp, exit, pool, custom). If the resolver doesn't make it, the answer is SERVFAIL; a name outside the plan's domain list gets REFUSED.

curl

curl -x socks5://127.0.0.1:20134 https://example.com
curl -x http://127.0.0.1:20250 https://example.com

Code examples

Python (requests)

import requests

proxies = {
    "http": "socks5://127.0.0.1:20134",
    "https": "socks5://127.0.0.1:20134",
}
r = requests.get("https://example.com", proxies=proxies)
print(r.status_code)

Node.js (undici)

import { ProxyAgent, request } from 'undici'

const agent = new ProxyAgent('http://127.0.0.1:20250')
const { statusCode } = await request('https://example.com', { dispatcher: agent })
console.log(statusCode)

Telegram (MTProto)

A Telegram client cannot go through an ordinary fingerprint-spoofing proxy — it speaks its own protocol. For it you open a port with the MTProto protocol: from the outside it looks like an ordinary Telegram proxy, and the camouflage makes the connection resemble TLS to an unrelated site.

  1. In the open-port dialog choose the “MTProto” preset, or the mtproto protocol.
  2. Turn on the “Advanced” toggle in the dialog header — without it the MTProto section stays hidden. Leave the secret empty so the application generates a new one, or enter your own in the canonical ee… form.
  3. Open the port. The response carries a ready tg://proxy?server=…&port=…&secret=… link — that is what you open on the device with Telegram.
Open an MTProto port
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"port":20443,"protocol":"mtproto",
       "mtproto_camouflage_domain":"www.google.com"}' \
  http://127.0.0.1:8891/api/v1/ports/open
Response
{
  "port": 20443,
  "protocol": "mtproto",
  "status": "opened",
  "tg_link": "tg://proxy?server=203.0.113.10&port=20443&secret=ee…",
  "mtproto_secret": "ee…"
}
  • The camouflage domain is also the SNI the client presents: www.google.com by default. From the network's side the connection looks like an ordinary visit to that site.
  • A prober or a client with a wrong secret is by default spliced to the REAL camouflage site rather than cut off: a cut would itself reveal that a proxy is here.
  • If the UPSTREAM egress is itself an MTProto proxy, the faketls egress mode makes the port talk to it over fake TLS; auto chooses by itself, obfuscated is the ordinary obfuscation.
  • An MTProto port is not an HTTP proxy: it cannot be given to a browser or to curl, and TLS fingerprint spoofing does not apply to it.

n8n

n8n has a ready-made node: the n8n-nodes-blanktrail package installs from npm under Settings → Community nodes. The node opens a port, picks the browser profile and the route, and hands the proxy address to the next step of the workflow — with no HTTP code of your own and no hand-written API calls.

TipWhen BlankTrail and n8n both run in containers, put them on the same Docker network and address the proxy by container name rather than 127.0.0.1 — inside the n8n container that address points at the container itself.

Common connection issues

  • Certificate errors on HTTPS — the certificate isn't trusted on this device. Install it (Installation → Root certificate).
  • Connection refused — the port isn't open, or you used the wrong host/port. Check the Overview tab.
  • Wrong protocol — a SOCKS5 port won't accept HTTP-proxy settings and vice versa. Match the protocol shown on the port.
  • Proxy authentication refused — the ports demand a login and password, and the address carries none. Write the address in full: socks5://user:password@127.0.0.1:20134. In the recommended Docker run command the password is set by default.
  • The port was there and vanished — a port with no traffic closes itself after 30 minutes, counted from the moment it was opened. Give the port its own time (PUT /api/v1/port/{port}/idle with {"seconds": 0}) or list it in portmanager.startup_ports.
  • Everything works but the site recognises the client — check whether TLS pass-through is on for that port: with it the fingerprint of your own application goes out, not the chosen profile.
  • Chrome says “Please verify that this is a valid provider” for the DoH address — check the endpoint with curl (DoH endpoint on the port → Checking the endpoint): the answer tells whether it is the certificate, the token or the browser.