single-file CLI (urnet.py) + README quick start + GUIDE with flags, scaling recipe, troubleshooting
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
# GUIDE — urnet from zero to a working proxy pool
|
||||
|
||||
Everything here was run and measured on 2026-11-13 on a stock Windows 11 box with Python 3.11 and
|
||||
git-bash. Linux and macOS behave the same; differences are called out where they matter.
|
||||
|
||||
---
|
||||
|
||||
## 1. What you get
|
||||
|
||||
| | per account | 10 accounts |
|
||||
|---|---|---|
|
||||
| traffic | 30 GiB / day (resets 00:00 UTC) | 300 GiB / day |
|
||||
| proxies | 5, each in its own country | 50 |
|
||||
| time to create | ~25 s | ~5 min |
|
||||
| cost | 0 — no card, no email, no captcha | 0 |
|
||||
|
||||
Exits are residential peers (Comcast, Vodafone, Bell, KPN, Bouygues, Telia, Swisscom, SoftBank…).
|
||||
They are not dedicated: the exit IP can change between requests, and not every peer is a home
|
||||
connection — see [§8 Caveats](#8-caveats-worth-knowing).
|
||||
|
||||
## 2. How it works
|
||||
|
||||
URnetwork is a P2P bandwidth network: a client ("network") buys traffic, peers supply the exits.
|
||||
A free network gets 30 GiB/day, and you can publish hosted proxy endpoints on top of it.
|
||||
|
||||
The API is public and needs no browser session:
|
||||
|
||||
```
|
||||
POST /auth/network-create {"terms": true, "product_updates": false}
|
||||
-> {"network": {"network_id": "...", "network_name": "february-exhaust-83", "by_jwt": "..."}}
|
||||
|
||||
POST /auth/regenerate-seedphrase (Bearer <by_jwt>)
|
||||
-> {"seedphrase": "24 words"} # the ONLY recovery path for the account
|
||||
|
||||
POST /account/api-key {"name": "urnet-1"} (Bearer <by_jwt>)
|
||||
-> {"api_key": "urn_..."} # long-lived key for everything below
|
||||
|
||||
POST /network/auth-client {"description": "HTTPS proxy · US",
|
||||
"device_spec": "resident proxy",
|
||||
"proxy_config": {"initial_device_state": {"country_code": "us"}}}
|
||||
(Bearer <urn_...>)
|
||||
-> {"client_id": "...", "proxy_config_result": {
|
||||
"https_proxy_url": "https://<token>.crisp.bringyour.com:7155",
|
||||
"socks_proxy_url": "socks5h://crisp.bringyour.com:7153",
|
||||
"http_proxy_url": "http://crisp.bringyour.com:7154" }}
|
||||
|
||||
GET /network/proxies (Bearer <urn_...>) -> all proxies of the account
|
||||
GET /subscription/balance (Bearer <urn_...>) -> bytes left today
|
||||
```
|
||||
|
||||
Base URL: `https://api.bringyour.com`. Every authenticated call takes
|
||||
`Authorization: Bearer <jwt or urn_ key>`.
|
||||
|
||||
`urnet.py` wraps exactly these calls. Nothing else is required.
|
||||
|
||||
## 3. Install
|
||||
|
||||
### Windows
|
||||
|
||||
1. Install Python 3.8+ from python.org (tick "Add python.exe to PATH").
|
||||
2. Verify:
|
||||
```bash
|
||||
python --version
|
||||
curl --version
|
||||
```
|
||||
`curl` ships with Windows 10 1803+ (`C:\Windows\System32\curl.exe`). If it is missing, install it,
|
||||
or run without proxy flags (direct mode).
|
||||
3. Get the code:
|
||||
```bash
|
||||
git clone https://git.reformboss.com/reform/ur-network-farm.git
|
||||
cd ur-network-farm
|
||||
```
|
||||
|
||||
### Linux / macOS
|
||||
|
||||
```bash
|
||||
sudo apt install -y python3 curl git # Debian/Ubuntu; brew install python curl git on macOS
|
||||
git clone https://git.reformboss.com/reform/ur-network-farm.git
|
||||
cd ur-network-farm
|
||||
```
|
||||
|
||||
There is nothing to install for the script itself — standard library only.
|
||||
|
||||
### Sanity check
|
||||
|
||||
```bash
|
||||
python urnet.py --help
|
||||
```
|
||||
|
||||
Expected: usage block listing `farm | collect | verify | export | balance`.
|
||||
|
||||
## 4. First account in one minute
|
||||
|
||||
```bash
|
||||
python urnet.py farm --count 1
|
||||
```
|
||||
|
||||
Expected output (names are random):
|
||||
|
||||
```
|
||||
farm: 1 account(s) x 5 proxies | egress: direct | bank: bank.jsonl
|
||||
#1 OK february-exhaust-83 proxies=5 [us,de,nl,fr,gb]
|
||||
{"accounts_ok": 1, "proxies_ok": 5, "failed": 0, "bank": "bank.jsonl"}
|
||||
|
||||
next: python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
python urnet.py verify --pool pool.jsonl --limit 10
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
python urnet.py verify --pool pool.jsonl --limit 3
|
||||
python urnet.py export --pool pool.jsonl --format txt --out proxies.txt
|
||||
python urnet.py balance --bank bank.jsonl
|
||||
```
|
||||
|
||||
Expected `verify` output:
|
||||
|
||||
```
|
||||
1 us 72.89.45.91 US Freeport AS701 Verizon Business
|
||||
1 de 77.187.40.197 DE Frankfurt am M AS6805 Telefonica Germany GmbH
|
||||
1 nl 81.204.241.210 NL Amsterdam AS1136 KPN B.V.
|
||||
|
||||
TOTAL 3 | alive 3 | unique_ip 3 | countries 3 | hosting_exits 0
|
||||
```
|
||||
|
||||
`balance` shows what is left today:
|
||||
|
||||
```
|
||||
1 february-exhaust-83 left 29.71 GiB of 30.00 GiB open 292.05 MiB | proxies 5
|
||||
|
||||
accounts 1 | live keys 1 | traffic left today 29.71 GiB
|
||||
```
|
||||
|
||||
## 5. Commands
|
||||
|
||||
### `farm` — create accounts, keys and proxies
|
||||
|
||||
| flag | default | meaning |
|
||||
|---|---|---|
|
||||
| `--count N` | 1 | how many accounts to create |
|
||||
| `--proxies N` | 5 | proxies per account, hard max **5** |
|
||||
| `--countries us,de,nl` | built-in list of 15 | ISO codes, cycled across proxies |
|
||||
| `--bank FILE` | `bank.jsonl` | where accounts are appended |
|
||||
| `--start N` | 1 | label of the first account |
|
||||
| `--proxy URL` | — | single egress for every request |
|
||||
| `--proxy-file FILE` | — | one proxy URL per line, rotates per account |
|
||||
| `--shuffle` | off | randomise the proxy file order |
|
||||
| `--delay SEC` | 1.3 | pause between proxy calls (keep >= 1.3) |
|
||||
| `--curl` | off | force curl as the transport |
|
||||
| `--show-seed` | off | print a seed prefix in the log |
|
||||
|
||||
Notes:
|
||||
|
||||
- Each account is written to `bank.jsonl` **after every step**, so a crash or Ctrl-C never loses an
|
||||
account that already exists. Re-running with a new `--start` continues where you stopped.
|
||||
- Names are server-generated (`february-exhaust-83`); you cannot choose them.
|
||||
- Every account stores `jwt`, `seed` and `urn`. The seed is the only recovery path — back the file up.
|
||||
|
||||
### `collect` — bank to pool
|
||||
|
||||
```bash
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
# collected 49 unique proxies from bank.jsonl -> pool.jsonl (15 countries: AT,BR,CA,CH,DE,ES,FR,GB,...)
|
||||
```
|
||||
|
||||
Duplicates are removed by URL. Proxies created in the web UI are picked up as long as their account
|
||||
line is in `bank.jsonl`.
|
||||
|
||||
### `verify` — is the proxy really alive
|
||||
|
||||
```bash
|
||||
python urnet.py verify --pool pool.jsonl --limit 20 --shuffle --out verify.json
|
||||
```
|
||||
|
||||
One `curl https://ipinfo.io/json` per proxy. Summary line:
|
||||
|
||||
```
|
||||
TOTAL 20 | alive 19 | unique_ip 18 | countries 9 | hosting_exits 2
|
||||
```
|
||||
|
||||
- `alive` — the proxy answered.
|
||||
- `unique_ip` — how many **distinct** exit IPs you really have; this is the number that matters.
|
||||
- `hosting_exits` — rows whose ASN looks like a datacenter/VPN (`3xK`, `OVH`, `Hetzner`, `M247`…).
|
||||
They still proxy traffic but they are not residential; drop them for anything geo-sensitive.
|
||||
|
||||
### `export` — for other tools
|
||||
|
||||
```bash
|
||||
python urnet.py export --pool pool.jsonl --format txt --out proxies.txt # one URL per line
|
||||
python urnet.py export --pool pool.jsonl --format csv --out proxies.csv --cc us # filter by country
|
||||
python urnet.py export --pool pool.jsonl --format env --out proxy.env # HTTP_PROXY/HTTPS_PROXY
|
||||
```
|
||||
|
||||
### `balance` — traffic left
|
||||
|
||||
```bash
|
||||
python urnet.py balance --bank bank.jsonl
|
||||
```
|
||||
|
||||
Walks every account and prints `left / start / open_transfer` plus the total left today. `start` is
|
||||
the daily allowance (30 GiB), so `left` is what you can still push until 00:00 UTC.
|
||||
|
||||
## 6. Scaling past the IP cap
|
||||
|
||||
Free accounts are capped **per IP address** (~4, then HTTP 429). The cap follows the address you
|
||||
connect from — `px.txt` exists to change that address.
|
||||
|
||||
```bash
|
||||
# step 1 - a few accounts directly
|
||||
python urnet.py farm --count 3
|
||||
|
||||
# step 2 - export what they gave you as egress
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
python urnet.py export --pool pool.jsonl --format txt --out px.txt
|
||||
|
||||
# step 3 - keep farming, rotating egress through your own proxies
|
||||
python urnet.py farm --count 20 --proxies 5 --proxy-file px.txt --start 100
|
||||
|
||||
# step 4 - grow the pool again
|
||||
python urnet.py collect --bank bank.jsonl --out pool.jsonl
|
||||
```
|
||||
|
||||
Measured: step 3 ran 8 accounts back-to-back with zero 429s. After each wave the pool grows
|
||||
(5 new proxies per account), so the next wave has more egress to rotate through.
|
||||
|
||||
Guard rails the script applies itself:
|
||||
|
||||
- retries only while failures stay under sanity thresholds, then stops with a clear message instead
|
||||
of hammering the API;
|
||||
- keeps `--delay 1.3` between proxy calls (the per-account limit is ~5 proxies/minute);
|
||||
- writes partial progress, so a stop costs you nothing.
|
||||
|
||||
Practical free ceiling: ~4 accounts per fresh IP, and each account yields 5 more IPs, so the pool
|
||||
compounds. 12 accounts = 360 GiB/day and 49 usable proxies is what one evening produced.
|
||||
|
||||
## 7. Using the proxies
|
||||
|
||||
```bash
|
||||
# curl
|
||||
curl --proxy "$(head -1 proxies.txt)" https://ipinfo.io/json
|
||||
|
||||
# environment (whole shell)
|
||||
python urnet.py export --pool pool.jsonl --format env --out proxy.env
|
||||
set -a; . ./proxy.env; set +a
|
||||
```
|
||||
|
||||
```python
|
||||
# python requests, random pick
|
||||
import random, requests
|
||||
urls = [l.strip() for l in open("proxies.txt") if l.strip()]
|
||||
r = requests.get("https://ipinfo.io/json", proxies={"https": random.choice(urls)}, timeout=30)
|
||||
```
|
||||
|
||||
All URLs are HTTPS CONNECT with the credential inside the URL — paste and go, no user/password
|
||||
fields to fill.
|
||||
|
||||
## 8. Caveats worth knowing
|
||||
|
||||
- **Exit IP is not pinned.** The same URL returned `188.103.48.237 AS3209 Vodafone Augsburg` and
|
||||
later `80.171.40.200 AS6805 Telefonica Essen`. For anything needing a stable address, enable
|
||||
*Fixed IP* on the proxy in the web UI, or treat the address as best-effort.
|
||||
- **The exit country can be wrong.** A proxy created with `country_code: br` came back as
|
||||
`209.50.178.206 AS200373 3xK Tech GmbH, Toronto`. The network is P2P; a peer can sit anywhere.
|
||||
Always `verify` and filter by `country`.
|
||||
- **`country_code` is mandatory** — omit `initial_device_state.country_code` and the API answers
|
||||
`Invalid location`.
|
||||
- **5 proxies is the free cap.** The 6th call returns `client_limit_exceeded` with
|
||||
`upgrade_required: true`.
|
||||
- **`--proxies` above 5 is pointless** — the extra calls only return the cap error.
|
||||
- **Do not do this in a browser.** The UI "Copy URL" copies the card you clicked, not the one you
|
||||
meant, and clipboard reads fail when the window is not focused. The API returns every URL.
|
||||
|
||||
## 9. Troubleshooting
|
||||
|
||||
| symptom | cause | fix |
|
||||
|---|---|---|
|
||||
| `429 Too many accounts have been created recently from your network address` | per-IP account cap (~4) | `--proxy-file px.txt` to rotate egress, or wait for the reset |
|
||||
| `Invalid location` | missing/invalid `country_code` | pass `--countries us,de` (2-letter ISO) |
|
||||
| `client_limit_exceeded` / `upgrade_required` | already 5 proxies | delete one in the UI or lower `--proxies` |
|
||||
| `curl returned nothing through this proxy` | dead proxy or rotated token | re-run `collect`; if it persists the account was reset |
|
||||
| `Remote end closed connection without response` | urllib cannot do TLS-in-TLS to an `https://` proxy | the script auto-uses curl; make sure `curl` is installed |
|
||||
| `create failed (0): URLError ...` with no proxy | no internet / DNS / firewall | `curl -s https://api.bringyour.com` and check connectivity |
|
||||
| account created but no proxies | hit the 5/min rate | raise `--delay` to 2.0 and retry with a new `--start` |
|
||||
| `balance` prints nothing for some rows | `bank.jsonl` keeps failed creates for the record | expected — those have no `urn` |
|
||||
| proxies answer `FAIL` in `verify` | peer went offline | normal churn; re-run `collect` and `verify`, drop dead rows |
|
||||
|
||||
Exit code is `0` on success, `1` when nothing was produced — safe to use in scripts.
|
||||
|
||||
## 10. Hygiene
|
||||
|
||||
- `bank.jsonl` = full control of every account. `chmod 600 bank.jsonl`, keep it out of git
|
||||
(`.gitignore` already lists it), back it up.
|
||||
- `pool.jsonl` and `proxies.txt` contain proxy tokens — anyone with the file can spend your traffic.
|
||||
- Nothing here needs a card, an email or a phone number, so there is no PII to leak.
|
||||
- The tool writes no logs besides the bank/pool files.
|
||||
|
||||
## 11. FAQ
|
||||
|
||||
**Can I choose the account name?** No, the server generates it.
|
||||
|
||||
**Can I use these proxies in a browser?** Yes, as an HTTPS proxy. Chrome:
|
||||
`--proxy-server="https://<token>.crisp.bringyour.com:7155"`. Playwright/Camoufox: the same string as
|
||||
`proxy.server`.
|
||||
|
||||
**Do they work for Gmail / Google sign-ups?** No. Google treats datacenter and rotating residential
|
||||
ranges as suspicious; those flows need a mobile or home line.
|
||||
|
||||
**How much traffic is enough?** One account covers ~30 GiB of scraping per day. Ten accounts are a
|
||||
comfortable pool for a small crawler; heavy media work needs Pro (10 TiB/month).
|
||||
|
||||
**Does the free tier expire?** No trial clock — the daily allowance simply resets every day.
|
||||
|
||||
**What happens after 30 GiB?** Requests stop passing until the 00:00 UTC reset; `balance` shows the
|
||||
remaining bytes.
|
||||
|
||||
**Is there a way to get more per account?** Pro: 10 TiB/month and 1000 proxies, $3 for the first
|
||||
year (USDC / Zcash / Monero or a card).
|
||||
|
||||
## 12. Scope
|
||||
|
||||
This tool creates accounts you own and prints the proxy endpoints they generate. It handles no card
|
||||
data, no third-party accounts and no payment flows. URnetwork's terms of service apply — read them
|
||||
before running large waves, and do not use the pool for anything you would not do from your own line.
|
||||
Reference in New Issue
Block a user