🧮 kayos's proxy pool 🌾 originally for LOLXDsoRANDum connections 🤽 now you're actually invisible 🎋
Go to file
ibotzhub fa5c755a49
Some checks failed
tests / build (push) Has been cancelled
Dr. Griffin was here
2026-02-24 00:45:18 -08:00
.github Fix (CI): deps 2024-07-19 01:29:25 -07:00
example Breaking change: refactor statistics, improve p5.CloseAllConns 2023-12-05 13:53:24 -08:00
internal dev->staging (#91) 2023-08-11 22:51:49 -07:00
logger dev->staging (#91) 2023-08-11 22:51:49 -07:00
.gitignore Chore: tidy up 2022-07-25 00:14:26 -07:00
CHANGELOG.md Dr. Griffin was here 2026-02-24 00:45:18 -08:00
conductor.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
daemons.go Breaking change: refactor statistics, improve p5.CloseAllConns 2023-12-05 13:53:24 -08:00
debug.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
defs.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
dispense.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
getters.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
go.mod Chore: gomod fix (anotha one x2) 2024-06-13 02:16:44 -07:00
go.sum Chore(deps): Bump github.com/miekg/dns from 1.1.58 to 1.1.59 (#135) 2024-05-24 02:08:09 -07:00
LICENSE small debugging tweak, add email to license 2022-11-22 21:26:11 -08:00
list_management.go dev->staging (#91) 2023-08-11 22:51:49 -07:00
mr_worldwide.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
mystery_dialer.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
mystery_resolver.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
parse.go Drop inet.af/ipaddr and therefore unsafe dependency 2023-02-04 19:06:12 -08:00
parse_test.go Improve parsing 2022-10-11 17:15:57 -07:00
proto.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
proto_test.go Testing: add immutable proto test 2023-01-04 22:08:45 -08:00
prox5_test.go Breaking change: refactor statistics, improve p5.CloseAllConns 2023-12-05 13:53:24 -08:00
proxy.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
README.md Dr. Griffin was here 2026-02-24 00:45:18 -08:00
scale_util.go Breaking change: refactor statistics, improve p5.CloseAllConns 2023-12-05 13:53:24 -08:00
setters.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
shim.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
socks5_server.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00
stats.go Breaking change: refactor statistics, improve p5.CloseAllConns 2023-12-05 13:53:24 -08:00
validator_engine.go Dr. Griffin was here 2026-02-24 00:45:18 -08:00

Prox5

SOCKS5/4/4a validating proxy pool + SOCKS5 server

Animated Screenshot of Prox5 Example

GoDoc Go Report Card IRC Test Status five

import git.tcp.direct/kayos/prox5

Prox5 is a golang library for managing, validating, and utilizing a very large amount of arbitrary SOCKS proxies.

Notably it features interface compatible dialer functions that dial out from different proxies for every connection, and a SOCKS5 server that utilizes those functions.


Caution

Using prox5 to proxy connections from certain offsec tools may cause denial of service. Please spazz out responsibly.

e.g: https://youtu.be/qVRFnxjD7o8


Table of Contents

  1. Overview
    1. Validation Engine
    2. Auto Scaler
    3. Rate Limiting
    4. Accessing Validated Proxies
  2. Additional info
    1. The Secret Sauce
    2. Making Yourself Invisible
    3. External Integrations
  3. Status and Final Thoughts
  4. Ideas from Dr. Griffin

Overview

Validation Engine

  1. TCP Dial to the endpoint, if successful, reuse net.Conn down for step 2
  2. HTTPS GET request to a list of IP echo endpoints
  3. Store the IP address discovered during step 2
  4. Allocate a new prox5.Proxy type || update an existing one, store latest info
  5. Enqueue a pointer to this proxy.Proxy instance, instantiating it for further use

Auto Scaler

The validation has an optional auto scale feature that allows for the automatic tuning of validation worker count as more proxies are dispensed. This feature is still new, but seems to work well. It can be enabled with [...].EnableAutoScaler().

Please refer to the autoscale related items within the documentation for more info.

Rate Limiting

Using Rate5, prox5 naturally reduces the frequency of proxies that fail to validate. It does this by reducing the frequency proxies are accepted into the validation pipeline the more they fail to verify or fail to successfully connect to an endpoint. This is not yet adjustable, but will be soon. See the documentation for Rate5, and the source code for this project (defs.go is a good place to start) for more info.

Accessing Validated Proxies

  • Retrieve validated 4/4a/5 proxies as simple strings for generic use
  • Use one of the dialer functions with any golang code that calls for a net.Dialer
  • Spin up a SOCKS5 server that will then make rotating use of your validated proxies

Additional info

The Secret Sauce

What makes Prox5 special is largely the Mystery Dialer. This dialer satisfies the net.Dialer and ContextDialer interfaces. The implementation is a little bit different from your average dialer. Here's roughly what happens when you dial out with a ProxyEngine;

  • Loads up a previously verified proxy
  • Attempts to make connection with the dial endpoint using said proxy
  • Upon failure, prox5:
    • repeats this process mid-dial
    • does not drop connection to the client
  • Once a proxy has been successfully used to connect to the target endpoint, prox5 passes the same net.Conn onto the client

Making Yourself Invisible

Dr. Jack Griffin discovered that invisibility requires more than just disappearing. You have to make sure nothing gives you away. Prox5 closes the gaps:

TLS fingerprinting: every TLS handshake from a single binary looks identical without countermeasures. A passive observer on any network can trivially identify your traffic by the ClientHello alone, regardless of which proxy you're using. Prox5 rotates through realistic browser fingerprints (Chrome 120, Firefox 120, Safari 16, Edge 106, and others) on every connection via uTLS. Your handshakes look like a crowd.

DNS leaks: even with a proxy, every hostname you connect to is typically resolved by your real IP before the proxy is ever involved. That's a full record of everywhere you went, in plaintext, from your real address. Enable p5.EnableDNSOverProxy() to route all resolution through the validated proxy pool via TCP DNS. The real IP never touches a resolver.

p5 := prox5.NewProxyEngine()
p5.EnableDNSOverProxy()
p5.SetDNSCacheTTL(10 * time.Minute)
p5.SetDNSCacheSize(1024)

The DNS cache also does round-robin across multiple resolved IPs, and collapses concurrent cache misses for the same hostname into a single query. No thundering herd against your resolver.

Connection closing: CloseAllConns() now broadcasts to every open connection simultaneously using context cancellation instead of the old channel approach. StopSOCKS5Server() shuts down the server gracefully.

Proxy chaining: one hop means one proxy that knows both you and the target. SetChainLength(n) routes each connection through N proxies in sequence. Proxy 0 knows your real IP but not the destination. Proxy N-1 connects to the target but only knows proxy N-2. The target sees only the exit node. Two hops is a substantial improvement. Three is sufficient for most threat models.

Timing jitter: proxy rotation, TLS fingerprinting, and DNS-over-proxy all operate on content. a passive observer watching traffic rhythm can still fingerprint a tool by when connections happen, how often, and at what intervals. SetJitter(max) adds a random sleep of 0..max before each dial. The pattern becomes unpredictable. 50ms is a reasonable start.

p5 := prox5.NewProxyEngine()
p5.EnableDNSOverProxy()          // no DNS from your real IP
p5.SetChainLength(2)             // two hops, no single proxy has the full picture
p5.SetJitter(50 * time.Millisecond) // unpredictable timing
p5.SetDNSCacheTTL(10 * time.Minute)

"An invisible man can rule the world. Nobody will see him come, nobody will see him go." The Invisible Man (1933)

Additions by Dr. Jack Griffin.

External Integrations

Mullvad

Take a look at mullsox for an easy way to access all of the mullvad proxies reachable from any one VPN endpoint. It is trivial to feed the results of GetAndVerifySOCKS into prox5.

Here's a snippet that should just about get you there:

package main

import (
    "os"
    "time"

    "git.tcp.direct/kayos/mullsox"
    "git.tcp.direct/kayos/prox5"
)

func main() {
	p5 := prox5.NewProxyEngine()
	mc := mullsox.NewChecker()

	if err := mc.Update(); err != nil {
		println(err.Error())
		return
	}

	incoming, _ := mc.GetAndVerifySOCKS()

	var count = 0
	for line := range incoming {
		if p5.LoadSingleProxy(line.String()) {
			count++
		}
	}

	if count == 0 {
		println("failed to load any proxies")
		return
	}

	if err := p5.Start(); err != nil {
		println(err.Error())
		return
	}
	
	go func() {
		if err := p5.StartSOCKS5Server("127.0.0.1:42069", "", ""); err != nil {
			println(err.Error())
			os.Exit(1)
		}
	}()
	
	time.Sleep(time.Millisecond * 500)
	
	println("proxies loaded and socks server started")
}
ProxyBonanza

Take a look at ProxyGonanza

(TODO: code example here)


Status and Final Thoughts

This project is in development.

It "works" and has been used in "production", but still needs some love. (i gave it love babe - ibot)

Please break it and let me know what broke.

The way you choose to use this lib is yours. The API is fairly extensive for you to be able to customize runtime configuration without having to do any surgery.

Things like the amount of validation workers that are concurrently operating, timeouts, and proxy re-use policies may be tuned in real-time.


Ideas from Dr. Griffin

things that could make this faster and meaner. not done yet. left here for whoever picks it up.

notification channel instead of polling GetAnySOCKS currently sleeps 2ms between checks waiting for a validated proxy. under high concurrency with many goroutines waiting, that polling overhead compounds. replace with a chan struct{} that add() signals when a proxy enters any valid list. waiters block on the channel instead of sleeping. proxy becomes available, everyone wakes up immediately. zero polling, zero wasted sleep.

channel-based lists instead of mutex-guarded linked lists every pop() and add() on a proxyList takes a full write lock. under high concurrency all goroutines serialize through one mutex per protocol. replace with a buffered channel per protocol. pop() becomes a non-blocking channel receive. add() becomes a channel send. no locks at all. tournament selection still works -- receive up to 3, compare, send 2 back.

warm connection pool every mysteryDialer call dials the proxy at request time: TCP handshake, SOCKS negotiation, then the connection to your target. a background goroutine could maintain N live connections to the top-scored proxies. when a dial comes in, grab a pre-established connection and skip straight to the target hop. dispense goes from three network roundtrips to one. needs a freshness TTL since idle SOCKS connections get killed by the proxy eventually.

fast pre-filter for validation the validation timeout is 9 seconds. a proxy that is going to fail holds a worker for the full 9 seconds. add a 500ms TCP dial before committing a worker to the full HTTP GET. cheap connections get the full treatment, timeouts get killed fast and the worker moves on. improves validation throughput significantly on dirty proxy lists.



Please see the docs and the example for more details.

kayos+ibot 5evr