//------------------------------------------------------------------- //-------------------------------------------------------------------
How to Expose Ollama Securely

How to Expose Ollama Securely on a Remote Linux Server with systemd and a Reverse Proxy

As you must know, Ollama has no built-in authentication. If you open port 11434 to the internet, anyone can use your GPU, pull models, and send requests at your cost. This guide shows you exactly how to expose Ollama securely, keeping the raw port locked down, running it as a proper systemd service, and putting Nginx in front with HTTPS and a password.

If you want a server that is already built for this kind of workload, check out PerLod AI Hosting for GPU-optimized plans.

What You Will Need to Expose Ollama Securely

Before starting to expose Ollama securely, make sure you have the following ready:

  • A remote Linux server running Ubuntu 22.04 or newer.
  • A domain name points to your server’s public IP.
  • Root or sudo access over SSH.
  • Ollama is already installed. You can also check the Open WebUI with Ollama setup guide if you haven’t done that yet.
  • Nginx and Certbot are available via apt.

Why not just open port 11434? Ollama has no built-in access control. Any exposed instance allows unauthenticated model usage, resource hijacking, and prompt injection from anyone who finds the port. The right way is to keep Ollama on localhost and let Nginx handle the public-facing side.

Before starting, here is the security model you are building:

Internet → Nginx (HTTPS + Basic Auth, port 443) → Ollama (localhost:11434)

Ollama listens only on 127.0.0.1:11434. Nginx sits in front, handles SSL termination, checks credentials, and forwards clean requests to Ollama internally.

For more details on platform-specific options and flags, you can also check the official Ollama Linux documentation.

Step 1: Install Ollama and Run It as a systemd Service

If you do not have Ollama installed yet, run the official installer with the command below:

curl -fsSL https://ollama.com/install.sh | sh

The install script automatically creates a systemd service file at /etc/systemd/system/ollama.service. It looks like this:

[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=$PATH"

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable ollama
sudo systemctl start ollama

Verify it is running:

sudo systemctl status ollama

Now, follow the steps below to expose Ollama securely.

Step 2: Lock Ollama to Localhost Only

By default, Ollama listens on 127.0.0.1:11434. You want to make sure this does not accidentally change. The safe way is to set the OLLAMA_HOST environment variable explicitly in the systemd service override, not in the main service file, which gets overwritten on updates.

To do this, run the command below:

sudo systemctl edit ollama

This opens a blank override file. Add the following:

[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"

Save and exit. Reload and restart:

sudo systemctl daemon-reload
sudo systemctl restart ollama

Important Note: Never set OLLAMA_HOST=0.0.0.0 unless Ollama is inside a private Docker network. Setting it to 0.0.0.0 binds to all interfaces and exposes the API to everyone. That is the unsafe pattern this guide avoids.

Confirm Ollama is only listening on localhost:

ss -tlnp | grep 11434

You should only see 127.0.0.1:11434, not 0.0.0.0:11434.

Step 3: Understand Key Ollama Environment Variables

When you need to expose Ollama securely, understanding these variables helps you control its behavior through systemd:

VariableDefaultWhat It Does
OLLAMA_HOST127.0.0.1:11434The address and port Ollama listens on
OLLAMA_ORIGINSlocalhostComma-separated list of allowed CORS origins
OLLAMA_MODELS~/.ollama/modelsPath where models are stored
OLLAMA_DEBUG0Set to 1 for verbose logging

To set any of these, add them as Environment= lines inside sudo systemctl edit ollama, then reload and restart.

For example, restrict CORS to your domain only:

[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_ORIGINS=https://yourdomain.com"

Step 4: Block Port 11434 at the Firewall

Even though Ollama is bound to localhost, it is good practice to block port 11434 at the firewall level too. This adds a second layer of protection:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp       # SSH
sudo ufw allow 80/tcp       # HTTP (for Certbot)
sudo ufw allow 443/tcp      # HTTPS
sudo ufw enable

Make sure port 11434 is NOT in the allow list. Check your rules:

sudo ufw status

Step 5: Install Nginx and Set Up Basic Auth Password

Install Nginx if it is not already on your server:

sudo apt update
sudo apt install nginx -y

Start and enable it:

sudo systemctl enable nginx
sudo systemctl start nginx

Because this is how you expose Ollama securely to specific users, you need a password file. Install apache2-utils to get the htpasswd tool:

sudo apt install apache2-utils -y

Create the password file and your first user:

sudo htpasswd -c /etc/nginx/.htpasswd yourusername

You will be prompted to enter and confirm a password. The file stores a hashed version of it.

To add more users later, you can omit the -c so you do not overwrite the file:

sudo htpasswd /etc/nginx/.htpasswd anotheruser

Step 6: Configure Nginx as a Reverse Proxy

Create a new Nginx config file for your domain:

sudo nano /etc/nginx/sites-available/ollama

Paste the following content with your domain:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        auth_basic "Ollama API – Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;

        proxy_pass http://127.0.0.1:11434;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Origin "";
        proxy_set_header Referer "";
        proxy_buffering off;
        proxy_read_timeout 300s;
        proxy_connect_timeout 60s;
    }
}

What each directive does:

auth_basic with auth_basic_user_file  #Enforces username and password before any request reaches Ollama.

proxy_pass http://127.0.0.1:11434     #Sends the request to Ollama on localhost.

proxy_buffering off                   #Required for streaming responses so tokens appear in real time.

proxy_read_timeout 300s               #Gives large models enough time to generate long outputs.

Origin "" and Referer ""              #Strips headers that can cause CORS issues from the proxy side.

Enable the site and test the config:

sudo ln -s /etc/nginx/sites-available/ollama /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 7: Get a Free SSL Certificate with Certbot

Now you can take your setup from HTTP to proper HTTPS by using Certbot:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com

Follow the prompts. Certbot will:

  • Issue a free Let’s Encrypt certificate.
  • Automatically update your Nginx config to use HTTPS.
  • Set up auto-renewal via a systemd timer.

Test auto-renewal to make sure it works:

sudo certbot renew --dry-run

After Certbot finishes, your Nginx config will have an updated listen 443 ssl block and HTTP-to-HTTPS redirect, all handled automatically.

Step 8: How to Expose Ollama Securely | Test the Setup

Now test that the setup works correctly. From your local machine, not the server, you can run:

Test authentication, which should return 401 without credentials:

curl -I https://yourdomain.com/api/tags

You should get 401 Unauthorized.

Test with credentials:

curl -u yourusername:yourpassword https://yourdomain.com/api/tags

You should get a JSON response listing your installed models.

Test a generate request:

curl -u yourusername:yourpassword https://yourdomain.com/api/generate \
  -d '{"model": "llama3.2", "prompt": "Hello!", "stream": false}'

If you get a valid JSON response, your setup to expose Ollama securely is working correctly.

How to Check Ollama Logs

When something does not work, knowing where the logs are is essential.

To check Ollama service logs, you can use:

journalctl -u ollama -f

View logs from the last hour only:

journalctl -u ollama --since "1 hour ago"

You can enable debug mode for more details by adding this to your systemd override:

sudo systemctl edit ollama

Add:

[Service]
Environment="OLLAMA_DEBUG=1"

Then restart:

sudo systemctl restart ollama
journalctl -u ollama -f

To check Nginx access and error logs, you can use:

sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

Safe API Usage Patterns

Once you expose Ollama securely behind Nginx, here is how to use the API correctly from your applications or scripts:

Python example using requests:

import requests

url = "https://yourdomain.com/api/generate"
auth = ("yourusername", "yourpassword")
payload = {
    "model": "llama3.2",
    "prompt": "Explain Docker in one sentence.",
    "stream": False
}

response = requests.post(url, json=payload, auth=auth)
print(response.json()["response"])

Using the Ollama Python library with a remote host:

import ollama

client = ollama.Client(
    host="https://yourdomain.com",
    auth=("yourusername", "yourpassword")
)

response = client.generate(model="llama3.2", prompt="Hello!")
print(response["response"])

Passing credentials in curl for quick tests:

curl -u user:pass https://yourdomain.com/api/tags
curl -u user:pass https://yourdomain.com/api/generate \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3.2","prompt":"Hi","stream":false}'

Note: Never hard-code credentials in scripts. Use environment variables or a .env file with restricted permissions:

chmod 600 .env

Conclusion

Getting Ollama to work on localhost is the easy part. The hard part is making it accessible from the internet without creating a security hole. By following this guide, you have the right way to expose Ollama securely for real-world use. You keep full control, your API is password-protected and encrypted, and you can check everything through journalctl when something needs debugging.

For heavy models, multi-user inference, or always-on deployments, a dedicated GPU server makes a real difference. You can check out the best GPU Dedicated Servers, built to run LLMs at scale.

FAQs

Will Ollama updates overwrite my environment variable settings?

No, as long as you used sudo systemctl edit ollama to create an override file. The override lives in /etc/systemd/system/ollama.service.d/override.conf and is not changed by updates.

Can I restrict access to specific API endpoints only?

Yes. In your Nginx config, replace the single location / block with specific location /api/generate and location /api/chat blocks, and return 403 for everything else.

How do I check if port 11434 is accidentally exposed?

Run ss -tlnp | grep 11434 on the server. You should only see 127.0.0.1:11434. If you see 0.0.0.0:11434, fix the OLLAMA_HOST variable immediately.

Post Your Comment

PerLod delivers high-performance hosting with real-time support and unmatched reliability.

Contact us

Payment methods

payment gateway