Integrations
Anything that speaks SOCKS5 works with p2proxy. Point it at socks5://localhost:1080 (or whatever port you’ve configured) and you’re done.
Playwright
import { chromium } from "playwright";
const browser = await chromium.launch({
proxy: { server: "socks5://localhost:1080" },
});
const page = await browser.newPage();
await page.goto("https://example.com");
For per-context proxies (Playwright ≥ 1.29):
const context = await browser.newContext({
proxy: { server: "socks5://localhost:1080" },
});
Puppeteer
Puppeteer takes proxy via launch args:
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=socks5://localhost:1080"],
});
curl
curl --socks5-hostname localhost:1080 https://example.com
Python requests (with PySocks)
import requests
proxies = {
"http": "socks5h://localhost:1080",
"https": "socks5h://localhost:1080",
}
r = requests.get("https://ifconfig.me", proxies=proxies)
print(r.text)
The socks5h:// scheme resolves DNS through the proxy. Use socks5:// if you want local resolution.
Chrome / Chromium
Launch Chrome with:
google-chrome \
--proxy-server="socks5://localhost:1080" \
--user-data-dir=/tmp/chrome-p2proxy
Use a fresh --user-data-dir so you don’t taint your normal profile.
Firefox
Settings → Network Settings → Manual proxy configuration → SOCKS Host: localhost, Port: 1080. Tick SOCKS v5 and Proxy DNS when using SOCKS v5.
WireGuard (whole-device tunnel)
For anything that can’t be pointed at a SOCKS5 proxy — a phone, a desktop app with no proxy setting, everything behind a router — run the server in WireGuard mode instead and connect with a stock WireGuard client.
# Config.yaml
servers:
- protocol: WireGuard
port: 51820
host: 0.0.0.0
country: NL
wireguard:
private_key: <contents of server.key>
address: 10.7.0.1/24
dns: 1.1.1.1
peers:
- public_key: <contents of laptop.pub>
allowed_ips:
- 10.7.0.2/32
# laptop.conf — wg-quick, or import into the macOS / iOS / Android app
[Interface]
PrivateKey = <contents of laptop.key>
Address = 10.7.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = <contents of server.pub>
Endpoint = <host running p2proxy>:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
wg-quick up ./laptop.conf
curl https://ifconfig.me # the peer's IP, not yours
p2proxy terminates the tunnel in userspace — it needs no root, no kernel module and no TUN device on the p2proxy host (your client still creates one locally, as it always does). Key generation, allowed_ips semantics, MTU and throughput tuning — and the routing trap that takes your machine offline if you run the client on the p2proxy host — are covered on the WireGuard / VPN page.
Full-tunnel via tun2socks
If you’d rather keep a SOCKS5 listener and tunnel at the OS level, tun2socks routes an entire interface through it.
High-level steps:
- Create a TUN device.
- Point
tun2socksatsocks5://localhost:1080. - Add a default route through the TUN device for the subnets you want to tunnel.
See the tun2socks README for the precise invocation on your platform. WireGuard mode above is usually the simpler path.
Picking the right SOCKS5 dialect
Most tools speak SOCKS5 well, but DNS handling varies:
socks5://— client resolves DNS locally, then asks p2proxy for the IP.socks5h://— p2proxy (via the peer) resolves DNS. Use this when DNS resolution from your machine would itself leak which sites you’re visiting, or when local DNS would resolve differently from the peer’s location.
For most scraping / multi-geo workloads you want socks5h://.