Secure Remote Ollama Access with Tailscale
Reach your Ollama fleet from anywhere over Tailscale, without exposing a single inference node to the public internet.
The safest simple way to use an Ollama fleet away from home or the office is to expose one Ollama Herd router through a private Tailscale network, not every Ollama node through public port forwarding. Your laptop, automation server, or phone reaches one stable endpoint; Herd continues routing requests to the available machines behind it.
Tailscale encrypts traffic between Tailnet devices. Tailscale Serve can also give the router a private HTTPS name, while Tailnet access controls decide which users or devices may reach it.
Do not use Tailscale Funnel for a private Ollama API. Funnel makes a local service reachable from the broader internet. Use Serve for Tailnet-only access unless you have deliberately added application authentication, rate limiting, and public-gateway controls.
Architecture
Remote laptop / n8n / Open WebUI
|
| encrypted Tailnet connection
v
Ollama Herd router :11435
one private endpoint
/ | \
v v v
Ollama node Ollama node embedding / MLX node
LAN or Tailnet-connected fleet
The router is the only address remote clients need. Inference nodes can remain on a trusted LAN, or every node can join the Tailnet for a fully private overlay network.
Choose one of two designs
Design A: Put every fleet machine on Tailscale
Use this when nodes are spread across locations, the LAN is untrusted, or you want one consistent network.
- Install Tailscale on the router, every node, and every client.
- Bind the router to its Tailscale IP.
- Start each node with an explicit Tailnet router URL.
- Restrict port
11435with Tailnet access controls.
This design does not depend on mDNS, which normally stays within a local broadcast domain.
Design B: Put only the router on Tailscale
Use this when all inference nodes are already on one trusted LAN.
- Node agents discover or reach the router over the LAN.
- Remote clients reach the same router over its Tailscale address or Tailscale Serve URL.
- The host firewall limits who can reach port
11435.
This is the least disruptive option, but the router still listens on a LAN interface unless you add more specific binding or firewall rules.
Prerequisites
- A working Ollama Herd fleet
- Tailscale installed on the router and remote client
- Tailscale installed on every node for Design A
- Permission to edit Tailnet access controls when restrictions are required
Verify the local fleet first:
curl -s http://localhost:11435/fleet/status | python3 -m json.tool
Design A: all fleet machines on the Tailnet
Step 1: get the router's Tailscale address
On the router machine:
tailscale ip -4
Example result:
100.96.12.34
Treat that as an example only. Each Tailnet assigns its own stable address.
Step 2: bind Herd to the Tailscale IP
Ollama Herd's default bind address is 0.0.0.0, which listens on every interface. For a Tailnet-only router, bind it to the Tailscale address:
FLEET_HOST=100.96.12.34 herd
For a background service, put the setting in the service environment or Herd environment file rather than a temporary shell.
Verify on the router:
curl -s http://100.96.12.34:11435/api/tags | python3 -m json.tool
Step 3: connect every node directly
On each fleet node:
herd-node --router-url http://100.96.12.34:11435
The traffic is HTTP at the application layer, but it travels inside Tailscale's encrypted network connection.
Check that every node appears:
curl -s http://100.96.12.34:11435/fleet/status | python3 -m json.tool
Step 4: connect a remote client
From another Tailnet device:
curl -i http://100.96.12.34:11435/api/chat \
-H "Content-Type: application/json" \
-d '{
"model": "llama3.2:3b",
"messages": [{"role": "user", "content": "Reply with remote access working."}],
"stream": false
}'
A successful response and an X-Fleet-Node header prove that the remote request reached the router and was handled by a fleet node.
Design B: trusted LAN nodes, Tailnet clients
Run Herd normally on the router:
herd
The default router bind is 0.0.0.0:11435, so the same service can accept node traffic over the LAN and client traffic over Tailscale. Confirm that the operating-system firewall allows only the required LAN and Tailscale sources.
Remote clients can use the router's Tailscale IP:
http://100.96.12.34:11435
The LAN nodes can continue using mDNS or an explicit LAN URL.
This design exposes only one inference API to the Tailnet. Do not separately expose each node's Ollama port unless a specific maintenance workflow requires it.
Add a private HTTPS name with Tailscale Serve
Some clients prefer or require an HTTPS URL. Tailscale Serve proxies a private Tailnet URL to a local backend. Current Tailscale documentation limits HTTP reverse-proxy targets to localhost, so Herd must answer on 127.0.0.1:11435 for this layout.
Herd's default 0.0.0.0:11435 bind includes localhost. Confirm the local path first:
curl -s http://127.0.0.1:11435/api/tags | python3 -m json.tool
Then create the persistent Serve proxy:
tailscale serve --bg http://127.0.0.1:11435
If Design A binds Herd only to its 100.x.x.x Tailscale address, use the direct Tailnet URL instead of Serve, or change the router layout so Herd is also reachable on localhost. Do not silently broaden the bind without reviewing the host firewall and LAN exposure.
Check the assigned URL:
tailscale serve status
It will resemble:
https://ollama-router.example-tailnet.ts.net
Test it from another Tailnet device:
curl -s https://ollama-router.example-tailnet.ts.net/api/tags \
| python3 -m json.tool
Tailscale Serve requires Tailnet HTTPS support. Tailscale notes that HTTPS certificate names are recorded in public Certificate Transparency logs, even though access to the service remains restricted by the Tailnet. Use a non-sensitive machine name.
Direct Tailnet IP or Serve URL?
| Option | Advantages | Tradeoffs |
|---|---|---|
http://100.x.x.x:11435 |
Minimal layers, stable address, encrypted by Tailscale | Some clients warn because the URL itself is HTTP |
https://name.tailnet.ts.net through Serve |
Browser-friendly HTTPS, MagicDNS name, Tailnet access controls | Requires HTTPS setup; certificate hostname is publicly logged |
Use the direct IP for service-to-service calls when plain HTTP URLs are accepted. Use Serve when a client insists on HTTPS or a readable private hostname improves operations.
Restrict access with Tailnet grants
Do not assume that every Tailnet member should use the AI router or view its dashboard. Limit the destination ports to the users or devices that need them.
A conceptual grants policy looks like this:
{
"groups": {
"group:ai-users": [
"alice@example.com",
"bob@example.com"
]
},
"tagOwners": {
"tag:ollama-herd": ["autogroup:admin"]
},
"grants": [
{
"src": ["group:ai-users"],
"dst": ["tag:ollama-herd"],
"ip": ["tcp:11435", "tcp:443"]
}
]
}
Tag the router as tag:ollama-herd, adapt the identities and ports, and validate the policy in the Tailscale admin console. When using only Tailscale Serve, port 443 may be sufficient for clients. Keep direct port 11435 only when clients use the raw Tailnet address.
Access controls protect the network path. They do not create per-request application roles inside Herd.
Configure common clients
OpenAI-compatible SDK
from openai import OpenAI
client = OpenAI(
base_url="https://ollama-router.example-tailnet.ts.net/v1",
api_key="not-needed",
)
response = client.chat.completions.create(
model="llama3.2:3b",
messages=[{"role": "user", "content": "Hello from the road"}],
)
print(response.choices[0].message.content)
Open WebUI
Set its Ollama connection to either:
http://100.96.12.34:11435
or:
https://ollama-router.example-tailnet.ts.net
n8n
Use the same URL as the Base URL in the Ollama credential. If n8n is in Docker, verify that its container can resolve and route to the Tailnet name or IP.
Ollama API client
curl https://ollama-router.example-tailnet.ts.net/api/chat \
-d '{
"model": "llama3.2:3b",
"messages": [{"role": "user", "content": "Hello"}],
"stream": false
}'
Security checklist
- Expose the Herd router, not every Ollama node.
- Keep the service private to the Tailnet.
- Use Tailnet grants or access controls for least privilege.
- Do not use Funnel for a private AI API.
- Do not enable full request-body debug capture on a shared or untrusted gateway; it records prompts and responses.
- Protect the dashboard because it reveals node, model, workload, and performance information.
- Treat a lost or unmanaged client device as a credential risk and remove it from the Tailnet.
- Use an authenticated reverse proxy when application-level user identity, audit, quotas, or keys are required.
- Review whether models or tools can perform privileged actions before granting broad remote access.
Troubleshooting
The Tailnet IP works on the router but not remotely
Check:
tailscale status
tailscale ping 100.96.12.34
Then confirm Herd is listening on the Tailscale address and that access controls permit the destination port.
Nodes disappear after binding Herd to the Tailscale IP
Every node must be on Tailscale and must use the explicit Tailnet router URL. LAN mDNS discovery will not automatically cross into an overlay network.
herd-node --router-url http://100.96.12.34:11435
Tailscale Serve returns an error
Confirm Herd works locally:
curl -s http://127.0.0.1:11435/api/tags
Then inspect Serve:
tailscale serve status
Reset and recreate the proxy when the target is wrong:
tailscale serve reset
curl -s http://127.0.0.1:11435/api/tags | python3 -m json.tool
tailscale serve --bg http://127.0.0.1:11435
If the local curl fails because Herd is bound only to a Tailscale IP, keep using the direct http://100.x.x.x:11435 route or revise the bind and firewall policy before enabling Serve.
The HTTPS hostname does not resolve
Confirm MagicDNS and HTTPS support are enabled for the Tailnet and that the client uses Tailscale DNS.
A client connects but model requests fail
The network path is working. Check Herd separately:
curl -s https://ollama-router.example-tailnet.ts.net/fleet/status \
| python3 -m json.tool
Look for offline nodes, missing models, memory pressure, queue saturation, or a model name that does not exactly match the fleet list.
The dashboard is reachable by too many people
Narrow the Tailnet grant or place an authenticated proxy in front of the dashboard. Network membership is not the same as authorization to view operational data.
Frequently asked questions
Is HTTP over a Tailscale IP encrypted?
Yes. Tailscale encrypts the network connection between Tailnet devices. HTTPS is still useful for client compatibility, service identity, and browser expectations.
Should I set OLLAMA_HOST=0.0.0.0 on every node?
Not for remote client access. Remote clients only need the Herd router. Node agents can proxy or reach their local Ollama instance as designed. Minimize exposed services.
Does Tailscale replace Herd?
No. Tailscale provides private connectivity and identity at the network layer. Herd discovers and routes inference workloads across machines. They are complementary.
Does Herd authenticate individual users?
The core router is designed for a trusted network boundary. Tailnet access controls restrict which devices or users can connect, but application-level roles, API keys, quotas, and per-user authorization require an additional gateway when needed.
Can the fleet span two locations?
Yes, when every participating node can reach the router over Tailscale and node agents use an explicit router URL. Measure WAN latency before placing tightly coupled interactive workloads across distant nodes.
Why not use port forwarding?
Public port forwarding exposes a service that is normally designed for local use and may not have the authentication, rate limiting, and abuse controls expected of a public API. A private overlay network is a safer default.