{"id":36457105,"url":"https://github.com/isacskoglund/rotox","last_synced_at":"2026-01-11T23:05:17.399Z","repository":{"id":304728734,"uuid":"967403331","full_name":"isacskoglund/rotox","owner":"isacskoglund","description":"Distributed rotating proxy compatible with serverless environments.","archived":false,"fork":false,"pushed_at":"2025-07-14T20:59:05.000Z","size":223,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-11T01:58:22.174Z","etag":null,"topics":["go","golang","proxy","serverless"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/isacskoglund.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-16T12:02:16.000Z","updated_at":"2025-07-16T17:34:49.000Z","dependencies_parsed_at":"2025-07-15T01:04:33.313Z","dependency_job_id":"ba88b288-4d3b-41ae-8a88-2cc1f939eb30","html_url":"https://github.com/isacskoglund/rotox","commit_stats":null,"previous_names":["isacskoglund/rotox"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/isacskoglund/rotox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isacskoglund%2Frotox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isacskoglund%2Frotox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isacskoglund%2Frotox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isacskoglund%2Frotox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/isacskoglund","download_url":"https://codeload.github.com/isacskoglund/rotox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/isacskoglund%2Frotox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28326196,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T22:11:01.104Z","status":"ssl_error","status_checked_at":"2026-01-11T22:10:58.990Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","proxy","serverless"],"created_at":"2026-01-11T23:05:16.677Z","updated_at":"2026-01-11T23:05:17.394Z","avatar_url":"https://github.com/isacskoglund.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rotox\n\n[![Go Documentation](https://pkg.go.dev/badge/github.com/isacskoglund/rotox.svg)](https://pkg.go.dev/github.com/isacskoglund/rotox)\n![Test](https://github.com/isacskoglund/rotox/actions/workflows/ci.yml/badge.svg)\n\n**rotox** is a distributed rotating proxy designed to make a large number of public IP addresses available through a single server. The proxy is particularly well suited for running on serverless, scale-to-zero platforms such as Google Cloud Run, allowing users to leverage the large number of public IP addresses available on such platforms, often at negligible cost.\n\n## Architecture\n\n**rotox** consists of two main parts, a **hub** and one or more **probes**. These are separate processes and typically run on different machines. When a client communicates with a target on the internet, the traffic is routed first through the hub, then through one of the many probes and finally to the target. The hub distributes the connections across the pool of probes, allowing the client to make repeated connections to the same target using many different public IPs.\n\n![Architecture](docs/architecture.svg)\n\n## Serverless Compatibility\n\nThe hub and the probes communicate over gRPC, which is based on the HTTP/2 protocol. This makes the probes compatible with serverless, scale-to-zero environments such as Google Cloud Run. On such platforms, one can deploy a large number of probes — each potentially offering a unique public IP — without incurring costs during idle time. More precisely, each probe is only active and billed while it is relaying traffic, as opposed to a virtual machine which remains active and incur costs regardless of usage.\n\nHowever, most common proxy protocols (e.g., HTTP CONNECT, SOCKS5) are not supported in serverless environments like Google Cloud Run due to networking restrictions (often imposed by intermediary layer 7 load balancers). As a result, the hub cannot function properly in such environments. Nor can traditional proxy software. This limitation is one of the core motivations for the hub-probe architecture: probes alone cannot function as proxies in these environments, but they can relay traffic once coordinated by the hub.\n\nThe hub must therefore run in an environment that allows clients to initiate raw TCP connections — this can be a VM or any environment that allows unrestricted inbound traffic. Importantly, only one hub is needed no matter the number of probes.\n\n## Client Compatibility\n\nThe **rotox** hub currently supports two protocols:\n\n-   **HTTP plaintext requests:** The client sends a standard HTTP request to the proxy, which forwards it unmodified to the target. This mode supports only HTTP — not HTTPS.\n-   **HTTP CONNECT requests:** The client sends a CONNECT request to the proxy, specifying the hostname or address of the target. The proxy then establishes a TCP connection to the target and relays traffic bidirectionally. This enables the client and target to establish a secure TLS session, and their communication is no longer limited to the HTTP protocol.\n\nSupport for SOCKS5 is planned (see [Roadmap](#roadmap-non-committal)) but not yet implemented.\n\n## Quick Start\n\nThe simplest way to get up and running with **rotox** is to run a hub and a single probe locally.\n\n### Using Docker\n\n#### Step 1: Create a `docker-compose.yml` file\n\n```yaml\nversion: \"3.8\"\n\nservices:\n    hub:\n        image: ghcr.io/isacskoglund/rotox-hub:latest\n        environment:\n            CONFIG_FILE: /etc/rotox/config.yml\n            HTTP_PROXY_SECRET: proxysecret\n            PROBES_SECRET: probesecret\n        volumes:\n            - ./hub-config.yml:/etc/rotox/config.yml:ro\n        ports:\n            - \"8000:8000\" # HTTP proxy\n\n    probe:\n        image: ghcr.io/isacskoglund/rotox-probe:latest\n        environment:\n            LOG_LEVEL: debug\n            LOG_FORMAT: json\n            PORT: 8000\n            SECRET: probesecret\n```\n\n\u003e ⚠️ Make sure the secrets match between `hub` and `probe`. The `hub` authenticates itself to the `probe` using the shared `SECRET`.\n\n#### Step 2: Create a hub config file (`hub-config.yml`)\n\n```yaml\nlog_level: debug\nlog_format: json\n\nproxies:\n    http:\n        port: 8000\n        secret_env: HTTP_PROXY_SECRET\n\nprobes:\n    - secret_env: PROBES_SECRET\n      require_tls: false\n      hosts:\n          - probe:8000\n```\n\n\u003e 📄 This config is mounted into the hub container and loaded at startup.\n\n#### Step 3: Start the stack\n\n```bash\ndocker-compose up\n```\n\nThe hub will start and listen for HTTP proxy requests on port `8000`, relaying incoming traffic through the probe.\n\n### Step 4: Test the proxy with curl\n\nUse curl to send an HTTP request through the rotox proxy (hub running on localhost:8080):\n\n```bash\ncurl -x http://localhost:8000 http://example.com\n```\n\nThis sends a plaintext HTTP request via the rotating proxy. The hub will route it through one of the probes.\n\nFor HTTPS sites, test the HTTP CONNECT support:\n\n```bash\ncurl -x http://localhost:8000 -L https://example.com\n```\n\nThis uses CONNECT to tunnel TLS traffic through the proxy.\n\n## Configuration\n\n### Hub\n\nThe hub configuration is loaded from a YAML file specified through an environment variable:\n\n```bash\nCONFIG_FILE=/path/to/config.yml\n```\n\nBelow is an example config file:\n\n```yaml\nlog_level: info\nlog_format: json\n\nproxies:\n    http:\n        port: 8080\n        secret_env: HTTP_PROXY_SECRET\n\ntelemetry:\n    port: 9000\n    secret: secret_value\n\nprobes:\n    - secret_env: PROBES_SECRET_1\n      require_tls: false\n      hosts:\n          - localhost:8000\n          - host.docker.internal:8000\n\n    - secret_env: PROBES_SECRET_2\n      require_tls: true\n      hosts:\n          - 10.0.0.1:8000\n          - 10.0.0.2:8000\n```\n\n**Fields:**\n\n-   `log_level`: Log verbosity (`debug`, `info`, `warn`, `error`).\n\n-   `log_format`: Log output format (`json` or `text`).\n\n-   `proxies`: Defines proxy listeners. Currently supports only `http`.\n\n    -   `port`: Port for proxy client connections.\n    -   `secret_env`: Environment variable name holding the proxy secret.\n\n-   `telemetry` (optional): Telemetry server configuration.\n\n    -   `port`: Telemetry server port.\n    -   `secret`: Secret for telemetry access.  \n        _Telemetry is not yet a fully implemented feature. It is recommended that this field is omitted, leaving the feature disabled._\n\n-   `probes`: List of probe groups. Each group includes:\n    -   `secret_env`: Environment variable name for the probe secret.\n    -   `require_tls`: Whether TLS is required (`true` or `false`).\n    -   `hosts`: List of one or more probe host addresses.\n\n---\n\n### Probe\n\nThe probe uses environment variables for configuration:\n\n-   `LOG_LEVEL`: Log verbosity (`debug`, `info`, `warn`, `error`).\n\n-   `LOG_FORMAT`: Log format (`json` or `text`).\n\n-   `PORT`: Port where the probe listens for hub connections.\n\n-   `SECRET`: Secret string used to authenticate the probe with the hub.\n\nYou can run multiple probes, each with different `SECRET` and `PORT` values.\n\n## Roadmap (non-committal)\n\n-   SOCKS5 Support\n-   Hub telemetry API\n-   Web UI for monitoring\n-   IP usage statistics\n\n## Disclaimer\n\nThis is a hobby project. No guarantees are made regarding stability, performance, or ongoing development. Contributions welcome.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisacskoglund%2Frotox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fisacskoglund%2Frotox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fisacskoglund%2Frotox/lists"}