README
¶
SOAX ECH GREASE Report Generation
This tool tests ECH GREASE compatibility by issuing requests via SOAX proxies. It iterates through a list of countries and ISPs, running tests with and without ECH GREASE to simulate diverse network vantage points.
Requirements
You need to build the ECH-enabled curl and place it in the workspace directory. See instructions.
You also need to set the SOAX credentials as environment variables and provide a list of ISO country codes.
(Optional) ASN Validation: To independently verify the ASN of the proxy exit nodes, you can provide a local IP-to-ASN database in .mmdb format (such as MaxMind GeoLite2 or DB-IP ASN Lite).
Configuration
SOAX Credentials (Environment Variables)
Set the following environment variables with your SOAX API details:
export SOAX_API_KEY="YOUR_API_KEY"
export SOAX_PACKAGE_KEY="YOUR_PACKAGE_KEY"
export SOAX_PACKAGE_ID="YOUR_PACKAGE_ID"
# Optional overrides:
# export SOAX_PROXY_HOST="proxy.soax.com"
# export SOAX_PROXY_PORT="5000"
Country List (countries.csv)
The countries file should be a CSV file containing country names and their 2-letter ISO codes. Lines starting with # are ignored.
"United States",US
"United Kingdom",GB
"Germany",DE
# Add more countries as needed
"Virgin Islands, U.S.",VI
You can download a complete list of country codes from here.
Running
To run the tool, ensure your environment variables are set, then use the go run command from the project root directory.
Basic Run:
go run ./ispreport --targetDomain www.google.com
With Independent ASN Validation (Recommended):
First, download a free IP-to-ASN .mmdb database (e.g., from DB-IP) to your workspace.
go run ./ispreport --targetDomain www.google.com --asnDB workspace/dbip-asn-lite.mmdb
With Custom IP Check URL and Verbose Logging:
go run ./ispreport --targetDomain www.google.com --ipCheckURL https://ifconfig.me/ip --verbose
This will:
- Load the SOAX credentials from the environment and the country list (
./workspace/countries.csvby default). - For each country, fetch the list of available ISPs.
- For each ISP, discover the real proxy exit IP via the
ipCheckURL. - Issue requests to the target domain via the SOAX proxy, once with ECH GREASE and once without.
- Save the results to
./workspace/ispreport/results-<domain>-countries<N>.csv.
Parameters
-workspace <path>: Directory to store intermediate files. Defaults to./workspace.-countries <path>: Path to CSV file containing country names and ISO codes. Defaults to./workspace/countries.csv.-targetDomain <domain>: Target domain to test. Defaults towww.google.com.-parallelism <number>: Maximum number of parallel requests. Defaults to16.-verbose: Enable verbose logging.-maxTime <duration>: Maximum time per curl request. Defaults to30s.-curl <path>: Path to the ECH-enabled curl binary. Defaults to./workspace/output/bin/curl.-ipCheckURL <url>: URL used to discover the real external IP of the proxy. Defaults tohttps://ipv4.icanhazip.com/.-asnDB <path>: Optional path to a MaxMind or DB-IP.mmdbdatabase file for independent ASN verification.
Output Format
The tool generates two output files in the workspace directory:
- Results CSV (
workspace/ispreport/results-<domain>-countries<N>.csv): Contains the detailed test results for each request. - ISP Audit Log (
workspace/ispreport/isps-audit.json): A JSON file mapping each country code to the list of ISPs discovered and used during the test. This is useful for auditing coverage.
The CSV file contains the following columns:
domain: The domain that was tested.country_code: The 2-letter ISO country code.country_name: The full name of the country.isp: The ISP name of the proxy used.asn: The ASN of the proxy exit node as reported by the SOAX proxy headers.exit_node_isp: The ISP name reported by the SOAX proxy headers.geodb_asn: The ASN corresponding to thediscovered_ip, looked up in the-asnDB(if provided).geodb_as_name: The AS organization name corresponding to thediscovered_ip, looked up in the-asnDB(if provided).asn_match:trueif the SOAX-reportedasnmatches thegeodb_asn,falseotherwise.ech_grease:trueif ECH GREASE was enabled for the request,falseotherwise.go_error: Any error that occurred during the request.curl_exit_code: The exit code returned by thecurlcommand.curl_error_name: The human-readable name corresponding to thecurlexit code.curl_error_message: The detailed error message from curl (if available).dns_lookup_ms: The duration of the DNS lookup.tcp_connection_ms: The duration of the TCP connection.tls_handshake_ms: The duration of the TLS handshake.server_time_ms: The time from the end of the TLS handshake to the first byte of the response.total_time_ms: The total duration of the request.http_status: The HTTP status code of the response.http_connect_status: The HTTP status code from the proxy connection.
Generating the Final Report
After running the data collection tool, you can generate a visual report using the provided Jupyter notebook.
1. Organize the Data
The notebook expects data to be organized in subdirectories within ispreport/report/ named after the tested domain.
-
Create a subdirectory for your results (e.g., for
www.google.com):mkdir -p ispreport/report/www_google_com -
Copy and rename the generated results from the
workspacedirectory:# Use a wildcard to match the generated file with the number of countries cp workspace/ispreport/results-www_google_com-countries*.csv ispreport/report/www_google_com/results.csv cp workspace/ispreport/isps-audit.json ispreport/report/www_google_com/isps-audit.json
2. Setup the Environment
Running the notebook requires Python 3 and several data analysis libraries.
# From the project root:
# 1. Create the virtual environment if it doesn't exist
python3 -m venv workspace/.venv
# 2. Activate the virtual environment
source workspace/.venv/bin/activate
# 3. Install required dependencies
pip install pandas numpy matplotlib seaborn ipywidgets jupyter
3. Run the Notebook
-
Navigate to the report directory and start Jupyter:
cd ispreport/report # If you didn't activate the venv yet, run: source ../../workspace/.venv/bin/activate jupyter notebook report.ipynb -
In the first code cell of the notebook, update the
DOMAINvariable to match the name of the subdirectory you created (e.g.,DOMAIN = "www_google_com"). -
Run all cells in the notebook to generate the analysis and visualizations.
Documentation
¶
There is no documentation for this package.