SOCKS5 Proxy Setup and When It Beats HTTP
SOCKS5 settings for curl, Python, Node and Firefox, the socks5h:// scheme that keeps DNS lookups at the proxy, and which Node4 products offer SOCKS5.
SOCKS5 on Node4 uses the same host and credentials as HTTP, on a different port. Use the socks5h:// scheme (or your client's equivalent) so hostnames are resolved at the proxy rather than by your local resolver. Every paid product speaks both protocols; the free tier is HTTP(S) only, and a SOCKS5 connection on a free account is refused with a message saying so.
Where to find the port: static datacenter proxies list their SOCKS5 port next to the HTTP one on the dashboard's Proxies page, and each gateway pairs its HTTP listener with a SOCKS5 listener on the same hostname, the Rotating Datacenter gateway on port 1083 and the residential gateway on port 1082. Rotating Unmetered has its own listener pair, printed on the Proxies page. Rotating plans behave the same over either protocol; rotation happens at the exit, not in the protocol.
If you have not decided which protocol you want, HTTP vs SOCKS5 makes that call, including the cases where it changes nothing.
Setup by client
Every example takes the same four values: host, port, username and password. The proxy connection string configurator emits the working line for curl, Python, Node.js and Scrapy over HTTP or SOCKS5 if you would rather not assemble it by hand.
curl
# hostname resolved AT THE PROXY: use this
curl -x socks5h://USERNAME:PASSWORD@HOST:PORT https://target-site.com/
# equivalent long-form flag
curl --socks5-hostname USERNAME:PASSWORD@HOST:PORT https://target-site.com/
# hostname resolved LOCALLY: your resolver sees target-site.com
curl -x socks5://USERNAME:PASSWORD@HOST:PORT https://target-site.com/--socks5-hostname is the flag form of socks5h://; plain --socks5 resolves locally.
Python
requests needs the SOCKS extra (pip install requests[socks]), after which the scheme carries the same meaning:
import requests
proxies = {
"http": "socks5h://USERNAME:PASSWORD@HOST:PORT",
"https": "socks5h://USERNAME:PASSWORD@HOST:PORT",
}
print(requests.get("https://api.ipify.org", proxies=proxies, timeout=30).text)Write socks5h in both entries. A mixed configuration resolves some hostnames locally and some remotely, which makes the leak intermittent. Session reuse and other Python patterns are in Python proxy integration.
Node
Node has no built-in SOCKS support; the usual route is socks-proxy-agent handed to your HTTP client as its agent:
import { SocksProxyAgent } from "socks-proxy-agent";
import https from "node:https";
// socks5h => remote DNS. With socks5:// the agent resolves locally first.
const agent = new SocksProxyAgent("socks5h://USERNAME:PASSWORD@HOST:PORT");
https.get("https://api.ipify.org", { agent }, (res) => res.pipe(process.stdout));The scheme string controls resolution exactly as in curl. Wiring agents into axios, got and native fetch differs enough to have its own page: Node.js proxy setup.
Firefox
Firefox's manual proxy dialog takes a SOCKS host, and the checkbox "Proxy DNS when using SOCKS v5" is the socks5:// versus socks5h:// choice under a label. Unticked resolves locally; tick it. Chrome behaves differently and is covered in browser proxy setup.
socks5:// versus socks5h://
When a client fetches a hostname through a SOCKS5 proxy, someone has to turn that hostname into an address, and SOCKS5 supports both answers:
socks5://: your machine resolves the hostname through its normal DNS, then asks the proxy to connect to the resulting IP.socks5h://: the hostname is sent to the proxy, which resolves it at its end. Thehis for hostname.
The response looks identical either way; the metadata does not. With socks5://, every hostname you visit is looked up by your local resolver (your ISP, your office network, whatever DNS you sit behind) even though the traffic itself goes through the proxy. With socks5h://, the lookup happens at the exit, which also means DNS-based load balancing hands you a server near the proxy rather than near you.
Local resolution has a second consequence: your resolver may answer differently from the proxy's (geo-fenced DNS, internal zones, filtered resolvers), producing "works from here, fails through the proxy" bugs that are resolution mismatches rather than proxy faults. Unless you have a specific reason to resolve locally, use the h.
What SOCKS5 does differently from an HTTP proxy
An HTTP proxy participates in your protocol. For plain HTTP the client sends it the full URL and the proxy replays the request; for HTTPS the client sends CONNECT target.com:443 and the proxy relays opaque TLS bytes from then on. The conversation with the proxy is an HTTP conversation, and many proxies restrict CONNECT to port 443.
SOCKS5 sits below that. After a short binary handshake (greeting, optional username/password authentication, then a destination address and port), the proxy connects and forwards bytes. It does not know what a header is, so SMTP, IMAP, a database wire protocol, an SSH session or a custom TCP protocol all pass through identically. SOCKS5 does not encrypt anything (your TLS is still your TLS) and does not modify what passes through. The specification also defines a UDP relay mode, but support varies widely across providers and client libraries; treat any UDP-over-SOCKS plan as unverified until tested against your endpoint.
For ordinary web scraping the two are close to equivalent: the target sees the same exit IP either way, and switching a working HTTP setup to SOCKS5 in the hope of fewer blocks changes nothing the target can see. If you are being blocked, the causes are in why is my IP getting blocked.
ssh -D is a SOCKS proxy too
Any machine you can SSH into can be a SOCKS5 proxy:
ssh -D 1080 -N user@your-server
# then: curl -x socks5h://127.0.0.1:1080 https://api.ipify.orgOpenSSH runs a local SOCKS listener and forwards each connection out through the remote host. It is useful for reaching a staging environment behind a firewall or borrowing one server's vantage point, and it clarifies what a commercial SOCKS service is: the same forwarding at scale. One SSH box gives one exit IP with your hosting provider's reputation attached; a proxy pool gives many exits, rotation, geographic choice and metered accounting.
Clients that only speak one
Check that your tool speaks SOCKS5 before designing around it. aiohttp raises ValueError on a socks5:// URL and needs a replacement connector, covered in its own guide; axios needs a SOCKS agent plus proxy: false. Some HTTP libraries accept only HTTP proxies, Chromium's flags handle SOCKS but refuse to attach credentials to it, and a lot of software honors http_proxy while ignoring all_proxy. Wrappers such as proxychains can force a stubborn TCP application through a SOCKS proxy, but a wrapper is one more thing to debug; if the tool has native support for either protocol, use it.
SOCKS5 authentication failures do not produce the HTTP 407 that the 407 guide covers: the handshake fails and the client reports it in its own words (curl: "user was rejected by the SOCKS5 server"). The causes are the same, though: a mangled password, a whitelist mismatch, a free account on a paid-only port. That guide's checklist still applies.
Verifying, including the DNS path
Two checks. First the exit:
curl -x socks5h://USERNAME:PASSWORD@HOST:PORT https://api.ipify.orgAn IP that is not yours means the tunnel works. Second, the DNS path. On a machine where you control the resolver, watch lookups while fetching through each scheme:
sudo tcpdump -n port 53 &
curl -x socks5://USERNAME:PASSWORD@HOST:PORT https://target-site.com/ >/dev/null # expect a lookup
curl -x socks5h://USERNAME:PASSWORD@HOST:PORT https://target-site.com/ >/dev/null # expect silenceThe target's hostname appears in the first capture and not the second. Every paid product exposes the SOCKS5 listeners used above; the free tier does not, so a SOCKS5 test needs a paid plan. The pricing page lists what each plan includes.