Skip to content

Clarify ngrok Free plan behavior and suggest reverse proxy workaround on quickstart.md#242

Open
minnsou wants to merge 1 commit intomicromdm:mainfrom
minnsou:patch-1
Open

Clarify ngrok Free plan behavior and suggest reverse proxy workaround on quickstart.md#242
minnsou wants to merge 1 commit intomicromdm:mainfrom
minnsou:patch-1

Conversation

@minnsou
Copy link
Copy Markdown

@minnsou minnsou commented Mar 10, 2026

The current quickstart suggests using two ngrok tunnels for the SCEP server
and NanoMDM server and provides a workaround using the tunnels stanza
when the user encounters the "1 simultaneous ngrok agent" limitation.

However, with modern versions of ngrok (v3) on the Free plan, multiple HTTP
tunnels may be multiplexed onto the same public hostname. In practice this
can result in output like:

Forwarding     https://abcd1234.ngrok-free.dev -> localhost:8080
Forwarding     https://abcd1234.ngrok-free.dev -> localhost:9000

In this situation both the SCEP server and NanoMDM server are exposed under
the same hostname, which prevents configuring separate URLs in the
enrollment profile as described later in this guide.

This PR adds a short note explaining this behavior and suggests a simple
workaround: running a local reverse proxy (e.g. nginx) and exposing a
single ngrok endpoint while routing paths to the appropriate backend
services.

Example routing:

/scep -> localhost:8080
/mdm  -> localhost:9000

This keeps the quickstart simple while allowing the guide to work correctly
with ngrok v3 Free accounts.

Clarify ngrok Free plan behavior and suggest reverse proxy workaround
@jessepeterson
Copy link
Copy Markdown
Member

[...] which prevents configuring separate URLs in the
enrollment profile as described later in this guide.

It's unclear why this is a requirement just because it's mentioned in the guide. The separate URLs are just a byproduct of ngrok generating separate hostnames in the past. For example MicroMDM has used a single URL from the get-go.

@minnsou
Copy link
Copy Markdown
Author

minnsou commented Mar 11, 2026

Thanks for the clarification — I agree that separate hostnames are not
strictly required. Using a single hostname with path routing (e.g. /scep
and /mdm) works fine when a reverse proxy is present.

However the quickstart currently runs both services directly behind ngrok
without a reverse proxy. With ngrok Free plan behavior, multiple tunnels
may share the same public hostname.

Example ngrok config:

version: 2
authtoken: xxxxxxxxxxxxxxxxxxxxx
tunnels:
  scep:
    proto: http
    addr: 8080
  nanomdm:
    proto: http
    addr: 9000

Example result:

Forwarding https://abcd1234.ngrok-free.dev -> http://localhost:8080
Forwarding https://abcd1234.ngrok-free.dev -> http://localhost:9000

In this case ngrok does not route based on path. Instead it effectively
load-balances requests between the upstream services. As a result,
requests to /scep or /mdm may be forwarded to either port, which
breaks the enrollment flow.

For example:

https://abcd1234.ngrok-free.dev/scep -> 8080 or 9000
https://abcd1234.ngrok-free.dev/mdm  -> 8080 or 9000

This means the workaround using the tunnels stanza may not work as
expected on Free accounts unless an additional reverse proxy (e.g.
nginx) is introduced to perform path-based routing.

My intention with the note was to clarify this behavior and suggest a
reverse proxy workaround so the quickstart works reliably with modern
ngrok setups.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants