Running a Snowflake Proxy on a VPS to Help Censored Users
A standalone Snowflake proxy turns a spare VPS into a volunteer relay that helps people in heavily censored regions reach the open internet through Tor. Unlike running a bridge you have to register and defend, a Snowflake proxy is fire-and-forget: it advertises itself to the Snowflake broker, gets paired with clients who cannot reach Tor directly, and shuttles their WebRTC traffic to the network. This guide covers the NAT type you actually need, how to budget bandwidth so the proxy does not blow through your VPS allowance, the exact install on an offshore VPS, and how to read the metrics so you know it is working.
Need this done for your project?
We implement, you ship. Async, documented, done in days.
What a standalone Snowflake proxy actually does
Snowflake is a pluggable transport for Tor designed to defeat IP-based and protocol-based blocking. A user inside a censored country runs a Snowflake client (built into Tor Browser, Orbot, and several apps). That client cannot connect to a normal Tor bridge because the censor has blocked the known addresses, so instead it asks the Snowflake broker to introduce it to a volunteer proxy. Your proxy is one of those volunteers.
The key trick is that the connection between the censored user and your proxy is a WebRTC data channel, the same peer-to-peer technology browsers use for video calls. To a censor, that traffic looks like ordinary WebRTC, which is far too widely used to block wholesale. Your proxy receives the user's traffic over WebRTC and forwards it to a fixed Tor relay (the default WebSocket relay wss://snowflake.torproject.net/), which hands it into the Tor network proper.
This means a Snowflake proxy is not a Tor relay or exit node. You are not carrying anonymized exit traffic to the open internet, and your IP is never the apparent source of anyone's browsing. You are a short-lived rendezvous point between a censored client and the Tor entry point. Because the broker hands out a fresh proxy each time, no single proxy IP is worth a censor blocking, and proxies that get blocked are simply rotated out. A few thousand volunteer proxies make the pool effectively impossible to enumerate and block.
The practical upshot for you as an operator: it is low-risk to run, it requires no inbound configuration on the Tor side, and it directly benefits users in places like Iran, Russia, and other networks where conventional bridges are aggressively probed and blocked.
NAT requirements: the part most operators get wrong
The single most common reason a Snowflake proxy runs but helps almost no one is NAT. Because the data channel is WebRTC, the censored client and your proxy must negotiate a direct UDP path using ICE/STUN. If your server sits behind a restricted (symmetric) NAT, that negotiation frequently fails, and the broker will deprioritize or skip your proxy.
What the Tor Project recommends, and what a VPS gives you almost by definition, is a host with no NAT or unrestricted (full-cone) NAT: an address-independent mapping, where the public IP and port your proxy is reachable on do not change based on who is connecting. A typical offshore VPS with a dedicated public IPv4 address satisfies this out of the box, which is exactly why a VPS is a better Snowflake host than a machine on a home connection behind carrier-grade NAT.
You also need the inbound UDP ephemeral port range open. The proxy uses ICE UDP candidates drawn from the kernel's local port range. Either open that whole range in your firewall:
cat /proc/sys/net/ipv4/ip_local_port_range
# e.g. 32768 60999 -> open UDP 32768-60999 inboundor constrain the proxy to a smaller, known range with the -ephemeral-ports-range flag (format <min>:<max>) and open only those ports. On an AnubizHost VPS you control the firewall, so a clean policy is: default-deny inbound, allow your SSH port, allow the chosen UDP range, and nothing else. The proxy makes only outbound connections to the broker, STUN server, and relay, so no other inbound ports are required.
To confirm your NAT type is usable, the proxy performs a NAT probe against the broker's probe endpoint on startup; check the logs after launch and you should see it report an unrestricted/full-cone result rather than restricted.
Bandwidth budgeting so you do not blow your allowance
A standalone Snowflake proxy can move real traffic. Operators routinely report a busy proxy carrying dozens of concurrent connections with throughput around 500 KB/s at peak, and the monthly total can run into hundreds of gigabytes or more if you leave it uncapped on a fast, well-connected IP. That is a feature, more relayed traffic means more censored users helped, but it can be a problem if your VPS plan has a metered transfer cap.
Budget before you deploy, not after the overage bill:
- Know your plan's transfer limit. Offshore VPS plans differ; an unmetered or generous-cap plan is ideal for Snowflake precisely because the proxy will use whatever it is given. If your plan is metered, decide how many GB/month you are willing to donate.
- Cap concurrency with
-capacity. By default the proxy accepts an unlimited number of concurrent clients. Setting-capacityto a fixed number of simultaneous clients is the most direct lever to bound throughput and therefore monthly transfer. Start conservative (for example a handful of concurrent clients) and raise it as you watch the totals. - Watch the hourly summary. The proxy emits a stats line on an interval (default one hour, configurable with
-summary-interval, e.g.-summary-interval 24h) showing connections handled and bytes relayed. Multiply a representative hour out to estimate your monthly draw and adjust-capacityaccordingly.
A sample summary log line looks like this, where sent and recv are bytes relayed in the interval:
snowflake,timeperiod_s=3600 conns=38 sent=236000000 recv=27000000That single hour relayed roughly 236 MB out and 27 MB in across 38 connections. Extrapolated naively that is on the order of hundreds of GB/month at full tilt, so a metered plan needs -capacity set deliberately. If transfer is unmetered, you can leave it uncapped and donate everything the line will carry.
Installing the proxy on an offshore VPS
A Snowflake proxy is extremely light on CPU and RAM. A 1 vCPU / 512 MB-1 GB VPS is plenty; the constraint is network, not compute. After provisioning, SSH in and pick one of two install paths.
Docker (simplest). The Tor Project publishes an official image. Pull and run it, and it stays up across reboots:
docker run --name snowflake-proxy --network host --restart unless-stopped -d \
thetorproject/snowflake-proxy:latest \
-summary-interval 1hHost networking is used so the proxy's ICE UDP candidates map to the VPS's real public IP rather than a bridged Docker address; this matters for NAT traversal. You can append flags after the image name, for example -capacity 5 to bound concurrency or -ephemeral-ports-range 40000:40100 to pin the UDP range.
From source (full control). Build the proxy binary with Go:
git clone https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
cd snowflake/proxy
go build
nohup ./proxy -summary-interval 1h >snowflake.log 2>&1 &For a real deployment, wrap that binary in a systemd unit with Restart=always instead of nohup, so the proxy survives reboots and crashes. Either way, the defaults already point at the production broker (https://snowflake-broker.torproject.net/), a STUN server, and the relay, so a bare ./proxy with no flags is a working proxy. You only add flags to cap bandwidth, fix the port range, or change logging.
Useful flags in practice: -capacity (max concurrent clients), -summary-interval (how often stats are logged), -ephemeral-ports-range (constrain ICE UDP ports), and -unsafe-logging (disables the default scrubbing of client IPs from logs, which you should leave OFF to protect the very users you are helping).
Metrics, monitoring, and good operator hygiene
Once running, you want to confirm the proxy is actually pairing with clients and relaying traffic. The first signal is the summary line described above: a healthy proxy on a clean IP starts showing nonzero conns and growing sent/recv within hours, often sooner, because the broker continuously hands out new proxies to clients.
For real monitoring, enable the metrics endpoint. Adding the metrics flag exposes proxy statistics on an internal HTTP path (default port 9999, configurable) that you can scrape with Prometheus and graph in Grafana, giving you connection counts and bytes relayed over time:
./proxy -enableMetrics -metricsPort 9999
# scrape http://127.0.0.1:9999/internal/metrics from Prometheus on the same hostBind the metrics port to localhost or your management network only; it is operator telemetry, not something to expose publicly. A few operator hygiene rules round this out:
- Never enable
-unsafe-loggingon a real proxy. The default behavior scrubs client identifiers from logs. Censored users are the people you are protecting; do not log their addresses. - Use a clean, unflagged IP. A proxy on an IP already blocklisted or already known to a censor is less useful. A fresh offshore VPS IP with no prior reputation is ideal, and rotating to a new VPS if an IP degrades is cheap.
- Keep the host minimal. Run only the proxy, key-only SSH on a non-standard port, default-deny firewall, automatic security updates. The proxy needs no inbound web services, so the attack surface stays tiny.
- Let it run 24/7. Snowflake's value comes from a large, always-available pool. A proxy that is up continuously on a stable connection helps far more users than one that comes and goes.
Because the workload is network-bound and trivially light on CPU, a single small offshore VPS can run a busy proxy indefinitely, and an unmetered plan lets you donate as much capacity as the link will carry. If you want to run several proxies or pair Snowflake with other anti-censorship services on dedicated cores and a fat uplink, an offshore dedicated server gives you the headroom; for a single donated proxy, an offshore VPS with a clean public IP is the right and inexpensive fit.
相关服务
Privacy & anti-censorship guides
Why Anubiz Host
Ready to get started?
Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.