Hosted oneric.vicenti.netvia theHypermedia Protocol

Document cover
Jean Web Access behind TailscaleA practical guide to running Jean Web Access behind Tailscale, explaining how to bind jean-server to localhost and publish it through Tailscale Serve so browsers, phones, and native apps can all connect reliably over HTTPS.

If Jean Web Access works in a browser but the native Jean app, phone, or another tailnet device cannot connect, check whether Jean is being reached directly over HTTP or through Tailscale Serve.

Recommended setup

Use Tailscale Serve as the tailnet entrypoint and bind jean-server to localhost:

# /etc/jean-server.env JEAN_HOST=127.0.0.1 JEAN_PORT=3456 JEAN_TOKEN=<long-random-token> JEAN_ALLOWED_ORIGINS=*

Restart Jean and publish it through Tailscale Serve:

sudo systemctl restart jean-server.service sudo tailscale serve --https=443 off sudo tailscale serve --bg http://127.0.0.1:3456 tailscale serve status

Use the HTTPS Tailscale Serve URL everywhere, including phones and the native Jean desktop app:

https://<machine-name>.<tailnet-name>.ts.net/?token=<JEAN_TOKEN>

<machine-name> is the device name in Tailscale. You can choose any name you want in Tailscale (for example, jean-server, build-box, or home-lab) and use that name in the URL.

For example, if you named the device jean-server in Tailscale:

https://jean-server.tail71152.ts.net/?token=<JEAN_TOKEN>

Why the direct Tailscale IP may stop working

When JEAN_HOST=127.0.0.1, Jean only listens on the server itself. That is intentional for the recommended Tailscale Serve setup. Other tailnet devices cannot connect directly to:

http://100.x.y.z:3456

They must use the Tailscale Serve HTTPS URL instead. Tailscale Serve receives the tailnet HTTPS request and proxies it locally to http://127.0.0.1:3456 on the server.

Quick checks

From any tailnet device, these should return 200 OK:

curl -i https://<machine-name>.<tailnet-name>.ts.net/readyz curl -i 'https://<machine-name>.<tailnet-name>.ts.net/api/auth?token=<JEAN_TOKEN>'

Expected /readyz body:

{"http":true,"ok":true,"websocket_broadcaster":true}

If the HTTPS URL returns a proxy error, confirm jean-server is listening on 127.0.0.1:3456 and restart Tailscale Serve.

Is this a Jean issue?

This is mostly a deployment/configuration gotcha for Jean servers behind a tailnet, not a core Jean server bug. The confusing part is that there are two valid modes:


    Tailscale Serve mode (recommended): JEAN_HOST=127.0.0.1, connect with https://...ts.net/?token=....

    Direct tailnet HTTP mode: JEAN_HOST=100.x.y.z or 0.0.0.0, connect with http://100.x.y.z:3456/?token=....

The modes are easy to mix up. If Jean binds to localhost, direct Tailscale IP access will fail. If Jean binds to the Tailscale IP, Tailscale Serve must proxy to that IP instead of 127.0.0.1, or it will fail.

Related

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime