Configuration

p2proxy reads a YAML config file. By default it looks for Config.yaml in the working directory; override the path with --config (or the P2PROXY_CONFIG env var). The bundled example in the repo is a good starting point; this page covers every field.

Top-level keys

Key Type Default Description
bitping_api_key string Required. Authenticates the daemon to the Bitping network. Can also be set via the BITPING_API_KEY env var, which overrides the file value.
servers list One or more proxy listeners (below).
listen_addrs list 0.0.0.0:0, [::]:0 libp2p listen addresses, each a host:port. TCP and QUIC are bound on every entry. Port 0 means “any free port”. Forwarding a fixed port isn’t required, but improves direct (non-relayed) peer connectivity. Takes precedence over port.
port u16 Shorthand that fixes the libp2p port on the default listen addresses (e.g. 45445). Ignored when listen_addrs is set explicitly.
log_level string info Default log level when RUST_LOG is unset — trace, debug, info, warn, error, or a full tracing directive. RUST_LOG overrides it.
metrics_port u16 9091 Port for the Prometheus metrics endpoint, bound on 0.0.0.0.
bootstrap_address string /dnsaddr/boot2.bitping.com libp2p multiaddr used to bootstrap into the Bitping network.
grpc_url string https://grpc.bitping.com Bitping gRPC endpoint the daemon authenticates against.
keypair_path string node_keypair.bin Path to the persisted libp2p keypair file.

Per-server keys

Each entry under servers defines a SOCKS5 listener and its peer selection rules.

Key Type Default Description
protocol enum Socks5. Currently the only supported protocol.
port u16 Local TCP port to listen on for incoming SOCKS5 connections.
min_bandwidth string 50Mbps Minimum advertised bandwidth a peer must have. Format: <N>{bps,Kbps,Mbps,Gbps}.
country string Optional country filter. Accepts an alpha-2 code (AU), an alpha-3 code (AUS), or a country name; values are normalized to alpha-2. Omit to allow any country.
city string Optional city filter. A bare city name (Amsterdam) or the City; Region; Country form.
isp string Optional ISP filter — a regex matched against the node’s ISP name (e.g. Comcast, or Comcast|Xfinity).
asn number Optional Autonomous System Number (ASN) filter (e.g. 1136). Pins traffic to nodes on a specific network.
proxy enum allow Proxy/VPN-node policy: allow (no constraint), deny (exclude them), or require (only proxy nodes).
mobile enum allow Mobile/cellular policy: allow, deny (exclude cellular), or require (cellular only).
hosting enum allow Hosting/datacenter policy: allow, deny (residential only — no datacenter IPs), or require (datacenter only).
destination_peers list Optional ordered list of peer IDs (or full multiaddrs) to pin traffic to. The first entry is the primary; later entries are failovers. See Pinning & sticky peers.
fallback_to_discovery bool false When all pinned peers are offline: false (default) keeps retrying the list and surfaces an error — your egress IP never silently changes. true falls back to country/min_bandwidth discovery. Only relevant when destination_peers is set.
sticky bool true Remember the discovered exit peer in sticky_peers.json and reconnect to it on restart for a stable egress IP. Set false to get a fresh peer on every restart. Only applies when destination_peers is not set.
sticky_reconnect enum with-backoff How to handle reconnecting to a sticky/pinned peer. with-backoff retries with exponential backoff; fail-fast gives up immediately and re-discovers.
pool object Optional per-server tuning (below).

Per-server pool keys

p2proxy is not a connection pool — every SOCKS5 connection opens a fresh libp2p stream to the exit peer. These two knobs bound the in-flight streams per server.

Key Type Default Description
max_total u32 30 Hard ceiling on concurrent streams to the exit peer.
open_timeout_secs u64 20 Give up dialing a new stream after this long.

Environment variables

Variable Description
BITPING_API_KEY Your Bitping API key. Overrides bitping_api_key in Config.yaml. Required if not set in the file.
P2PROXY_CONFIG Path to the config file. Defaults to Config.yaml in the working directory. Same as --config.
NO_UI If true, disables the TUI (equivalent to --no-ui). Defaults to true in the official Docker image.
RUST_LOG Standard Rust tracing filter (info, debug, module=trace, …). Overrides the log_level config key when set; when unset, logging falls back to log_level (default info).

CLI flags

Flag Description
--config, -c Path to the config file (defaults to Config.yaml).
--no-ui Run headless, without the TUI.

Recipes

Country-pinned listener

A single SOCKS5 listener that only routes through nodes in Australia, with high bandwidth required:

bitping_api_key: <your-key>
servers:
  - protocol: Socks5
    port: 1080
    country: AU
    min_bandwidth: 100Mbps

Multi-region setup

Three listeners on different local ports, each pinned to a region:

bitping_api_key: <your-key>
servers:
  - protocol: Socks5
    port: 1080
    country: US
  - protocol: Socks5
    port: 1081
    country: DE
  - protocol: Socks5
    port: 1082
    country: JP

Point your client at localhost:1080 for US traffic, localhost:1081 for DE, etc.

Filtering by network and node type

Beyond country, target a specific network or node type. This routes only through residential nodes on Comcast’s US network:

servers:
  - protocol: Socks5
    port: 1080
    country: US
    asn: 7922            # Comcast (AS7922)
    hosting: deny        # residential only — never a datacenter IP
    min_bandwidth: 25Mbps

proxy, mobile, and hosting each take allow (default — no constraint), deny (exclude that type), or require (only that type). isp is a regex, so isp: "Comcast|Xfinity" matches either; add city for metro-level targeting.

Bounding concurrent streams

Raise the per-server stream ceiling for bursty workloads, and give dials longer before they time out:

servers:
  - protocol: Socks5
    port: 1080
    min_bandwidth: 100Mbps
    pool:
      max_total: 60
      open_timeout_secs: 30

Pinned peer list with failover

Route through a preferred peer; fall back to a second if it’s offline:

servers:
  - protocol: Socks5
    port: 1080
    destination_peers:
      - 12D3KooWPrimaryPeerIdHere...
      - 12D3KooWBackupPeerIdHere...
    fallback_to_discovery: false   # hard pin — error if both are offline

Entries are bare peer IDs (recommended) or full multiaddrs ending in /p2p/<id>. The hub resolves the current circuit address dynamically, so a bare peer ID stays reachable even when the peer moves between hubs.

Pinning & sticky peers

p2proxy has two complementary ways to keep a stable egress IP:

Ordered peer list (destination_peers) — explicit control. You provide one or more peer IDs in priority order. p2proxy always tries the primary (rank 0) first, moves to rank 1 on failure, and so on. Routes are re-resolved through the hub on every connect, so the peer stays reachable even after it re-homes to a different hub. If every listed peer is offline, p2proxy retries with backoff and surfaces an error (hard pin by default). Set fallback_to_discovery: true to silently fall back to the country/bandwidth filter instead.

Sticky peers (sticky: true, the default) — hands-free stability. For servers without destination_peers, p2proxy remembers the exit peer it chose during discovery and reconnects to the same one on restart. The remembered peer is stored in sticky_peers.json in the current working directory (same location as node_keypair.bin). One entry is kept per listen port.

The sticky entry carries a fingerprint of the server’s selection filters — country, city, isp, asn, the proxy/mobile/hosting policies, min_bandwidth, and the listen port. If you change any of them, the fingerprint no longer matches and p2proxy automatically discards the stale entry and discovers a fresh peer. Set sticky: false to opt out and get a new peer on every restart.

sticky_reconnect controls what happens when the remembered (or pinned) peer drops: with-backoff (the default) retries with exponential backoff, holding the egress IP steady through transient outages; fail-fast gives up immediately and lets discovery pick a replacement.

Default behaviour: sticky: true. If you want a fresh exit peer on every restart (e.g. for IP rotation), add sticky: false to each server.

Next