{"id":34764652,"url":"https://github.com/drmckay/cloakprobe","last_synced_at":"2026-06-07T07:01:46.904Z","repository":{"id":327774909,"uuid":"1109206498","full_name":"drmckay/cloakprobe","owner":"drmckay","description":"Privacy-first, security-focused IP information service for Cloudflare","archived":false,"fork":false,"pushed_at":"2026-05-22T05:22:31.000Z","size":2047,"stargazers_count":4,"open_issues_count":11,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T13:56:44.529Z","etag":null,"topics":["cloudflare","ip-address","ip-geolocation","ip-lookup","ipv6","osint","privacy","privacy-tools","rust","security-tools","self-hosted","what-is-my-ip","whatismyip"],"latest_commit_sha":null,"homepage":"https://cloakprobe.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drmckay.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["drmckay"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2025-12-03T13:39:35.000Z","updated_at":"2026-05-20T04:01:05.000Z","dependencies_parsed_at":"2026-03-16T07:02:12.450Z","dependency_job_id":"61ceceb3-ac10-4d62-8682-14e05c5a7a8f","html_url":"https://github.com/drmckay/cloakprobe","commit_stats":null,"previous_names":["drmckay/cloakprobe"],"tags_count":181,"template":false,"template_full_name":null,"purl":"pkg:github/drmckay/cloakprobe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmckay%2Fcloakprobe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmckay%2Fcloakprobe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmckay%2Fcloakprobe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmckay%2Fcloakprobe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drmckay","download_url":"https://codeload.github.com/drmckay/cloakprobe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drmckay%2Fcloakprobe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34011812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["cloudflare","ip-address","ip-geolocation","ip-lookup","ipv6","osint","privacy","privacy-tools","rust","security-tools","self-hosted","what-is-my-ip","whatismyip"],"created_at":"2025-12-25T07:04:33.760Z","updated_at":"2026-06-07T07:01:46.866Z","avatar_url":"https://github.com/drmckay.png","language":"Rust","funding_links":["https://github.com/sponsors/drmckay"],"categories":[],"sub_categories":[],"readme":"# CloakProbe\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/badge.png\" alt=\"CloakProbe Social Banner\" width=\"100%\"\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![CI](https://github.com/drmckay/cloakprobe/workflows/CI/badge.svg)](https://github.com/drmckay/cloakprobe/actions)\n[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n[![Rust](https://img.shields.io/badge/rust-1.80%2B-orange.svg)](https://www.rust-lang.org/)\n\nPrivacy-first, security-focused IP information service designed to run behind Cloudflare.\n\n\u003c/div\u003e\n\n\u003e ⚠️ **Commercial Use Notice**: This software is licensed under AGPL-3.0 with additional commercial use restrictions. Commercial use requires explicit written permission. See [LICENSE](LICENSE) for details.\n\n## Features\n\n- 🔒 **Privacy-first**: No tracking, no ads, no analytics\n- 🛡️ **Security-focused**: Comprehensive security headers, input validation\n- 🌐 **IPv4 \u0026 IPv6**: Full support for both IP versions\n- 📊 **Detailed Information**: IP details (multiple formats), ASN lookup, network information, organization details from all 5 RIRs\n- 🎨 **Modern UI**: Beautiful dark theme, responsive design, one-click IP copy\n- ⚡ **Fast**: Built with Rust for performance\n- 🔧 **Easy Setup**: Simple configuration, Docker-ready\n- 📡 **Cloudflare Integration**: Reads client IP from Cloudflare headers (CF-Connecting-IP)\n- 🌍 **Cloudflare Worker Headers**: Supports extended Cloudflare Worker headers (X-CF-Country, X-CF-City, X-CF-ASN, X-CF-Trust-Score, etc.)\n- 🔒 **XSS Protection**: All Cloudflare header values are sanitized before HTML rendering\n- 🗄️ **Local ASN Database**: Uses ip2asn-based binary database (`asn_db.bin`)\n- 🏢 **Multi-RIR Organization Data**: Organization details from all 5 RIRs (RIPE, APNIC, LACNIC, AFRINIC, ARIN)\n- 🔍 **Reverse DNS Lookup**: Client-side reverse DNS (PTR) lookup using Cloudflare DNS over HTTPS (DoH) - only on user interaction\n- 🌐 **ISP Hint Detection**: Client-side authoritative NS lookup to identify ISP/provider from nameserver hostnames\n\n## Requirements\n\n- Rust (stable, e.g. 1.80+)\n- Linux / macOS\n- `curl`, `gunzip` (for gzip package)\n\n## Installation\n\n\u003e 📖 **Detailed Installation Guide**: See [INSTALL.md](INSTALL.md) for comprehensive installation instructions, troubleshooting, and manual setup.\n\n### Quick Install (from GitHub Release)\n\n```bash\n# Download and run the installation script\ncurl -fsSL https://raw.githubusercontent.com/drmckay/cloakprobe/main/install.sh | sudo bash\n\n# Download ASN database\nsudo /opt/cloakprobe/scripts/update_asn_db.sh\n\n# Start the service\nsudo systemctl start cloakprobe\n\n# Check status\nsudo systemctl status cloakprobe\n```\n\n### Manual Installation\n\n```bash\ngit clone https://github.com/drmckay/cloakprobe.git\ncd cloakprobe\n\n# Build\ncargo build --release\n\n# Generate IP→ASN database\n./scripts/update_asn_db.sh\n\n# Run locally\nCLOAKPROBE_PRIVACY_MODE=strict \\\nCLOAKPROBE_ASN_DB_PATH=./data/asn_db.bin \\\nCLOAKPROBE_REGION=eu-central \\\n  ./target/release/cloakprobe\n```\n\nDefault address: `0.0.0.0:8080`.\n\n### Systemd Service\n\nThe installation script automatically sets up a systemd service. Manual setup:\n\n```bash\n# Copy service file\nsudo cp cloakprobe.service /etc/systemd/system/\n\n# Edit paths if needed\nsudo nano /etc/systemd/system/cloakprobe.service\n\n# Reload systemd\nsudo systemctl daemon-reload\n\n# Enable and start\nsudo systemctl enable cloakprobe\nsudo systemctl start cloakprobe\n```\n\n## Configuration\n\nCloakProbe uses a TOML configuration file for clean, organized settings. Environment variables can override config file values for container deployments.\n\n### Configuration File\n\nCopy the example config and customize:\n\n```bash\ncp cloakprobe.example.toml cloakprobe.toml\n```\n\nConfig file locations (in order of priority):\n1. Path specified with `-c/--config` argument\n2. `./cloakprobe.toml` (current directory)\n3. `/etc/cloakprobe/cloakprobe.toml` (system-wide)\n\nExample configuration:\n\n```toml\n[server]\nbind_address = \"0.0.0.0\"\nport = 8080\nmode = \"cloudflare\"    # \"cloudflare\" or \"nginx\"\nregion = \"eu-central\"  # optional\n\n[privacy]\nmode = \"strict\"        # \"strict\" or \"balanced\"\n\n[database]\nasn_db_path = \"data/asn_db.bin\"\norg_db_path = \"data/orgs_db.bin\"\n```\n\n### Proxy Modes\n\n- **`cloudflare`**: Trust `CF-Connecting-IP` header (default). Use when running behind Cloudflare CDN.\n- **`nginx`**: Trust `X-Real-IP` and `X-Forwarded-For` headers. Use when running behind nginx or other standard reverse proxies without Cloudflare.\n\n### Command Line Options\n\n```bash\ncloakprobe [OPTIONS]\n\nOPTIONS:\n    -c, --config \u003cPATH\u003e    Path to configuration file (TOML)\n    -h, --help             Print help information\n    -v, --version          Print version information\n```\n\n### Environment Variables (Override Config)\n\nEnvironment variables override TOML config values (useful for containers):\n\n- `CLOAKPROBE_BIND_ADDRESS`: IP address to bind to\n- `CLOAKPROBE_PORT`: Port number\n- `CLOAKPROBE_MODE`: Proxy mode (`cloudflare` or `nginx`)\n- `CLOAKPROBE_REGION`: Server region identifier\n- `CLOAKPROBE_PRIVACY_MODE`: Privacy mode (`strict` or `balanced`)\n- `CLOAKPROBE_ASN_DB_PATH`: Path to ASN database\n- `CLOAKPROBE_ORG_DB_PATH`: Path to multi-RIR organization database\n\n**Note**: If database paths are not specified, CloakProbe will automatically search for databases in the `data/` directory.\n\n## API Endpoints\n\n- `GET /` – HTML UI (dark card-based view with detailed IP information)\n- `GET /privacy` – Privacy Policy page (GDPR and CCPA compliant)\n- `GET /api/v1/json` – JSON debug info\n- `GET /api/v1/plain` – Plain text output, convenient for CLI\n- `GET /healthz` – Health check, returns `{\"status\":\"ok\"}`\n\n## Database Updates\n\nCloakProbe uses two databases:\n\n### 1. IP→ASN Database (ip2asn)\n\nUses the **ip2asn-combined.tsv.gz** database from [iptoasn.com](https://iptoasn.com/) (Public Domain / PDDL).\n\n- Format: `range_start range_end AS_number country_code AS_description`\n- Contains both IPv4 and IPv6 ranges.\n- Script: `scripts/update_asn_db.sh`\n- Output: `data/asn_db.bin`\n\n### 2. Multi-RIR Organization Database\n\nUses data from all 5 Regional Internet Registries (RIRs) to map ASN → Organization details.\n\n- **Sources**: RIPE, APNIC, LACNIC, AFRINIC (RPSL format), ARIN (delegated stats fallback)\n- **Data**: org_id, org_name, country, RIR, org_type, abuse_contact, last_updated\n- **Script**: `scripts/update_org_db.sh`\n- **Output**: `data/orgs_db.bin`\n\n### Usage\n\n```bash\ncd /opt/cloakprobe\ncargo build --release\n\n# Update ASN database (IP ranges)\n./scripts/update_asn_db.sh\n\n# Update multi-RIR organization database\n./scripts/update_org_db.sh\n```\n\nThen:\n\n```bash\n# Databases will be automatically found in ./data/ if environment variables are not set\nCLOAKPROBE_PRIVACY_MODE=strict \\\n  ./target/release/cloakprobe\n```\n\nOr explicitly specify database paths:\n\n```bash\nCLOAKPROBE_ASN_DB_PATH=/opt/cloakprobe/data/asn_db.bin \\\nCLOAKPROBE_ORG_DB_PATH=/opt/cloakprobe/data/orgs_db.bin \\\nCLOAKPROBE_PRIVACY_MODE=strict \\\n  ./target/release/cloakprobe\n```\n\n### Cron Example\n\n```cron\n# Update ASN database daily at 3:00 AM\n0 3 * * * /opt/cloakprobe/scripts/update_asn_db.sh \u003e\u003e /var/log/cloakprobe-asn-update.log 2\u003e\u00261\n\n# Update multi-RIR organization database weekly on Sunday at 4:00 AM\n0 4 * * 0 /opt/cloakprobe/scripts/update_org_db.sh \u003e\u003e /var/log/cloakprobe-org-update.log 2\u003e\u00261\n```\n\n---\n\n## Running Behind Nginx\n\n\u003e 📖 **Detailed Nginx Guide**: See [docs/nginx-deployment.md](docs/nginx-deployment.md) for comprehensive nginx configurations including security hardening, Cloudflare IP restrictions, and dual-stack detection setup.\n\n### Quick Setup\n\nCloakProbe supports two proxy modes:\n\n| Mode | Use Case | Trusted Header |\n|------|----------|----------------|\n| `cloudflare` | Behind Cloudflare CDN | `CF-Connecting-IP` |\n| `nginx` | Direct nginx (no CF) | `X-Real-IP` |\n\n**Basic nginx config:**\n\n```nginx\nserver {\n    listen 443 ssl http2;\n    server_name ip.example.com;\n\n    ssl_certificate     /etc/letsencrypt/live/ip.example.com/fullchain.pem;\n    ssl_certificate_key /etc/letsencrypt/live/ip.example.com/privkey.pem;\n\n    location / {\n        proxy_pass http://127.0.0.1:8080;\n        proxy_http_version 1.1;\n\n        proxy_set_header Host              $host;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        \n        # IMPORTANT: Always use $remote_addr to prevent IP spoofing\n        proxy_set_header X-Real-IP         $remote_addr;\n        proxy_set_header X-Forwarded-For   $remote_addr;\n    }\n}\n```\n\n### Security Warning\n\n**Never use `$proxy_add_x_forwarded_for`** - it appends to existing headers, allowing IP spoofing. Always use `$remote_addr`.\n\nFor Cloudflare deployments, restrict connections to Cloudflare IPs only. See [docs/nginx-deployment.md](docs/nginx-deployment.md) for the full security configuration.\n\n### Dual-Stack Detection\n\nFor IPv4/IPv6 network capability detection, deploy multiple instances:\n\n- `ip.example.com` - Primary (Cloudflare, dual-stack)\n- `ip4.example.com` - IPv4-only (A record only)\n- `ip6.example.com` - IPv6-only (AAAA record only, no Cloudflare)\n\nSee [docs/nginx-deployment.md](docs/nginx-deployment.md) for complete setup instructions\n\n---\n\n## Security Headers\n\nThe app sets the following HTTP headers on every response:\n\n- `Content-Security-Policy`\n- `Referrer-Policy`\n- `X-Frame-Options`\n- `Strict-Transport-Security`\n- `X-Content-Type-Options`\n- `Permissions-Policy`\n\nNo external scripts, fonts, or analytics sources; all assets come from the same domain. The only external connection allowed is to `cloudflare-dns.com` for the optional client-side reverse DNS lookup feature (only when user explicitly clicks the lookup button).\n\n### Input Sanitization\n\nAll Cloudflare header values are sanitized before being rendered in HTML to prevent XSS (Cross-Site Scripting) attacks. HTML special characters (`\u003c`, `\u003e`, `\u0026`, `\"`, `'`, `/`) are automatically escaped, ensuring that malicious header values cannot inject JavaScript or HTML into the page.\n\n### Privacy Policy\n\nCloakProbe includes a comprehensive Privacy Policy page (`/privacy`) that is GDPR and CCPA compliant. The policy explains:\n- What data is collected and processed\n- How data is handled (no disk storage, no logging in strict mode)\n- Cloudflare's data processing practices\n- User rights under GDPR and CCPA\n- Security measures implemented\n- Reverse DNS lookup feature (client-side only, on user interaction)\n\nThe privacy policy is accessible from the main page footer and can be viewed at `/privacy`.\n\n### Reverse DNS and ISP Hint Lookup\n\nCloakProbe includes optional client-side DNS lookup features:\n\n**Reverse DNS (PTR) Lookup:**\n- **User-initiated only**: The lookup only happens when the user explicitly clicks the \"Lookup Reverse DNS\" button\n- **Client-side**: Uses Cloudflare DNS over HTTPS (DoH) directly from the browser\n- **No server-side processing**: No data is sent to the CloakProbe server\n- **Privacy-focused**: Cloudflare DoH is privacy-focused and does not log queries\n- **No automatic requests**: The page does not send any external requests automatically\n\n**Authoritative NS (ISP Hint) Lookup:**\n- **Runs in parallel**: When PTR lookup is triggered, NS lookup runs simultaneously\n- **ISP detection**: Extracts ISP/provider domain from nameserver hostnames (e.g., `ns1.telekom.hu` → `telekom.hu`)\n- **Useful for identification**: Helps identify the actual ISP even when reverse DNS hostname doesn't contain the provider name\n\n---\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) first.\n\n## License\n\nThis project is licensed under the **GNU Affero General Public License v3.0** with additional commercial use restrictions.\n\n**Non-commercial use** (personal, educational, research, non-profit) is permitted under AGPL-3.0.\n\n**Commercial use** requires explicit written permission from the copyright holders.\n\nSee [LICENSE](LICENSE) for full details.\n\n## Security\n\nPlease report security vulnerabilities privately. See [SECURITY.md](SECURITY.md) for details.\n\n## Development / Extension\n\n- **Code Structure**: Modular architecture with separate handler modules (`handlers/`), header extraction (`headers/`), utilities (`utils/`), and formatters (`formatters/`)\n- **ASN lookup**: `src/asn.rs` uses a binary prefix-range database from ip2asn.\n- **Tor / VPN detection**:\n  - The `NetworkInfo` struct contains `tor_exit` and `vpn_or_hosting` flags, these default to `false`.\n- **Reverse DNS**:\n  - Client-side reverse DNS lookup is available via the HTML UI using Cloudflare DNS over HTTPS (DoH)\n  - The lookup happens entirely in the browser when the user clicks the \"Lookup Reverse DNS\" button\n  - No server-side reverse DNS lookup is implemented (the API response does not include reverse DNS)\n- **Testing**:\n  - Comprehensive test suite with 70 tests covering handlers, headers, utils, and formatters\n  - All handlers have dedicated test modules\n  - Run tests with `cargo test`\n  - Ensure code passes `cargo fmt` and `cargo clippy` without warnings\n\n## Acknowledgments\n\n- Uses [iptoasn.com](https://iptoasn.com/) data (Public Domain / PDDL)\n- Uses data from all 5 Regional Internet Registries (RIRs): [RIPE NCC](https://www.ripe.net/), [APNIC](https://www.apnic.net/), [LACNIC](https://www.lacnic.net/), [AFRINIC](https://www.afrinic.net/), [ARIN](https://www.arin.net/)\n- Built with [Rust](https://www.rust-lang.org/) and [Axum](https://github.com/tokio-rs/axum)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrmckay%2Fcloakprobe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrmckay%2Fcloakprobe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrmckay%2Fcloakprobe/lists"}