|
1 | | -# 🪞 Reflex |
| 1 | +## reflex — HTTPS referrer emulation for analytics testing |
2 | 2 |
|
3 | | -**Simulate Referrer-Based Traffic with HTTPS Redirects** |
| 3 | +**Reflex** is a lightweight CLI tool helps growth, marketing, and analytics teams reliably emulate inbound referrals (e.g., from `https://news.google.com`) in modern browsers. It does this by: |
4 | 4 |
|
5 | | -**Reflex** is a lightweight CLI tool for developers and QA engineers to simulate web traffic that appears to originate from trusted domains like `news.google.com`. It’s ideal for testing A/B experiments, analytics triggers (e.g. Piano, Adobe Target), or any system that relies on referrer headers. |
| 5 | +- Mapping a chosen referrer hostname to your machine via the system hosts file |
| 6 | +- Serving a locally trusted HTTPS site for that hostname (certs via mkcert) |
| 7 | +- Issuing a redirect (302/meta/JS) to your target URL so the browser sends the correct `Referer` |
6 | 8 |
|
7 | | -> ⚡️ _“Redirect. Spoof. Test. Repeat.”_ |
| 9 | +This enables safe, repeatable end-to-end tests of attribution, A/B splits, and analytics pipelines without fragile header spoofing extensions. |
8 | 10 |
|
9 | | ---- |
| 11 | +Important: This tool modifies your hosts file and runs a local HTTPS server. It restores cleanly on exit, and you can run `reflex cleanup` at any time. |
10 | 12 |
|
11 | | -## 🚀 Features |
| 13 | +How it works |
12 | 14 |
|
13 | | -- ✅ Simulates traffic with any `Referer` value |
14 | | -- 🔒 HTTPS redirect server with trusted local certs (via `mkcert`) |
15 | | -- 🛠️ Safe modification & restoration of `/etc/hosts` |
16 | | -- 🌐 Automatically opens browser to spoofed domain |
17 | | -- 🔁 Auto-fallback from port 443 → 8443 |
18 | | -- 🧹 Cleanup certs and hosts on exit |
19 | | -- 🐧 macOS + Linux support |
| 15 | +- Host spoof: Adds a tagged line like `127.0.0.1 news.google.com # reflex-managed` to your hosts file |
| 16 | +- HTTPS: Generates a locally trusted certificate for the hostname with `mkcert` |
| 17 | +- Redirect: Serves a small HTTPS site on that host which redirects to your target; the browser sends a real `Referer` header per current referrer policies |
20 | 18 |
|
21 | | ---- |
| 19 | +Install |
22 | 20 |
|
23 | | -## 🔧 Use Cases |
| 21 | +- Requires Go 1.21+ for building |
| 22 | +- Requires `mkcert` (https://github.com/FiloSottile/mkcert) |
| 23 | +- Requires sudo/admin privileges (the CLI runs with sudo) |
24 | 24 |
|
25 | | -- ✅ Test A/B testing platforms (Adobe Target, Optimizely, etc.) |
26 | | -- ✅ Validate analytics pipelines (Piano, GA, Segment, etc.) |
27 | | -- ✅ Simulate traffic from social media, news aggregators, or search engines |
28 | | -- ✅ Reproduce edge-case behaviors (like `document.referrer` logic) |
| 25 | +Build from source |
29 | 26 |
|
30 | | ---- |
| 27 | +- `go build ./cmd/reflex` |
| 28 | +- Or: `go run ./cmd/reflex --help` |
| 29 | + |
| 30 | +One-time Setup (Linux) |
| 31 | + |
| 32 | +To avoid the common "no Firefox/Chrome security databases found" issue when running under sudo, pin a shared CAROOT used by both root and your user. |
| 33 | + |
| 34 | +1. Install the local CA into the system trust store and your user’s browser trust store: |
| 35 | + |
| 36 | +- `sudo mkcert -install` # system trust store |
| 37 | +- `mkcert -install` # your user’s Firefox/Chromium trust |
| 38 | + |
| 39 | +2. Pin a shared CAROOT so root and user use the same CA: |
| 40 | + |
| 41 | +- `sudo mkdir -p /etc/mkcert` |
| 42 | +- `sudo cp -a "$(mkcert -CAROOT)/." /etc/mkcert/` |
| 43 | +- `sudo chmod 755 /etc/mkcert && sudo chmod 644 /etc/mkcert/*` |
| 44 | + |
| 45 | +After this, reflex (which runs with sudo) uses `/etc/mkcert` automatically to generate certs that match your user’s trusted CA. |
| 46 | + |
| 47 | +Notes for other platforms: |
| 48 | + |
| 49 | +- macOS: `brew install mkcert nss && sudo mkcert -install` (no pinned CAROOT needed) |
| 50 | +- Windows: `choco install mkcert` then `mkcert -install` in an elevated shell |
| 51 | + |
| 52 | +Run with sudo |
| 53 | + |
| 54 | +- reflex requires elevated privileges to modify `/etc/hosts` and bind to port 443. |
| 55 | +- Always run commands with sudo, e.g.: `sudo reflex run --referrer ... --target ...` |
| 56 | + |
| 57 | +Quick start |
| 58 | + |
| 59 | +- Spoof Google News and redirect to your site: |
| 60 | + - `reflex run --referrer https://news.google.com --target https://your-app.example` |
| 61 | + |
| 62 | +Commands |
| 63 | + |
| 64 | +- `reflex run`: Start HTTPS server, spoof host, and open browser |
| 65 | +- `reflex cleanup`: Remove hosts entry and generated certificates for a host; add `--all` to remove all reflex-managed entries, all certs, and the lock |
| 66 | +- `reflex status`: Inspect whether hosts entry and certs exist |
| 67 | + |
| 68 | +Run options |
| 69 | + |
| 70 | +- `--referrer`: Referrer URL or hostname (required) |
| 71 | +- `--target`: Target URL to navigate to (required) |
| 72 | +- `--method`: Redirect strategy: meta (default), 302, js |
| 73 | +- `--delay`: Delay for meta/js methods in ms (default 1500) |
| 74 | +- `--port`: TLS port (default 443). Falls back to 8443 if unavailable |
| 75 | +- `--no-browser`: Do not open the browser automatically |
| 76 | +- `--private`: Open browser in incognito/private mode (default true) |
| 77 | +- `--keep-certs`: Keep generated certs after exit |
| 78 | +- `--no-hosts`: Do not modify hosts (advanced) |
| 79 | +- `--force-unlock`: Forcefully clear a stale lock before starting |
| 80 | +- `--referrer-policy`: Explicit Referrer-Policy for the referrer page (default `origin-when-cross-origin`). Use `unsafe-url` to send the full URL to cross-origin targets. |
| 81 | + |
| 82 | +Notes |
| 83 | + |
| 84 | +- Elevated privileges: Binding to 443 and editing the hosts file typically require admin/sudo |
| 85 | +- If 443 is busy or you lack privileges, the server falls back to 8443 and opens `https://<host>:8443` |
| 86 | +- Modern default referrer policy is `strict-origin-when-cross-origin`, so your target receives at least the origin |
| 87 | +- HSTS domains: A valid, trusted certificate is required. `mkcert` provides a locally trusted CA for this purpose. Reflex now runs `mkcert -install` for you (idempotent) before generating certs; if it fails, you’ll see a clear instruction. |
| 88 | + |
| 89 | +Cleanup and safety |
| 90 | + |
| 91 | +- Tagged hosts entries let reflex remove only what it added |
| 92 | +- A timestamped backup of the hosts file is created adjacent to the file on first write |
| 93 | +- On exit or `reflex cleanup --referrer <host>`, reflex removes the tagged line and generated certs (unless `--keep-certs`) |
| 94 | + |
| 95 | +Troubleshooting |
| 96 | + |
| 97 | +- Browser blocks the page: Ensure `mkcert` is installed and its root CA is trusted |
| 98 | +- Empty `document.referrer`: Set `--referrer-policy origin-when-cross-origin` (default) for origin referrers, or `--referrer-policy unsafe-url` to send the full path. You can also try `--method meta` or `--method js` if your stack handles those better. |
| 99 | +- Linux note: If you see "no Firefox and/or Chrome/Chromium security databases found" while using sudo, complete the One-time Setup above to pin a shared CAROOT at `/etc/mkcert`. |
| 100 | +- Wrong host is opened: Verify the URL shown by the tool and that your browser didn’t cache an older page |
| 101 | +- Hosts entry doesn’t apply: Some VPN/enterprise setups override name resolution; try disabling the VPN temporarily |
| 102 | + |
| 103 | +Development |
| 104 | + |
| 105 | +- Code layout: |
| 106 | + - `cmd/reflex`: CLI entrypoint and subcommands |
| 107 | + - `internal/hosts`: Safe hosts file management with tagged lines |
| 108 | + - `internal/certs`: mkcert integration and cert lifecycle |
| 109 | + - `internal/server`: HTTPS server and redirect strategies |
| 110 | + - `internal/browser`: Cross-platform browser opener |
| 111 | + - `internal/util`: Utilities (hostname parsing, port probing, locking) |
| 112 | +- Tests: `internal/hosts` and `internal/util` include basic unit tests you can run with `go test ./...` |
| 113 | + |
| 114 | +Roadmap |
| 115 | + |
| 116 | +- Optional DNS-based spoofing mode (no hosts edits) |
| 117 | +- CAP_NET_BIND_SERVICE support on Linux to bind 443 without root |
| 118 | +- UI control panel and session recorder |
| 119 | +- Native installers and signed binaries |
0 commit comments