Multiple Iran-ISP users (#924 Recruit1992, #913 ehsan272727) report that ngrok's free tier now exclusively hands out *.ngrok-free.dev domains for new accounts, with no path to claim the older *.ngrok-free.app TLD. Some Iran ISPs (TCI, Irancell, IRMCI confirmed) block *.ngrok-free.dev at DNS or TCP. Symptom: curl from Iran network to ngrok URL times out, but works from non-Iran. Updates README.md and ngrok.md to: 1. Note the ngrok TLD shift (.app grandfathered, .dev for new accounts). 2. List ISPs confirmed to block *.ngrok-free.dev. 3. Add an "Alternative hosts" section recommending HuggingFace Spaces (Docker SDK) as the most Iran-friendly option in 2026 — permanent *.hf.space URL with no tunnel layer. 4. Update the URL behavior column for Method 2 since ngrok now gives a permanent dev domain by default (not "new URL each session"). No code changes — docs only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.4 KiB
ngrok Tunnel
Run a Full tunnel for 6 hours using an ngrok account (free tier). ngrok provides a public URL that exposes the tunnel-node running on GitHub Actions.
Prerequisites
- A GitHub account (free)
- An ngrok account (free — sign up at ngrok.com)
CodeFull.gsdeployed as a Google Apps Script Web App
Setup
Step 1: Get Your ngrok Authtoken
- Go to dashboard.ngrok.com and sign in
- Copy your authtoken from the Getting Started or Your Authtoken section
Step 2: Create the Repository
If you already have a repository from another method, you can reuse it. Otherwise:
- Go to github.com and sign in
- Click the + icon in the top-right corner, then New repository
- Enter a repository name (e.g.,
my-tunnel) - Select Private (recommended — keeps your secrets secure)
- Click Create repository
Step 3: Add the Secrets
-
In your repository, go to Settings > Secrets and variables > Actions
-
Click New repository secret and add:
Name Value TUNNEL_AUTH_KEYA strong password. You will also set this in CodeFull.gs.NGROK_AUTH_TOKENYour ngrok authtoken from Step 1. -
Click Add secret for each
Step 4: Add the Workflow
- In your repository, go to the Actions tab
- Click New workflow
- Click the set up a workflow yourself link
- Delete the default content and paste the contents of
ngrok.yml[here] - Click Commit changes..., add a commit message, then click Commit changes
The workflow file will be saved to .github/workflows/ngrok.yml.
Step 5: Run the Workflow
- Go to the Actions tab
- Select Full Tunnel (ngrok) from the left sidebar
- Click Run workflow > Run workflow
The workflow will start immediately.
Step 6: Get the Tunnel URL
- Click on the running workflow to see live logs
- Wait for the Expose tunnel step to complete (about 10 seconds)
- Look for the
::notice::Tunnel URL:line in the log output - Copy the URL — it will look like
https://abc123.ngrok-free.app
Step 7: Configure CodeFull.gs
Open CodeFull.gs in the Google Apps Script editor and update these constants:
const TUNNEL_SERVER_URL = "https://abc123.ngrok-free.app";
const TUNNEL_AUTH_KEY = "the-secret-you-set-in-step-3";
Deploy: Deploy > New Deployment > Web App.
Copy the new Deployment ID and update your mhrv-rs config.
Step 8: Verify
mhrv-rs test is wired only for the apps_script relay path; in Full mode it
refuses to run. To verify a Full-mode tunnel, visit https://ipleak.net (or
https://whatismyipaddress.com) through your proxy — you should see a
GitHub Actions or ngrok IP address.
How It Works
- GitHub Actions starts a Docker container running
mhrv-tunnel-nodeon port8080 ngrokcreates a secure tunnel using your authtoken, assigning a temporary*.ngrok-free.appURL that routes tolocalhost:8080on the runner- The workflow extracts this URL from the ngrok API and displays it
CodeFull.gsforwards tunnel operations to this URL over HTTPS- The runner stays alive for 6 hours, then shuts down automatically
Renewing the Tunnel
The tunnel shuts down after 6 hours. To start a new session:
- Go to the Actions tab
- Select Full Tunnel (ngrok)
- Click Run workflow > Run workflow
- Check the tunnel URL in the logs. Each ngrok free account gets one
auto-assigned dev domain that's permanent across runs — the URL is the
same every time you re-run the workflow, so no
CodeFull.gsupdate is needed after the initial setup.
Limitations
- Requires an ngrok account (free tier: 1 online tunnel, limited connections per minute).
- ngrok TLD note: ngrok handed out
*.ngrok-free.appdomains until early 2026; new free-tier accounts now get*.ngrok-free.devinstead, with no way to switch back. Some Iran ISPs block*.ngrok-free.devat the DNS layer. If your tunnel works on a non-Iran network butcurlfrom your Iran network times out at TCP, the.devblock is why. Workarounds:- Switch to cloudflared Quick (Method 1) — different TLD, often passes
where ngrok's
.devdoesn't. - Switch to HuggingFace Spaces (Docker) — run tunnel-node directly on
a Space, get a permanent
*.hf.spaceURL with no tunnel layer. - Pay for ngrok's $10/mo Personal plan to get a
*.ngrok.appdomain (the older, more widely allowlisted TLD).
- Switch to cloudflared Quick (Method 1) — different TLD, often passes
where ngrok's
- 6-hour maximum per session (GitHub Actions limit).
- Slightly higher latency than cloudflared methods (extra hop through ngrok's relay servers).
Troubleshooting
| Problem | Solution |
|---|---|
| ngrok authentication fails | Verify NGROK_AUTH_TOKEN matches the token in your ngrok dashboard. |
| Workflow fails at Docker step | GitHub Actions may be pulling the image for the first time. Wait 2-3 minutes and retry. |
| No tunnel URL appears in logs | Check that the Expose tunnel step completed. The URL is fetched from the ngrok API — allow 10 seconds for the tunnel to establish. |
| Connection limit reached | ngrok's free tier limits connections per minute. Wait a moment and retry. |
CodeFull.gs returns 502 or timeout |
Verify the tunnel URL is correct and the workflow is still running. Check that TUNNEL_AUTH_KEY matches in both the secret and CodeFull.gs. |