GoProxy: a self-hosted proxy pool with validation and two protocols
GoProxy 从多个公开代理源自动抓取 HTTP/SOCKS5 代理,通过严格验证(出口 IP + 位置 + 延迟)后加入智能代理池,对外提供 HTTP 和 SOCKS5 双协议代理服务。系统采用质量分级、智能补充、自动优化等机制,确保代理池始终保持高质量和稳定性。
At a glance
- What is it?
- GoProxy is a Go service that scrapes HTTP and SOCKS5 proxies from public sources, validates them on exit IP, geography and latency, and serves them over five ports with a WebUI, while also importing paid Clash or V2ray subscriptions through sing-box. It suits crawling and IP diversity work, and the free pool it builds from public sources is exactly where the security uncertainty comes from.
- Who is it for?
- Adopt GoProxy if you need rotating outbound addresses for data collection and you want the pool, the validation and the WebUI on your own machine, with the option to import your own subscription as the stable tier. Do not adopt it to carry credentials or sensitive traffic through the free pool, because the project's own disclaimer states the scraped proxies come from public resources whose security is not guaranteed.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 130 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What GoProxy is: a proxy pool that harvests public proxies and validates them
GoProxy is a Go service that scrapes HTTP and SOCKS5 proxies from public sources, validates them, and then serves them as a proxy pool. It also imports paid subscriptions in Clash or V2ray format and converts them into local SOCKS5 proxies. The homepage is proxy.amux.ai, the licence is MIT, and the language is Go.
The interesting part is the validation, not the scraping. A harvested proxy goes through three checks before it enters the pool: the exit IP, the geographic location, and the latency. HTTP proxies get an extra check, a verification that an HTTPS CONNECT tunnel actually works. The project then grades quality in four bands, S, A, B and C, and runs the pool as a fixed capacity with a dynamic state machine, moving through Healthy, Warning, Critical and Emergency as the pool degrades.
The pool also runs itself. There are on-demand fetch modes named Emergency, Refill and Optimize, a scheduled replacement of slow proxies, and self healing on the request path, where a failed request switches to another proxy and retries up to three times without the caller noticing.
That combination is the whole pitch. Scraping a proxy list is trivial and useless, because most of the entries are dead, slow, or in the wrong country. The work in this project is in deciding which of them to keep and in keeping that set usable.
The intended user is anyone who needs outbound HTTP or SOCKS5 connectivity through a rotating set of addresses, which typically means data collection, crawling, and IP diversity. The project's own disclaimer limits the intended use to learning, exchange and technical research, states that the scraped proxies come from public internet resources whose availability, stability and security are not guaranteed, and puts the risk on the user, including network security risk and legal risk.
The two pools and the five selection modes
The architecture is a dual pool design, and the separation is the point.
The free pool scrapes from more than twenty public sources, grades quality, and refills or replaces entries as needed. The subscription pool holds nodes imported from a Clash or V2ray subscription, where the encrypted node protocols are converted by sing-box into local SOCKS5 proxies. The protocols listed as supported are vmess, vless, trojan, shadowsocks, hysteria2, anytls, http and socks5.
On top of the two pools sit five usage modes, switchable at any time from the WebUI: mixed with subscription priority, mixed with free priority, mixed with equal treatment, subscription only, and free only. The env file documents the first, the last two and a plain mixed mode as the string values, with the two priority variants reachable from the settings panel.
The two pools behave differently on failure, and the difference is a deliberate design choice rather than an inconsistency. A free proxy that fails its health check is deleted. A subscription proxy that fails is disabled, not deleted, and a scheduled probe can wake it up again. A subscription that has no usable node for seven consecutive days is removed automatically. Subscription entries are also not subject to the free pool's slot capacity limit, and a geographic filter disables a subscription entry rather than deleting it.
For the manager, the practical consequence is that the free pool is a churn mechanism and the subscription pool is a stable one. The free pool is refreshed and graded constantly; the subscription pool is preserved and probed. Which mode you run decides which of those two behaviours dominates your traffic.
Five ports, two protocols, and what each one is for
GoProxy exposes five ports, and the split between random rotation and lowest latency is the main design decision on the interface side.
Port 7777 is HTTP with random rotation, aimed at crawling, data collection and IP diversity. Port 7776 is HTTP with the lowest latency, aimed at long connections, streaming and stability first. Port 7779 is SOCKS5 with random rotation, for browsers, SSH and games. Port 7780 is SOCKS5 with the lowest latency, for stable applications and fixed connections. Port 7778 is the HTTP WebUI, the management panel, which has a dual role permission model.
The reason for having both is that the two use cases want opposite things. A crawler wants a different exit address for every request, because the point is to look like many people rather than one. A streaming session wants the same fast path for its whole life, because reconnecting mid-stream is worse than a slightly slower address.
The same duality shows up in the client side. The HTTP route is the environment variable route, `http_proxy` and `https_proxy` set to the random rotation port, and the SOCKS5 route is `ALL_PROXY` set to a `socks5://` URL. The project also documents the authenticated form, where the credentials are embedded in the proxy URL, and the browser and SSH case, where a browser is pointed at the SOCKS5 port and SSH reaches it through a `ProxyCommand` that pipes the connection through `nc`.
curl -x http://localhost:7777 https://httpbin.org/ip
export http_proxy=http://localhost:7777
export https_proxy=http://localhost:7777curl --socks5 localhost:7779 https://httpbin.org/ip
export ALL_PROXY=socks5://localhost:7779The library bindings are shown in the same shape, with the Python example using a proxies dictionary for the requests library and the Node example using a SocksProxyAgent with node-fetch, both pointing at the random SOCKS5 port.
Deploying with Docker: the compose file, the volume and the health check
Docker is the recommended deployment path, and the quick start is one command.
docker compose up -dThe WebUI is then at http://localhost:7778, and the default password is `goproxy`. The README is explicit that this default should be changed, and the env file carries the same warning next to the value.
To customise, you copy the sample env file, edit it, and start again.
cp .env.example .env
docker compose up -dThe compose file itself is small and shows the whole deployment shape. It pulls the published image with `pull_policy: always`, so every deployment takes the latest build, and it has a commented out local build alternative. The container name and every port are parameterised by env variables with defaults, and the data lives in a named volume.
container_name: ${CONTAINER_NAME:-goproxy}
restart: unless-stopped
volumes:
- goproxy-data:/app/dataThe health check is a curl against the WebUI root on port 7778 every thirty seconds, with a five second timeout and three retries. Using the WebUI as the health signal rather than a proxy port is a reasonable choice, since the WebUI is the component that has to be up for the service to be manageable at all.
The image build is a two stage Dockerfile. The builder stage is a full Debian based golang image, and the comment explains that the full image is used rather than Alpine to avoid apk problems, which is the usual reason for a native dependency like go-sqlite3. The build enables CGO explicitly, and the sing-box binary is downloaded separately as a versioned artefact and copied into the final image.
FROM golang:1.25 AS builder
COPY go.mod go.sum ./
RUN go mod downloadEXPOSE 7776 7777 7778 7779 7780
CMD ["./proxy-pool"]The final stage is a debian bookworm slim image with only ca-certificates, tzdata and curl added, which is what the health check needs. The module dependencies are minimal, a SQLite driver, golang.org/x/net and golang.org/x/time, with yaml.v3 for parsing the imported subscription files.
module goproxy
go 1.25.0
require (
github.com/mattn/go-sqlite3 v1.14.37
golang.org/x/net v0.38.0
)Subscription handling: format detection, sing-box and soft deletion
Subscriptions are managed through the WebUI by an administrator, and there are two ways in. You paste a Clash or V2ray subscription URL, and the format is detected and parsed automatically, or you upload a Clash YAML or V2ray configuration file by drag and drop.
The format detection is the piece that saves the most work. The supported inputs are Clash YAML, V2ray links, Base64 encoded content and plain text, and the project does not ask you to say which one you have. The parse layer lives in a `parser.go` module in the source tree, with sing-box process management in `singbox.go` and the refresh loop, probe wake-up and expiry cleanup in `manager.go`.
The Docker image ships sing-box built in, so encrypted protocol nodes are converted into local SOCKS5 proxies without any configuration. The `SINGBOX_PATH` variable points at the binary and defaults to `sing-box`, and the comment in the env file says the Docker image has it built in and does not need changing, while a local run needs sing-box installed separately.
The soft deletion rule is the detail that makes a subscription pool survivable. A subscription proxy that fails its health check is disabled rather than removed, and a scheduled probe can wake it up. A geographic filter also disables rather than deletes. Only a subscription with no usable node for seven days running is removed outright.
The reason is obvious in hindsight. A node on a paid subscription may be temporarily unreachable because of a network blip on the far end, and deleting it because of a single failed probe would throw away a working proxy. The seven day rule is the safety net, and the probe is the recovery path.
The configuration surface is set out in the env file, and the country filtering deserves a note because the defaults are opinionated.
BLOCKED_COUNTRIES=CN
ALLOWED_COUNTRIES=
CUSTOM_PROXY_MODE=mixed
SINGBOX_PATH=sing-box
TZ=Asia/ShanghaiThe blacklist defaults to `CN`, and the comment notes that Hong Kong, Macau and Taiwan are not affected by it. The whitelist, when non-empty, takes priority and the blacklist is ignored, so an empty whitelist means blacklist mode. The two default values together mean the service blocks mainland China exit addresses out of the box, which is a sensible default for a tool whose users are elsewhere, and a surprising one if you did not read the file.
The WebUI, the two roles, and the visitor contribution path
The management panel is a separate HTTP port with its own login, and the README describes a two role permission model: guests have read only access and administrators have full control.
The dashboard separates the free pool from the subscription pool and shows their state in real time. The subscription management section covers adding a URL, uploading a file, refreshing, pausing and deleting. The system settings page carries the five proxy mode switches, the pool parameters, and the geographic filters, and there is a Chinese and English language switch.
The visitor contribution path is the unusual part. An unauthenticated user can contribute a subscription URL or configuration file through a button at the top, and an administrator then reviews and manages those contributions. The disclaimer is explicit about who owns the result: contributed subscriptions are the contributor's responsibility and the maintainers accept no responsibility for their content.
That design solves a real problem, because everyone running a proxy pool wants a bigger pool of good nodes and nobody wants to hand out their own subscription URLs. But it also means the system accepts third party configuration from unauthenticated users, so what an administrator is really doing when reviewing a contribution is deciding whether to trust a stranger's file. The repository has a `webui/` directory described as an embedded HTML panel with a REST API, so the panel is served by the same binary rather than being a separate deployment.
The repository root also carries the documentation the README points to, and the source tree mirrors the pipeline in its directory names. There is a `fetcher/` for multi source scraping with a circuit breaker, a `validator/` for connection, IP, geography and latency checks, a `pool/` for admission, replacement and the state machine, a `checker/` for health checks, an `optimizer/` for quality work on the free pool only, a `custom/` for subscription management, a `proxy/` for the serving layer, a `storage/` for SQLite persistence across proxies, subscriptions and source status, a `config/` directory, and a `logger/` module.
Where GoProxy is the wrong choice, and what the alternatives are
Three limitations are worth stating plainly, and the first is in the project's own disclaimer.
The scraped proxies come from public internet resources and the project does not guarantee their availability, stability or security. That is not a caveat about the code, it is a statement about the input. A free proxy pool is a collection of machines you do not control, which means traffic through it can be observed, and which means an arbitrary third party can be sitting on the other end of a connection you thought was anonymous. If the data you are moving through the pool is sensitive, that is disqualifying regardless of how the validation works.
The second limitation is the operational shape. The service is a single Go binary with a SQLite database, five listening ports and a WebUI, and the compose file publishes all of them with `pull_policy: always`. The env file ships with the comment that the proxy ports are open to the internet by default and that enabling authentication is strongly recommended, and the security table is explicit that a public deployment should enable proxy authentication and change the WebUI password, an internal deployment should enable authentication or use a firewall allowlist, and only local testing is fine with the defaults. A service that defaults to open proxy ports is a service you have to think about before you expose it.
The third is what the pool is good at. Random rotation is the right answer for collecting data from many vantage points, and the wrong answer for a login session, a payment flow, or anything where a stable address matters. The lowest latency ports help with throughput but not with reputation, and IP diversity is the feature rather than a side effect.
The alternative approach is to use the subscription pool alone, with the free pool switched off through the `custom_only` mode, and treat the free pool as an optional extra source of addresses rather than the foundation. The difference in approach is direct. Free proxies are plentiful and unreliable, and they are the source of the availability and security uncertainty. A paid subscription converted through sing-box gives you a small set of nodes you chose, with a known provider, which is a pool you can reason about.
The other alternative is not a proxy pool at all. If what you need is reliable egress, a hosted API, a residential proxy service or your own egress node are different tools with different guarantees, and for anything where the address's reputation matters, an open list of scraped addresses is the wrong source.
Editorial conclusion
Adopt GoProxy if you need rotating outbound addresses for data collection and you want the pool, the validation and the WebUI on your own machine, with the option to import your own subscription as the stable tier. Do not adopt it to carry credentials or sensitive traffic through the free pool, because the project's own disclaimer states the scraped proxies come from public resources whose security is not guaranteed. Before you expose it, enable `PROXY_AUTH_ENABLED` and change `WEBUI_PASSWORD` from the shipped default, set `ALLOWED_COUNTRIES` or `BLOCKED_COUNTRIES` deliberately rather than leaving the `CN` default in place, and decide whether to run in `custom_only` mode so the pool is made of nodes you chose rather than ones anyone published.
Frequently asked questions
What does GoProxy do and how does it validate the proxies it scrapes?
It scrapes HTTP and SOCKS5 proxies from more than twenty public sources and validates each one on exit IP, geographic location and latency, with HTTP proxies additionally checked for a working HTTPS CONNECT tunnel. Validated proxies enter a pool graded S, A, B or C, and the service exposes HTTP and SOCKS5 ports.
Which ports does GoProxy expose and what is the difference between them?
Port 7777 is HTTP with random rotation for crawling and IP diversity, 7776 is HTTP with the lowest latency, 7779 is SOCKS5 with random rotation, 7780 is SOCKS5 with the lowest latency, and 7778 is the WebUI management panel. The rotation ports change the exit address per request, the lowest latency ports keep a stable fast path.
How do I run GoProxy with Docker?
Run `docker compose up -d`, which pulls the published image and starts the service, then open the WebUI at http://localhost:7778 where the default password is `goproxy`. To change settings, copy `.env.example` to `.env`, edit it, and start the stack again. The data lives in a named volume called `goproxy-data`.
Which subscription formats and node protocols does GoProxy support?
Subscription input is detected automatically and covers Clash YAML, V2ray links, Base64 and plain text, and the supported node protocols are vmess, vless, trojan, shadowsocks, hysteria2, anytls, http and socks5. The Docker image bundles sing-box, which converts encrypted nodes into local SOCKS5 proxies.
What happens to a subscription node that fails its health check in GoProxy?
A subscription proxy is disabled rather than deleted, and a scheduled probe can wake it up. A subscription with no usable node for seven consecutive days is removed automatically, and geographic filtering also disables rather than deletes an entry.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/isboyjc-goproxy)Was this useful?