Op afstand toegang tot Ollama via Tailscale of WireGuard, zonder openbare poorten.

Toegang op afstand tot Ollama zonder openbare poorten

Inhoud

Ollama is het meest tevreden wanneer het wordt behandeld als een lokale daemon: de CLI en uw apps communiceren met een loopback HTTP-API, en de rest van het netwerk heeft geen idee van zijn bestaan.

Standaard gebeurt dat precies zo: het gebruikelijke lokale basisadres bevindt zich op localhost op poort 11434.

ollama remote access

Dit artikel gaat over het moment waarop u externe toegang wilt (laptop, een andere kantoorcomputer, misschien een telefoon), maar u geen niet-geauthenticeerde model-runner naar het hele internet wilt publiceren. Die intentie is belangrijk, omdat de eenvoudigste schaalbeweging (een poort openen, forwarden, klaar) ook de beweging is die de rommel creëert.

Een praktische north star is eenvoudig: houd de Ollama-API privé, en maak het privé-netwerkpad saai. Tailscale en WireGuard zijn twee veelvoorkomende manieren om dat te doen, en de rest draait erom ervoor te zorgen dat de host alleen luistert waar het hoort en dat de firewall akkoord gaat.

Remote device
  |
  | (private VPN path: tailscale or wireguard)
  v
VPN interface on host (tailscale0 or wg0)
  |
  | (local hop)
  v
Ollama server (HTTP API on localhost or VPN IP)

Bedreigingsmodel en wie toegang tot de API moet hebben

Hoe kan Ollama op afstand worden benaderd zonder het aan het openbare internet bloot te stellen? Het antwoord draait minder om een specifiek hulpmiddel en meer om expliciet te zijn over “wie mag verbinding maken” en “vanwaar”.

Een nuttig mentaal model bestaat uit drie concentrische ringen:

  • Alleen lokaal: alleen processen op de machine kunnen de API aanroepen.
  • Alleen LAN: apparaten in hetzelfde lokale netwerk kunnen de API aanroepen.
  • Alleen VPN: geselecteerde apparaten en gebruikers op een privé-overlay-netwerk kunnen de API aanroepen.

De eerste ring is de standaard. Veel handleidingen (en hulpmiddelen zoals Postman) gaan uit van localhost 11434 als basis-URL, wat zowel handig als een verrassend sterke veiligheidsbarrière is.

De reden waarom de ringen belangrijk zijn, is dat Ollama vaak wordt omschreven als niet over ingebouwde authenticatie beschikt voor zijn lokale HTTP-API. Dit betekent dat netwerkblootstelling en toegangsbeheer uw taak worden als u verder gaat dan localhost.

De andere reden is kosten en misbruik: zelfs een “privé” LLM-eindpunt is nog steeds een API-eindpunt. De OWASP API Security Top 10 noemt categorieën zoals beveiligingsmisconfiguratie en onbeperkt bronnenverbruik; een model-runner is praktisch een posterkind voor “bronnenverbruik” als het casual wordt blootgesteld.

Het basisbedreigingsmodel is dus niet alleen “een aanvalser leest mijn gegevens”. Het is ook “iemand kan mijn CPU en GPU gebruiken alsof het een gehuurde auto is” en “onbedoelde gebruikers ontdekken het en beginnen hierop te bouwen”.

OLLAMA_HOST en bind-semantiek in 90 seconden

Wat doet OLLAMA_HOST en wat is de veiligste standaardwaarde? OLLAMA_HOST is de schakelaar die bepaalt waar de Ollama-server luistert. In ollama serve wordt de omgevingsvariabele omschreven als het IP-adres en de poort voor de server, met een standaard van 127.0.0.1 en poort 11434.

In gewone taal bepaalt het bind-adres welke netwerken überhaupt een TCP-verbinding kunnen proberen:

  • 127.0.0.1 betekent alleen localhost.
  • Een LAN-IP (zoals 192.168.x.y) betekent dat het LAN er toegang toe heeft.
  • 0.0.0.0 betekent alle interfaces (LAN, VPN, alles) kunnen er toegang toe hebben, tenzij een firewall dit blokkeert.

Daarom suggereren de meeste “maak het toegankelijk”-handleidingen om over te schakelen van 127.0.0.1 naar 0.0.0.0, maar dat advies is onvolledig zonder een firewall die bewust is van interfaces.

Dit is de cheat sheet die ik in mijn hoofd bewaar:

# Local only (baseline)
export OLLAMA_HOST=127.0.0.1:11434

# All interfaces (powerful, easy to regret)
export OLLAMA_HOST=0.0.0.0:11434

# VPN interface only (preferred when the VPN has a stable IP on the host)
export OLLAMA_HOST=100.64.0.10:11434   # example tailscale IP
export OLLAMA_HOST=10.10.10.1:11434    # example wireguard IP

# Different port (useful when 11434 is already taken)
export OLLAMA_HOST=127.0.0.1:11435

Het geval met “andere poort” wordt expliciet besproken in de Ollama-issue-tracker als een voorbeeld van het gebruik van OLLAMA_HOST om de luister-poort te wijzigen.

Een operationeel voetnoot dat mensen bijt: als Ollama loopt als een beheerd service, dan verandert het instellen van omgevingsvariabelen in een interactieve shell niet per se de service-configuratie. Dit is waarom veel verhalen over “het werkte in mijn terminal maar niet na herstart” eindigen in systemd-eenheden-overrides of service-manager-configuratie.

Patroon A: VPN eerst met Tailscale

Kan Tailscale toegang beperken tot slechts één service-poort op een machine? Ja, en dat is een groot deel van de reden waarom Tailscale goed past bij “externe toegang zonder publiceren”.

Tailscale geeft u een privénetwerk (een tailnet) met centraal beheerde toegangscontroles (ACL’s). ACL’s bestaan specifiek om apparaattoegang te beheren en het netwerk te beveiligen.

Geen openbare poort betekent geen router-choreografie

Het schoonste patroon is om überhaupt geen internet-gerichte poort voor Ollama te openen en de VPN als enige ingang te behandelen. Met Tailscale proberen apparaten direct peer-to-peer te verbinden wanneer dat mogelijk is, en kunnen ze terugvallen op relay-mechanismen wanneer directe connectiviteit niet mogelijk is.

Dit is op zich geen magische beveiliging, maar het verkleint de explosieradius radicaal vergeleken met “ik heb 11434 op mijn router doorgestuurd”.

Split horizon en naamgeving met MagicDNS

Een tweede vraag die in het echte leven opduikt is: “verbind ik via LAN-IP als ik thuis ben en via VPN-IP als ik weg ben”. Dat is in wezen een split-horizon-probleem.

Tailscale MagicDNS helpt door elk apparaat een stabiele tailnet-hostnaam te geven. Onder de motorkap genereert MagicDNS een FQDN voor elk apparaat dat de machinaam en uw tailnet-DNS-naam combineert, en moderne tailnet-namen eindigen in .ts.net.

De mening is dat het gebruik van een naam meestal beter is dan het hard-codigen van een IP, omdat de naam het apparaat volgt, zelfs als uw tailnet-IP verandert. Maar het is ook prima om opzettelijk saai te zijn en een klein hosts-bestand of een enkel intern DNS-record te behouden als u dat prefereert. MagicDNS bestaat zodat u dat niet hoeft te doen.

Directe poort versus tailnet-only proxying

Er zijn twee veelvoorkomende Tailscale-wijzen om een service te bereiken:

  • Directe poorttoegang, waarbij de service luistert op de tailnet-interface en clients verbinding maken met dat IP en die poort.
  • Tailscale Serve, waarbij Tailscale verkeer van andere tailnet-apparaten routet naar een lokale service op de host.

Serve wordt expliciet omschreven als het routeren van verkeer van andere tailnet-apparaten naar een lokale service die op uw apparaat draait.

Voor Ollama kan Serve aantrekkelijk zijn omdat het u toelaat om Ollama op localhost te houden en alleen een gecontroleerde ingangsroute via Tailscale te blootstellen. Het past ook natuurlijk aan met HTTPS binnen het tailnet als u browser-vriendelijke eindpunten wilt.

Een gerelateerde functie die het waard is te noemen en dan mentaal te parkeren, is Funnel. Funnel is ontworpen om verkeer van het bredere internet naar een service op een tailnet-apparaat te routeren en is expliciet bedoeld voor “iedereen die toegang heeft, zelfs als ze Tailscale niet gebruiken”. Dat is het tegenovergestelde van dit artikel.

Patroon B: WireGuard voor degenen die de ruwe primitives willen

WireGuard is de onderliggende primitieve die veel VPN-producten aandrijft, en het is opzettelijk minimaal: u configureert een interface, definieert peers en beslist welk verkeer mag stromen.

De WireGuard-quick start toont de basisvorm: maak een interface zoals wg0, wijs IPs toe en configureer peers met wg.

Het sleutelconcept voor het omcirkelen van toegang is AllowedIPs. In de Red Hat-documentatie leest WireGuard het bestemmings-IP van een pakket en vergelijkt het met de lijst van toegestane IP-adressen; als de peer niet wordt gevonden, gooit WireGuard het pakket weg.

Voor een Ollama-host is de praktische vertaling:

  • Plaats de host op een privé WireGuard-subnet.
  • Bind Ollama ofwel aan localhost en stuur het door, of bind direct aan het WireGuard-IP.
  • Alleen peers met de juiste sleutels en AllowedIPs kunnen verkeer naar dat privé-IP routeren.

Dit is minder bewegende onderdelen dan een commercieel overlay-netwerk, maar het betekent ook dat u verantwoordelijk bent voor sleutelverdeling, peer-levenscyclus en hoe externe peers uw netwerk bereiken.

Firewall: toestaan alleen VPN-interface of tailnet

Hoe kan een firewall Ollama beperken tot alleen VPN-interface-verkeer? Het doel is om onbedoelde blootstelling te voorkomen, zelfs als het bind-adres breder wordt dan beoogd.

Het algemene patroon is:

  • Sta de Ollama TCP-poort alleen toe op de VPN-interface (tailscale0 of wg0).
  • Verbied dezelfde poort op alles andere.
  • Geef de voorkeur aan “default deny inbound” als u op die manier voor de host werkt.

Tailscale heeft expliciete richtlijnen over het gebruik van UFW om niet-Tailscale-verkeer naar een server te beperken, wat in wezen de “alles vergrendelen behalve het tailnet”-aanpak is.

Een nuance die specifiek voor Tailscale belangrijk is, is dat host-firewall-verwachtingen mogelijk niet overeenkomen met de realiteit als u ervan uitgaat dat UFW tailnet-verkeer zal blokkeren. Het Tailscale-project heeft besproken dat het opzettelijk een regel installeert om verkeer op tailscale0 toe te staan en vertrouwt op een door ACL-bestuurd filter binnen tailscaled.

Dat is geen argument tegen een host-firewall. Het is een argument om doordacht te zijn over welk controlevlak de beleid daadwerkelijk handhaaft. Als u wilt dat “alleen deze apparaten poort 11434 kunnen bereiken”, zijn Tailscale ACL’s daarvoor ontworpen.

Als u toch interface-niveau hostcontroles wilt, zien de voorbeelden er vaak zo uit:

# UFW style logic (illustrative)
ufw allow in on tailscale0 to any port 11434 proto tcp
ufw deny  in to any port 11434 proto tcp

# Or for wireguard
ufw allow in on wg0 to any port 11434 proto tcp
ufw deny  in to any port 11434 proto tcp

Zelfs als u voornamelijk vertrouwt op VPN-beleid, biedt de host-firewall nog steeds een nuttige “veiligheidsriem” tegen misbinding naar 0.0.0.0 of onverwachte service-wrappers.

Optionele reverse proxy alleen op VPN-ingang

Wanneer is een reverse proxy nuttig voor externe Ollama-toegang? Een proxy is nuttig als u een of meer van deze eigenschappen wilt:

  • Een standaard authenticatiepoort (basic auth, OIDC, client-certs).
  • TLS-terminatie met een certificaat dat clients vertrouwen.
  • Aanvraaglimieten en time-outs.
  • Schoonere URLs voor hulpmiddelen die rauwe poorten niet leuk vinden.

Dit is waar de “niet publiceren op het internet”-intentie nog steeds waar moet blijven: de reverse proxy is alleen bereikbaar via de VPN, niet op het openbare WAN-interface.

Is TLS nodig als verkeer al door een VPN gaat? Niet altijd voor cryptografie, maar vaak voor ergonomie. Tailscale wijst erop dat verbindingen tussen nodes al end-to-end versleuteld zijn, maar browsers weten dat niet omdat ze vertrouwen op TLS-certificaten om HTTPS-vertrouwen tot stand te brengen.

Als u in de Tailscale-wereld bent, kunt u HTTPS-certificaten inschakelen voor uw tailnet, wat MagicDNS vereist en expliciet opmerkt dat machinaam en de tailnet-DNS-naam op een openbaar register (certificate transparency logs) worden gepubliceerd.

Dat detail over het openbare register is geen reden om TLS te vermijden, maar het is wel een reden om machines op volwassen wijze te noemen (vermijd het insluiten van private projectnamen of klantidentificatoren in hostnamen).

Dit artikel bevat opzettelijk geen volledige reverse-proxy-configuratie (zie uw A1-artikel daarvoor). Het enige idee dat hier van belang is, is plaatsing:

  • Ollama luistert op localhost of VPN-IP.
  • Reverse proxy luistert alleen op de VPN-interface.
  • Proxy stuurt door naar Ollama.

Veiligheidscontrolelijst voor externe toegang tot de Ollama API

Dit is de controlelijst die ik gebruik om te voorkomen dat “extern” stilzwijgend “openbaar” wordt.

Binding en bereikbaarheid

  • Bevestig dat de server luistert waar u denkt dat hij luistert. De gedocumenteerde standaard is 127.0.0.1 en poort 11434, en OLLAMA_HOST verandert dat.
  • Behandel 0.0.0.0 als een doordachte keuze, niet als een handig schakeltje.
  • Geef de voorkeur aan binding aan een VPN-interface-IP als deze stabiel is en past bij de topologie.

Toegangsbeheer

  • Als u Tailscale gebruikt, implementeer ACL’s die alleen specifieke gebruikers of getagged apparaten toestaan op de Ollama-poort. ACL’s bestaan om apparaattoegang te beheren.
  • Als u WireGuard gebruikt, houd AllowedIPs strak en behandel sleutels als de echte identiteitsgrens. WireGuard gooit pakketten weg die niet overeenkomen met een geldige peer AllowedIPs-mapping.

Firewall

  • Voeg een regel op host-niveau toe die de Ollama-poort alleen toestaat op tailscale0 of wg0 en overal anders blokkeert.
  • Als u verwacht dat UFW tailnet-verkeer blokkeert, verifieer hoe Tailscale met uw firewall interacteert. Tailscale heeft besproken dat het tailscale0-verkeer toestaat en vertrouwt op ACL-filtering binnen tailscaled.

TLS en proxying

  • Gebruik TLS als clients browsers zijn of als hulpmiddelen HTTPS verwachten, zelfs als de VPN al transport versleutelt. Tailscale documenteert deze kloof tussen VPN-versleuteling en browser-HTTPS-vertrouwen.
  • Als u Tailscale HTTPS-certificaten inschakelt, onthoud dan de implicatie van certificate transparency voor hostnamen.
  • Als u een reverse proxy toevoegt, houd deze VPN-only en gebruik het voor auth en limieten, niet voor internetblootstelling.

Vermijd onbedoelde openbare blootstelling

  • Wees op je hoede voor functies die expliciet zijn ontworpen om services naar het internet te publiceren. Tailscale Funnel routet verkeer van het bredere internet naar een tailnet-apparaat, wat niet de standaard-veilige route is voor een Ollama-API.
  • Als iets internet-bereikbaar wordt, laat dan geen anoniem /api-oppervlak achter. Op dat punt stoppen de OWASP API “security misconfiguration” en “resource consumption” risicocategorieën met theoretisch te zijn.

Observabiliteit en schadebeperking

  • Log aanvragen op de ingaanslaag (VPN-beleid logs, proxy logs, of beide).
  • Voeg aanvraag- en concurrentielimieten toe als uw proxy ze ondersteunt, omdat modelinferentie een gebeurtenis van bronverbruik is, geen normale API-aanroep.

Het consistente thema is opzettelijk saai: houd de Ollama-API standaard privé, voeg een privé-pad toe voor externe toegang, en handhaaf dat beleid tweemaal (VPN-identiteit plus host-firewall) zodat een enkele misstap niet resulteert in een openbaar eindpunt.