基本信息
- 系统版本: fnOS 1.1.8
- 安装镜像: fnos-1.1.8-1419.iso(官网最新版本)
- dockermgr 版本: 0.9.16
- Docker 版本: 29.1.3
- 问题时间: 2025-12-25
- 硬件设备: 零刻 SER8(实体机,非虚拟机)
- CPU: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics
- 内存: 32GB
- 存储: Lexar SSD ARES 4TB (nvme) + CT1000P3PSSD8 1TB (nvme)
- 安装方式: ISO 全新安装
问题描述
使用官网最新 ISO(fnos-1.1.8-1419.iso)全新安装 fnOS 1.1.8 后,飞牛默认镜像加速源 docker.fnnas.com 返回 401 Unauthorized 错误,导致:
- 命令行
docker pull 拉取任意镜像失败
- 应用商店安装基于 Docker 的应用失败(如迅雷、qBittorrent 等)
所有需要从 Docker 镜像源拉取镜像的操作均受影响。
已尝试的解决方法
- 系统修复 - 问题未解决
- 系统更新 - 问题未解决
错误信息
Error response from daemon: unknown: failed to resolve reference "docker.io/ollama/ollama:rocm":
failed to authorize: failed to fetch anonymous token: unexpected status from GET request to
https://docker.fnnas.com/service/token?scope=repository%3Afnnas%2Follama%2Follama%3Apull&scope=repository%3Aollama%2Follama%3Apull&service=harbor-registry: 401 Unauthorized
问题分析
1. 认证配置存在
系统在 /root/.docker/config.json 中正确生成了认证信息:
{
"HttpHeaders": {
"X-Meta-Sign": "********************************",
"X-Meta-Token": "************************************************************"
}
}
2. 手动验证认证有效
使用 curl 手动携带这些 headers 请求 token 服务可以成功:
curl -H 'X-Meta-Sign: ****' -H 'X-Meta-Token: ****' \
'https://docker.fnnas.com/service/token?service=harbor-registry&scope=repository:library/hello-world:pull'
返回有效的 JWT token,说明服务端认证正常。
3. Docker 客户端未传递 Headers
问题根因: Docker 的 HttpHeaders 配置仅用于 Docker CLI 与 Docker Daemon 之间的 API 通信,不会被传递给 Registry 的 token 请求。
当 Docker 向 docker.fnnas.com/service/token 请求认证时,没有携带 X-Meta-Sign 和 X-Meta-Token headers,导致 Harbor registry 返回 401。
验证步骤
-
不带 headers 请求(模拟 Docker 行为)- 失败:
curl -I https://docker.fnnas.com/v2/
# 返回 401 Unauthorized
-
带 headers 请求 - 成功:
curl -H 'X-Meta-Sign: ****' -H 'X-Meta-Token: ****' \
'https://docker.fnnas.com/service/token?service=harbor-registry&scope=repository:library/hello-world:pull'
# 返回有效 JWT token
相关日志
Docker 服务日志
Dec 25 21:21:55 fnOS systemd[1]: Starting docker.service - trim docker service...
Dec 25 21:21:55 fnOS wait_resolv_nameserver.sh[36347]: [INFO] Checking /etc/resolv.conf for nameserver entry...
Dec 25 21:21:55 fnOS wait_resolv_nameserver.sh[36347]: [OK] Found nameserver in /etc/resolv.conf
Dec 25 21:21:55 fnOS systemd[1]: Started docker.service - trim docker service.
Dec 25 21:21:55 fnOS dockerd[36349]: time="2025-12-25T21:21:55.873917957+08:00" level=info msg="Starting up"
Dec 25 21:21:57 fnOS dockerd[36349]: time="2025-12-25T21:21:57.233240810+08:00" level=info msg="Docker daemon" commit=fbf3ed2 containerd-snapshotter=true storage-driver=overlayfs version=29.1.3
Dec 25 21:21:57 fnOS dockerd[36349]: time="2025-12-25T21:21:57.246775289+08:00" level=info msg="API listen on /var/run/docker.sock"
Dec 25 21:22:16 fnOS dockerd[36349]: time="2025-12-25T21:22:16.049693574+08:00" level=warning msg="Host doesn't match" cfgHost=registry-1.docker.io host=docker.fnnas.com
Dec 25 21:22:16 fnOS dockerd[36349]: time="2025-12-25T21:22:16.413585641+08:00" level=info msg="trying next host" error="failed to authorize: failed to fetch anonymous token: unexpected status from GET request to https://docker.fnnas.com/service/token?scope=repository%3Afnnas%2Follama%2Follama%3Apull&scope=repository%3Aollama%2Follama%3Apull&service=harbor-registry: 401 Unauthorized" host=docker.fnnas.com
Dec 25 21:22:46 fnOS dockerd[36349]: time="2025-12-25T21:22:46.527067457+08:00" level=error msg="Handler for POST /v1.51/images/create returned error: unknown: failed to resolve reference \"docker.io/ollama/ollama:rocm\": failed to authorize: failed to fetch anonymous token: unexpected status from GET request to https://docker.fnnas.com/service/token?scope=repository%3Afnnas%2Follama%2Follama%3Apull&scope=repository%3Aollama%2Follama%3Apull&service=harbor-registry: 401 Unauthorized"
trim_license 服务启动异常
系统启动时 trim_license 服务曾出现 panic(后自动恢复):
Dec 25 20:32:05 fnOS systemd[1]: Started trim_license.service - Trim License.
Dec 25 20:32:05 fnOS trim_license[1841]: overwrite config with env value, key: infra.logger.path, value: /var/log/trim_license
Dec 25 20:32:05 fnOS trim_license[1841]: panic: dial unix /run/trim_app_cgi/sysinfo: connect: no such file or directory
Dec 25 20:32:05 fnOS trim_license[1841]: goroutine 1 [running]:
Dec 25 20:32:05 fnOS trim_license[1841]: app/core/pkg/config.Init()
Dec 25 20:32:05 fnOS trim_license[1841]: /app/core/pkg/config/config.go:16 +0x1c8
Dec 25 20:32:05 fnOS trim_license[1841]: main.main()
Dec 25 20:32:05 fnOS trim_license[1841]: /app/main.go:35 +0xfc
Dec 25 20:32:05 fnOS systemd[1]: trim_license.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Dec 25 20:32:05 fnOS systemd[1]: trim_license.service: Failed with result 'exit-code'.
Dec 25 20:32:10 fnOS systemd[1]: trim_license.service: Scheduled restart **, restart counter is at 1.
Dec 25 20:32:10 fnOS systemd[1]: Started trim_license.service - Trim License.
dockermgr 日志
[25 20:32:30.236] [info] [3525] Start update docker config thread
[25 20:32:30.236] [info] [3515] No need to merge old config file
[25 20:32:30.237] [info] [3515] Load config file: /usr/trim/etc//dockermgr.conf, content: {"current-mirror":"默认加速源","data-root":1,"live-restore":true,"mirrors":{},"mirrors-v2":[{"name":"默认加速源","url":"https://docker.fnnas.com"},{"name":"docker","url":"https://registry.hub.docker.com"}],"projects":[...]}
[25 20:32:30.237] [info] [3515] Need update false, default proxy:https://docker.fnnas.com
[25 20:32:30.237] [info] [3515] Handle daemon mirror url: https://docker.fnnas.com, name: 默认加速源
[25 20:32:30.237] [info] [3515] Handle daemon mirror url: https://registry.hub.docker.com, name: docker
[25 20:32:30.237] [info] [3515] No need to update the docker config
[25 20:32:30.237] [info] [3515] Started!!
[25 20:32:30.237] [info] [3515] version 0.9.16
trim_sac 日志
time="2025-12-25T20:32:05+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/coredb.Init completed"
time="2025-12-25T20:32:05+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/trimrpc.defaultInit completed"
time="2025-12-25T20:32:05+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/coreweb.Init completed"
time="2025-12-25T20:32:05+08:00" level=info msg="=== === === Start Trim-Sac === === ==="
time="2025-12-25T20:32:05+08:00" level=info msg="module ups register route success"
time="2025-12-25T20:32:05+08:00" level=info msg="module common register route success"
time="2025-12-25T20:32:05+08:00" level=info msg="module entry register route success"
time="2025-12-25T20:32:05+08:00" level=info msg="Init upgrade done" module=upgrade
trim_license 日志
time="2025-12-25T20:32:10+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/coredb.Init completed"
time="2025-12-25T20:32:10+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/trimrpc.defaultInit completed"
time="2025-12-25T20:32:10+08:00" level=info msg="exec init func: git.teiron-inc.cn/infra/coreweb.Init completed"
time="2025-12-25T20:32:10+08:00" level=info msg="lazy apply success: [com.trim.main com.trim.sysinfo com.trim.network com.trim.sysdiag]"
time="2025-12-25T20:32:16+08:00" level=info msg="dd, ven: AZW, p: SER8, ver: Default string, sk: 75"
额外发现
ISO 默认配置与实际不符
fnOS 1.1.8 ISO 中的默认镜像源配置(etc/dockermgr/setting.json)为:
{"current-mirror":"默认镜像","data-root":0,"mirrors":{"docker":{"url":"https://registry.hub.docker.com"},"默认镜像":{"url":"https://docker.ketches.cn"}}}
但 dockermgr 程序中硬编码了 https://docker.fnnas.com,会覆盖默认配置。
注:docker.ketches.cn 目前返回 404,已失效。
dockermgr 中硬编码的相关字符串
通过 strings 命令分析 /usr/trim/bin/dockermgr,发现以下相关硬编码:
X-Meta-Sign
X-Meta-Token
HttpHeaders
https://docker.fnnas.com
/root/.docker/
/root/.docker/config.json
/etc/docker/daemon.json
index.docker.teiron-inc.cn
registry-hub.docker.teiron-inc.cn
建议修复方案
- 方案一: 使用 Docker 标准的认证机制(
auths 配置或 credential helper),而不是依赖 HttpHeaders
- 方案二: 在 Docker daemon 和 registry 之间增加本地代理,自动注入认证 headers
- 方案三: 修改 Harbor registry 配置,支持匿名访问公共镜像的代理请求
- 方案四: 修复 dockermgr 中的认证传递逻辑,确保
X-Meta-Sign 和 X-Meta-Token 能正确传递给 registry 请求
临时解决方案
用户可通过以下方式绕过问题:
- 使用其他镜像加速源
- 直接访问 Docker Hub(需要网络支持)
- 移除默认加速源:
sudo sed -i 's/"https:\/\/docker.fnnas.com",//' /etc/docker/daemon.json
sudo systemctl restart docker
附件信息
daemon.json 配置
{
"data-root": "/vol1/docker",
"live-restore": true,
"log-driver": "json-file",
"log-opts": {"max-file": "5", "max-size": "100m"},
"proxies": {},
"registry-mirrors": ["https://docker.fnnas.com", "https://registry.hub.docker.com"]
}
dockermgr.conf 配置
{
"current-mirror": "默认加速源",
"data-root": 1,
"live-restore": true,
"mirrors": {},
"mirrors-v2": [
{"name": "默认加速源", "url": "https://docker.fnnas.com"},
{"name": "docker", "url": "https://registry.hub.docker.com"}
]
}