n8n-workflows 的 FastAPI 服务如何安全加固?配置 ADMIN_TOKEN、限流与 CORS 白名单
2026/9/10 4:38:59 网站建设 项目流程

n8n-workflows 的 FastAPI 服务如何安全加固?配置 ADMIN_TOKEN、限流与 CORS 白名单

【免费下载链接】n8n-workflowsall of the workflows of n8n i could find (also from the site itself)项目地址: https://gitcode.com/GitHub_Trending/n8nworkflo/n8n-workflows

把 n8n-workflows 的 FastAPI 服务(api_server.py)暴露到局域网或公网之前,需要做三件事:设置ADMIN_TOKEN/api/reindex重建索引接口不再向任何人敞开;确认按 IP 的限流在敏感端点上生效;把 CORS 白名单从“仅本机开发端口”改成你自己的域名。本文按这三项给出配置命令、行为对照和逐条验证方式,全部依据仓库内的 SECURITY.md、api_server.py 和 test_security.sh。

启动服务,确认加固基线

服务依赖在 requirements.txt 中(FastAPI 0.109.0、uvicorn 0.27.0 等,注释标明兼容 Python 3.9–3.12)。README.md 要求 Python 3.9+,而 DEPLOYMENT.md 的直跑一节写的是 Python 3.11+,两处口径不一致,按较高的 3.11+ 准备环境最稳妥。

pip install -r requirements.txt python run.py

run.py默认绑定127.0.0.1:8000,启动时会检查依赖、创建database/static/workflows目录并建立 SQLite 索引。服务起来后先确认基线可用:

curl http://localhost:8000/health

返回{"status": "healthy", "message": "N8N Workflow API is running"}表示服务正常。后续所有验证命令都以本机http://localhost:8000为目标。

配置 ADMIN_TOKEN:/api/reindex 的鉴权开关

/api/reindex是唯一需要认证的写操作入口,其鉴权逻辑在 api_server.py:从环境变量读取ADMIN_TOKEN,请求通过查询参数admin_token携带令牌,两者必须一致。

在启动服务的同一 shell 里设置令牌(替换为你自己生成的随机字符串,SECURITY.md 明确不要把令牌提交进仓库):

export ADMIN_TOKEN="your-secure-random-token" python run.py

三种状态与返回的对照关系(均由源码行为决定):

条件返回detail
未设置ADMIN_TOKEN环境变量503Reindexing endpoint is disabled. Set ADMIN_TOKEN environment variable to enable.
已设置,但admin_token缺失或与令牌不一致401Invalid authentication token(服务端同时打印Security: Unauthorized reindex attempt from {client_ip}
令牌一致200{"message": "Reindexing started in background", "requested_by": "<client_ip>"}

验证 503 与 401 不需要触发真实重建:

# 未设置 ADMIN_TOKEN 启动的服务 curl -i -X POST "http://localhost:8000/api/reindex" # 已设置 ADMIN_TOKEN,但令牌错误或不带令牌 curl -i -X POST "http://localhost:8000/api/reindex?admin_token=wrong-token"

副作用提示:令牌正确的调用会在后台执行db.index_all_workflows()全量重建索引,会写入数据库。因此“令牌正确返回 200”这条验证请留到你确实需要重建索引时再做,不要当作日常探活手段。

SECURITY.md的部署清单还要求:使用强ADMIN_TOKEN、定期轮换令牌。

限流:60 次/分钟/IP 在哪些端点生效

限流实现位于 api_server.py:模块级变量MAX_REQUESTS_PER_MINUTE = 60check_rate_limit()按客户端 IP 维护一个 60 秒滑动窗口内的请求时间戳列表,超限返回 HTTP 429(Rate limit exceeded. Please try again later.)。

check_rate_limit只在四个端点被调用,其余接口(如/api/workflows搜索、/api/stats)不受限流:

  • GET /api/workflows/{filename}
  • GET /api/workflows/{filename}/download
  • GET /api/workflows/{filename}/diagram
  • POST /api/reindex

验证限流:用test_security.sh中出现过的真实文件名连发 61 次请求,前 60 次应返回 200/404,之后应开始出现 429:

for i in $(seq 1 61); do curl -s -o /dev/null -w "%{http_code}\n" \ "http://localhost:8000/api/workflows/0720_Schedule_Filter_Create_Scheduled.json/download" done

两点注意:

  1. 限流阈值没有环境变量入口。SECURITY.md 的示例里把MAX_REQUESTS_PER_MINUTE=60写成了可选环境变量,但api_server.py中该值是硬编码常量,代码并未读取同名环境变量——两处口径不一致。想调整阈值,需要修改 api_server.py 第 34 行的常量后重启服务。
  2. 限流状态是进程内内存。计数存在模块级defaultdict中,DEPLOYMENT.md 推荐的gunicorn -w 4 ... api_server:app多 worker 部署下,每个进程各自独立计数,单 IP 的实际放行量会高于 60/分钟,文档未给出跨进程共享方案。

收紧 CORS 白名单:把你的域名加进 ALLOWED_ORIGINS

CORS 中间件在 api_server.py 中配置,默认白名单与 SECURITY.md 中“已修复 CORS 配置”一节一致:

ALLOWED_ORIGINS = [ "http://localhost:3000", "http://localhost:8000", "http://localhost:8080", "https://zie619.github.io", "https://n8n-workflows-1-xxgm.onrender.com", ]

同时限制:allow_methodsGETPOSTallow_headersContent-TypeAuthorizationallow_credentials=True

如果你的前端部署在别的域名,按SECURITY.md的说明修改api_server.py里的ALLOWED_ORIGINS列表,追加生产域名(例如https://your-domain.com),重启服务生效。

用 OPTIONS 预检请求验证白名单行为:

# 白名单外的 Origin:响应头中不应出现 Access-Control-Allow-Origin curl -i -X OPTIONS "http://localhost:8000/api/workflows" \ -H "Origin: https://not-allowed.example.com" \ -H "Access-Control-Request-Method: GET" | head -n 20 # 白名单内的本地开发 Origin:响应头中应出现 Access-Control-Allow-Origin curl -i -X OPTIONS "http://localhost:8000/api/workflows" \ -H "Origin: http://localhost:3000" \ -H "Access-Control-Request-Method: GET" | head -n 20

判断标准就是一条:Origin 不在ALLOWED_ORIGINS中时,FastAPI 的 CORSMiddleware 不会在响应上放行该来源的跨域访问,浏览器侧会因缺少Access-Control-Allow-Origin而拦截请求。

用 test_security.sh 批量验证文件访问端点

除上述三项外,文件访问端点(/api/workflows/{filename}/download/diagram)内置了路径穿越防护:validate_filename()会多次解码 URL 编码,拒绝..、反斜杠、绝对路径、通配符等模式,只放行匹配^[a-zA-Z0-9_\-]+\.json$的文件名,并用Path.resolve().relative_to()二次确认文件确实落在workflows/目录内。

test_security.sh 把这套防护做成了可直接运行的检查脚本:它对本地http://localhost:8000发送 10 个路径穿越攻击向量(如../../etc/passwd..%2F..%2Fapi_server.py),期望每个都返回 400 或 404;再请求一个合法文件名,期望返回 200。脚本只发 GET 请求,不改写任何文件,可以在服务运行时直接执行:

bash test_security.sh

输出按行标注 ✅ Blocked / ❌ FAILED TO BLOCK。只要出现一行❌ FAILED TO BLOCK,说明对应向量未被拦截,需要回到validate_filename()检查规则。注意合法文件名(如0720_Schedule_Filter_Create_Scheduled.json)必须已存在于workflows/子目录中,否则最后一步会以 404 报“Valid download failed”。

部署前对照安全清单

SECURITY.md 给出的部署清单,与本文操作直接相关的条目:

  • 设置强ADMIN_TOKEN环境变量(本文已完成,令牌不要提交进仓库);
  • 按你的实际域名配置 CORS 来源(本文已完成);
  • 生产环境使用 HTTPS(HTTP 仅限本地开发);
  • 配置防火墙规则限制访问、开启监控告警;
  • 定期审查并轮换管理员令牌;
  • 若挂在反向代理之后,SECURITY.md推荐追加X-Frame-OptionsX-Content-Type-OptionsStrict-Transport-Security等响应头(示例为 nginxadd_header配置)。

完成上述配置后,服务的暴露面是:搜索/统计类接口公开只读,文件访问接口受文件名白名单 + 限流保护,重建索引接口需要ADMIN_TOKEN且受同一限流约束。需要进一步收敛时,SECURITY.md还建议保持 Python 与依赖更新、用 Trivy 等扫描器跟进依赖漏洞(仓库根目录已有 trivy.yaml)。

【免费下载链接】n8n-workflowsall of the workflows of n8n i could find (also from the site itself)项目地址: https://gitcode.com/GitHub_Trending/n8nworkflo/n8n-workflows

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询