mirror of
https://github.com/SajadMRjl/find-me-internet.git
synced 2026-07-02 15:09:00 +00:00
feat: readme, validcount
This commit is contained in:
107
README.md
Normal file
107
README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Find Me Internet 🌐
|
||||
|
||||
**Find Me Internet** is a high-performance, scalable proxy scanner and tester written in Go. It is designed to ingest thousands of proxy links (VLESS, VMess, Trojan, Reality, etc.), filter out dead nodes efficiently using "cheap" network checks, and rigorously test survivors using a real **Sing-box** core.
|
||||
|
||||
It uses a "Funnel Architecture" to minimize resource usage, allowing it to scan 100,000+ proxies without crashing your system.
|
||||
|
||||
## 🚀 Architecture
|
||||
|
||||
The system processes proxies through a multi-stage pipeline:
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Source File/URL] --> B(Parser)
|
||||
B --> C{Dedup}
|
||||
C -- New --> D{Cheap Filter}
|
||||
C -- Duplicate --> X[Discard]
|
||||
D -- TCP/TLS OK --> E(Sing-box Core)
|
||||
D -- Fail --> X
|
||||
E -- Latency OK --> F(GeoIP Enricher)
|
||||
E -- Fail --> X
|
||||
F --> G[JSONL Sink]
|
||||
|
||||
```
|
||||
|
||||
## 🛠️ Prerequisites
|
||||
|
||||
1. **Go 1.21+** installed.
|
||||
2. **Sing-box Binary:** The engine that powers the tests.
|
||||
3. **GeoLite2 Database (Optional):** For country detection.
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
### 1. Clone & Dependencies
|
||||
|
||||
```bash
|
||||
git clone https://github.com/sajadMRjl/find-me-internet.git
|
||||
cd find-me-internet
|
||||
go mod tidy
|
||||
|
||||
```
|
||||
|
||||
### 2. Install Sing-box
|
||||
|
||||
Download the latest release for your OS from [Sing-box Releases](https://github.com/SagerNet/sing-box/releases).
|
||||
|
||||
- Extract the binary.
|
||||
- Place it in the `./bin/` folder (or anywhere you like).
|
||||
- _Linux/macOS:_ Ensure it is executable: `chmod +x ./bin/sing-box`
|
||||
|
||||
### 3. Setup GeoIP (Optional)
|
||||
|
||||
- Register for a free MaxMind account.
|
||||
- Download the `GeoLite2-Country.mmdb`.
|
||||
- Place it in `./data/`.
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
Create a `.env` file in the root directory:
|
||||
|
||||
```ini
|
||||
# --- General ---
|
||||
LOG_LEVEL=INFO # Options: DEBUG, INFO, WARN, ERROR
|
||||
MAX_WORKERS=50 # Concurrency limit for Sing-box instances
|
||||
|
||||
# --- Timeouts ---
|
||||
TCP_TIMEOUT=2s # Max time for "Cheap" TCP connect
|
||||
TEST_TIMEOUT=10s # Max time for "Expensive" HTTP test
|
||||
TEST_URL=http://cp.cloudflare.com # The target to fetch
|
||||
|
||||
# --- Paths ---
|
||||
SING_BOX_PATH=./bin/sing-box
|
||||
INPUT_PATH=./data/proxies.txt
|
||||
OUTPUT_PATH=./data/valid_proxies.jsonl
|
||||
GEOIP_PATH=./data/GeoLite2-Country.mmdb
|
||||
|
||||
```
|
||||
|
||||
## 🏃 Usage
|
||||
|
||||
1. **Prepare Input:**
|
||||
Add your raw proxy links (one per line) to `data/proxies.txt`.
|
||||
2. **Run the Scanner:**
|
||||
|
||||
```bash
|
||||
go run cmd/main.go
|
||||
|
||||
```
|
||||
|
||||
3. **View Results:**
|
||||
Valid proxies are streamed to `data/valid_proxies.jsonl`.
|
||||
|
||||
```bash
|
||||
tail -f data/valid_proxies.jsonl
|
||||
|
||||
```
|
||||
|
||||
### Output Example
|
||||
|
||||
```json
|
||||
{"link":"vless://uuid@1.2.3.4:443...","type":"vless","address":"1.2.3.4","port":443,"latency_ms":145,"country":"DE"}
|
||||
{"link":"vmess://...","type":"vmess","address":"5.6.7.8","port":80,"latency_ms":210,"country":"US"}
|
||||
|
||||
```
|
||||
|
||||
## ⚠️ Disclaimer
|
||||
|
||||
This tool is for educational purposes and network analysis only. The user is responsible for ensuring they have permission to test the networks and proxies they scan.
|
||||
26
cmd/main.go
26
cmd/main.go
@@ -46,21 +46,23 @@ func main() {
|
||||
netFilter := filter.NewPipeline(cfg.TcpTimeout)
|
||||
boxRunner := tester.NewRunner(cfg.SingBoxPath, cfg.TestURL, cfg.TestTimeout)
|
||||
|
||||
// 3. Input Stream (Example: reading from a local file 'proxies.txt')
|
||||
// In production, you might loop through a list of URLs here
|
||||
// 3. Input Stream
|
||||
linkStream, err := source.LoadFromFile(cfg.InputPath)
|
||||
if err != nil {
|
||||
slog.Error("input_source_failed", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 4. Worker Pool
|
||||
// 4. Worker Pool & Counters
|
||||
var wg sync.WaitGroup
|
||||
semaphore := make(chan struct{}, cfg.Workers)
|
||||
|
||||
slog.Info("pipeline_started", "workers", cfg.Workers)
|
||||
|
||||
// Counters for final stats
|
||||
countProcessed := 0
|
||||
countValid := 0
|
||||
var mu sync.Mutex // Protects countValid from race conditions
|
||||
|
||||
slog.Info("pipeline_started", "workers", cfg.Workers)
|
||||
|
||||
// Main Loop
|
||||
loop:
|
||||
@@ -110,22 +112,30 @@ loop:
|
||||
// --- STAGE 6: SAVE ---
|
||||
if err := resultsWriter.Write(proxy); err != nil {
|
||||
slog.Error("write_failed", "error", err)
|
||||
}
|
||||
} else {
|
||||
// Thread-Safe Increment
|
||||
mu.Lock()
|
||||
countValid++
|
||||
mu.Unlock()
|
||||
|
||||
slog.Info("proxy_saved",
|
||||
"country", proxy.Country,
|
||||
"latency", proxy.Latency.Milliseconds(),
|
||||
"type", proxy.Type,
|
||||
)
|
||||
}
|
||||
|
||||
}(rawLink)
|
||||
|
||||
countProcessed++
|
||||
if countProcessed % 1000 == 0 {
|
||||
slog.Info("progress_report", "processed", countProcessed)
|
||||
slog.Info("progress_report", "processed", countProcessed, "valid_so_far", countValid)
|
||||
}
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
slog.Info("scan_finished", "total_processed", countProcessed)
|
||||
slog.Info("scan_finished",
|
||||
"total_processed", countProcessed,
|
||||
"total_valid", countValid,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user