【n8n教程】:n8n安全防护秘籍

如果你的n8n部署了企业级工作流或处理敏感业务数据,安全防护就成了必不可少的一环。本教程将从实战角度出发,手把手教你如何构建一个**"防火墙级别"**的n8n安全体系。无需深厚的技术背景,只要跟着步骤走,你就能让你的n8n实例变得固若金汤!


📋 核心安全策略一览

在深入细节之前,先了解n8n提供的完整防护工具箱:

防护层面防护方式难度优先级
网络层SSL/TLS加密⭐ 低🔴 必做
认证层SSO(SAML/OIDC)⭐⭐⭐ 中等🟠 重要
授权层角色权限管理⭐⭐ 低🔴 必做
功能层禁用危险节点⭐ 低🟠 重要
隐私层关闭遥测数据⭐ 低🟡 推荐
API层禁用公共API⭐ 低🟠 重要
审计层安全审计扫描⭐⭐ 低🟡 推荐
计算层隔离任务运行器⭐⭐⭐ 中等🟠 重要

第一步:启用SSL/TLS加密 🔐

为什么这很关键?

想象你的工作流数据在网络上像明信片一样传输——任何人都能读。SSL/TLS就是给这张明信片装进保险箱。

实现方案

n8n提供两种部署方案,推荐选择第一种:

方案A:反向代理(⭐ 推荐)

原理:让专业的反向代理(如Traefik)来管理SSL证书,n8n只需专注业务逻辑。


    
    
    
  # 使用Traefik作为反向代理
# 编辑 docker-compose.yml


version: '3'
services:
  n8n:
    image: n8nio/n8n:latest
    environment:
      - N8N_HOST=your-domain.com
      - N8N_PROTOCOL=https
      - NODE_ENV=production
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.n8n.rule=Host(`your-domain.com`)"
      - "traefik.http.routers.n8n.entrypoints=websecure"
      - "traefik.http.routers.n8n.tls.certresolver=letsencrypt"

  traefik:
    image: traefik:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yml:/traefik.yml
      - ./acme.json:/acme.json

优势

方案B:直接传入证书

如果你的环境不能用反向代理,可以直接配置:


    
    
    
  # 设置环境变量
export
 N8N_SSL_CERT=/path/to/cert.pem
export
 N8N_SSL_KEY=/path/to/key.pem

# 启动n8n

n8n start

⚠️ 注意:你需要手动管理证书更新!

验证SSL是否生效


    
    
    
  # 测试HTTPS连接
curl -I https://your-n8n-domain.com
# 输出应该包含 "HTTP/2 200" 或 "HTTP/1.1 200"

第二步:配置单点登录(SSO) 🔑

什么是SSO?为什么需要它?

场景:你们公司用企业级身份认证系统(如Azure AD、Okta等),员工登录任何系统都用同一套账号。n8n也能接入这个系统,省去维护多套账号的麻烦。

支持的协议

n8n支持两种行业标准:

协议适用场景配置难度
SAML 2.0企业级应用集成中等
OIDC现代云应用中等

配置步骤(以SAML为例)


    
    
    
  # 1. 获取n8n的元数据
# 访问:https://your-n8n.com/api/sso/saml/metadata

# 这个文件包含n8n作为服务提供商(SP)的信息


# 2. 在身份提供商(如Okta)创建应用

# - 上传n8n的元数据

# - 配置断言消费者服务URL (ACS)

# - 获取IdP元数据


# 3. 在n8n中配置环境变量

export
 N8N_SSO_SAML_ENABLED=true
export
 N8N_SSO_SAML_IDP_METADATA_URL="https://your-idp.com/metadata"
export
 N8N_SSO_SAML_STRICT=true

# 4. 重启n8n

OIDC配置(另一选择)


    
    
    
  export N8N_SSO_OIDC_ENABLED=true
export
 N8N_SSO_OIDC_CLIENT_ID="your-client-id"
export
 N8N_SSO_OIDC_CLIENT_SECRET="your-client-secret"
export
 N8N_SSO_OIDC_DISCOVERY_URL="https://your-idp/.well-known/openid-configuration"

第三步:实施角色权限管理 👥

n8n的权限模型

n8n提供了精细的权色划分:

角色权限用途
Owner所有权限系统管理员
Admin除用户删除外的所有权限技术主管
Editor创建/编辑工作流工作流开发者
Viewer仅查看权限业务分析师
Member基础权限普通用户

实践建议


    
    
    
  📊 权限分配金字塔:

        👤 Owner (1人)
       ├─ 决策权、紧急操作权
       │
      👤👤 Admin (2-3人)
     ├─ 日常维护、备份、监控
     │
   👤👤👤👤 Editor (5-10人)
  ├─ 创建和修改工作流
  │
👤👤👤👤👤 Viewer (20+人)
├─ 查看工作流运行结果、日志

第四步:关键节点的安全防护 🚫

哪些节点最危险?

这些节点能执行系统命令,需要特别控制:


    
    
    
  ⚠️ 高风险节点:
- Execute Command(执行系统命令)
- Read/Write Files(读写文件系统)
- Function(执行自定义代码)
- HTTP Request(可能暴露敏感数据)
- SQL(数据库注入风险)

禁用危险节点


    
    
    
  # 编辑环境变量或.env文件
export
 NODES_EXCLUDE='["n8n-nodes-base.executeCommand","n8n-nodes-base.readWriteFile"]'

# 多个节点用逗号分隔

export
 NODES_EXCLUDE='["n8n-nodes-base.executeCommand","n8n-nodes-base.readWriteFile","n8n-nodes-base.function"]'

# 重启n8n生效

安全的节点替代方案

禁用的节点安全替代方案
Execute CommandHTTP Request (调用API)
Read/Write FilesGoogle Drive / S3 / OneDrive
FunctionCode 节点(受沙箱保护)

第五步:禁用公共API(如不需要) 🔒

什么是公共API?

n8n提供了REST API,允许外部系统通过代码调用n8n的功能。如果你不需要这个功能,关闭它能减少攻击面。

快速禁用


    
    
    
  # 禁用API服务
export
 N8N_PUBLIC_API_DISABLED=true

# 同时禁用API文档界面(Swagger UI)

export
 N8N_PUBLIC_API_SWAGGERUI_DISABLED=true

# 重启n8n

验证是否成功禁用


    
    
    
  # 尝试访问API端点,应该返回403
curl https://your-n8n.com/api/v1/workflows
# 应该得到拒绝响应

第六步:关闭遥测数据收集 📡

n8n收集什么数据?

n8n会自动收集匿名数据用于改进产品:


    
    
    
  📊 收集的数据示例:
- 工作流执行统计
- 节点使用情况
- 安装配置类型
- 系统版本信息
(⚠️ 不包含你的业务数据或凭证)

完全禁用遥测


    
    
    
  # 禁用诊断事件收集
export
 N8N_DIAGNOSTICS_ENABLED=false

# 禁用版本检查通知

export
 N8N_VERSION_NOTIFICATIONS_ENABLED=false

# 完全隔离n8n(不连接任何外部服务)

export
 N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true

在.env文件中配置


    
    
    
  # .env 文件示例
N8N_DIAGNOSTICS_ENABLED=false
N8N_VERSION_NOTIFICATIONS_ENABLED=false
NODE_ENV=production

第七步:运行安全审计 🔍

为什么需要审计?

每月运行一次审计,就像定期体检一样,能提前发现安全隐患。

三种运行审计的方法

✅ 方法1:CLI命令(最简单)


    
    
    
  # SSH进入n8n服务器
n8n audit

# 输出示例:

# ✓ 检查凭证使用情况...

# ⚠️ 发现3个未使用的凭证

# ✓ 检查危险节点...

# ⚠️ 发现2个Function节点

✅ 方法2:公共API调用


    
    
    
  # 需要管理员权限
curl -X POST https://your-n8n.com/api/v1/audit \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json"

✅ 方法3:在工作流中添加审计节点

在n8n编辑器中:

  1. 1. 点击"+"添加节点
  2. 2. 搜索"n8n"节点
  3. 3. 选择 ResourceAudit
  4. 4. 选择 OperationGenerate
  5. 5. 点击执行

审计报告包含什么?


    
    
    
  📋 五大风险报告:

1️⃣ 凭证检查
   - 未使用的凭证 ❌
   - 非活跃工作流中的凭证 ⚠️
   - 最近未使用的凭证 ⚠️

2️⃣ 数据库检查
   - SQL注入风险 🚨
   - 参数化查询问题 ⚠️

3️⃣ 文件系统检查
   - 哪些节点访问文件系统
   - 潜在的路径遍历风险

4️⃣ 节点风险检查
   - 官方危险节点 🔴
   - 社区节点
   - 自定义节点

5️⃣ 实例配置检查
   - Webhook保护状态
   - 安全设置缺陷
   - n8n版本是否过旧

第八步:强化任务运行器 ⚙️

什么是任务运行器?

当你在n8n中使用Code节点执行JavaScript代码时,任务运行器负责在隔离的容器中执行这些代码。

安全配置


    
    
    
  # Docker Compose配置示例
version: '3'

services:
  n8n:
    image: n8nio/n8n:latest
    environment:
      - EXECUTIONS_PROCESS=external
      - EXECUTIONS_PROCESS_MODE=queue

  task-runner-1:
    image: n8nio/n8n:latest
    command
: worker --concurrency=5
    environment:
      - N8N_WORKER_TYPE=taskRunner
    volumes:
      - n8n_runner_data:/home/node/.n8n

为什么要隔离运行器?


    
    
    
  ┌─────────────────────┐
│   n8n核心进程       │  (处理UI、API、工作流编辑)
│   (主进程)          │
└─────────────────────┘
          │
          ↓ 通过队列通信
┌─────────────────────┐
│  独立任务运行器      │  (执行代码节点)
│  (隔离进程)         │  ← 即使崩溃也不影响主进程
└─────────────────────┘

监控任务运行器状态


    
    
    
  # 查看运行器日志
docker logs n8n_task_runner_1

# 监控资源使用

docker stats n8n_task_runner_1

实战案例:构建安全监控工作流 🛡️

现在,让我们把学到的知识应用到实际场景中!

场景描述

你需要:定期扫描n8n实例的安全问题,如果发现:

就自动发送警报到Slack。

完整可执行工作流 JSON


    
    
    
  {
  "name"
: "n8n Security Monitor",
  "description"
: "定期扫描n8n实例安全问题并发送Slack告警",
  "active"
: true,
  "nodes"
: [
    {

      "id"
: "schedule",
      "type"
: "n8n-nodes-base.schedule",
      "typeVersion"
: 1,
      "position"
: [250, 300],
      "parameters"
: {
        "interval"
: [1, "days"],
        "timezone"
: "Asia/Shanghai"
      }
,
      "name"
: "每日早上8点运行"
    }
,
    {

      "id"
: "audit",
      "type"
: "n8n-nodes-base.n8n",
      "typeVersion"
: 1,
      "position"
: [450, 300],
      "parameters"
: {
        "resource"
: "audit",
        "operation"
: "generate"
      }
,
      "credentials"
: {
        "n8nApi"
: "n8n_api"
      }
,
      "name"
: "执行安全审计"
    }
,
    {

      "id"
: "analyze",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 1,
      "position"
: [650, 300],
      "parameters"
: {
        "jsCode"
: "// 分析审计结果\nconst report = $input.all();\nconst issues = [];\n\n// 检查未使用的凭证\nif (report[0].credentials?.unusedCredentials?.length > 0) {\n  issues.push({\n    severity: '⚠️ 警告',\n    title: '发现未使用的凭证',\n    count: report[0].credentials.unusedCredentials.length,\n    details: report[0].credentials.unusedCredentials.slice(0, 3)\n  });\n}\n\n// 检查危险节点\nif (report[0].nodes?.risky?.length > 0) {\n  issues.push({\n    severity: '🚨 严重',\n    title: '发现危险节点',\n    count: report[0].nodes.risky.length,\n    details: report[0].nodes.risky.slice(0, 3)\n  });\n}\n\n// 检查实例问题\nif (report[0].instance?.issues?.length > 0) {\n  issues.push({\n    severity: '🔴 关键',\n    title: '实例配置问题',\n    count: report[0].instance.issues.length,\n    details: report[0].instance.issues\n  });\n}\n\nreturn [{\n  hasIssues: issues.length > 0,\n  issueCount: issues.length,\n  issues: issues,\n  scanTime: new Date().toISOString()\n}];"
      }
,
      "name"
: "分析审计结果"
    }
,
    {

      "id"
: "slack_alert",
      "type"
: "n8n-nodes-base.slack",
      "typeVersion"
: 1,
      "position"
: [850, 300],
      "parameters"
: {
        "channel"
: "#security-alerts",
        "text"
: "=== n8n 安全扫描报告 ===\n发现 {{$node[\"analyze\"].json.issueCount}} 个问题\n\n{{$node[\"analyze\"].json.issues.map((issue) => `${issue.severity} ${issue.title}: ${issue.count}项`).join(\"\\n\")}}\n\n📊 扫描时间:{{$node[\"analyze\"].json.scanTime}}\n\n请登录管理后台查看详细信息!",
        "attachments"
: []
      }
,
      "credentials"
: {
        "slackApi"
: "slack_token"
      }
,
      "name"
: "发送Slack告警"
    }
,
    {

      "id"
: "store_report",
      "type"
: "n8n-nodes-base.googleSheets",
      "typeVersion"
: 1,
      "position"
: [850, 450],
      "parameters"
: {
        "resource"
: "spreadsheet",
        "operation"
: "append",
        "spreadsheetId"
: "{{ $env.SECURITY_REPORT_SHEET_ID }}",
        "range"
: "A:F",
        "values"
: "[[\"{{$node[\\\"analyze\\\"].json.scanTime}}\", \"{{$node[\\\"analyze\\\"].json.issueCount}}\", \"{{JSON.stringify($node[\\\"analyze\\\"].json.issues)}}\", \"已处理\", \"管理员\", \"\"]]"
      }
,
      "credentials"
: {
        "googleSheetsOAuth2"
: "google_sheets_token"
      }
,
      "name"
: "保存报告到Google Sheets"
    }

  ]
,
  "connections"
: {
    "schedule"
: {
      "main"
: [
        [

          {

            "node"
: "audit",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "audit"
: {
      "main"
: [
        [

          {

            "node"
: "analyze",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "analyze"
: {
      "main"
: [
        [

          {

            "node"
: "slack_alert",
            "type"
: "main",
            "index"
: 0
          }
,
          {

            "node"
: "store_report",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

工作流执行流程图


    
    
    
  ┌─────────────────────┐
│  每日早上8点触发     │
└──────────┬──────────┘
           │
           ↓
┌─────────────────────┐
│  执行安全审计扫描   │
│  (生成完整报告)     │
└──────────┬──────────┘
           │
           ↓
┌─────────────────────┐
│  分析审计结果       │
│  (过滤关键问题)     │
└──────────┬──────────┘
           │
      ┌────┴────┐
      │          │
      ↓          ↓
 ┌─────────┐  ┌──────────────┐
 │ 有问题? │  │ 发送Slack告警 │
 │   是    │  └──────────────┘
 └─────────┘
      │
      ↓
 ┌──────────────────────────┐
 │ 保存完整报告到GoogleSheets│
 │ (长期追踪和审计)         │
 └──────────────────────────┘

如何导入这个工作流?

🔧 导入步骤

  1. 1. 复制上面的JSON代码
  2. 2. 进入你的n8n实例 → 左侧菜单 → "Workflows"
  3. 3. 点击右上角 "+" 按钮 → "Import from URL""Import from File"
  4. 4. 粘贴JSON代码
  5. 5. 点击 "Save" 保存工作流
  6. 6. 配置凭证:
    • • 点击 Slack 节点 → 配置 Slack Bot Token
    • • 点击 Google Sheets 节点 → 配置 Google OAuth
    • • 设置环境变量 SECURITY_REPORT_SHEET_ID
  7. 7. 点击 "Test Workflow" 测试
  8. 8. 点击 "Activate" 启动定时任务

✅ 测试验证


    
    
    
  # 检查工作流日志
docker logs n8n | grep "n8n Security Monitor"

# 应该看到类似输出:

# 2024-12-03 08:00:00 [INFO] Workflow: n8n Security Monitor - Execution started

# 2024-12-03 08:00:15 [INFO] Audit completed. Issues found: 3

# 2024-12-03 08:00:20 [INFO] Slack notification sent

🎓 安全最佳实践速记表


    
    
    
  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ n8n 安全防护检查清单            ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

□ 【网络层】 ✅ SSL/TLS已启用
□ 【认证层】 ✅ SSO已配置(SAML/OIDC)
□ 【授权层】 ✅ 角色权限已细化分配
□ 【功能层】 ✅ 危险节点已禁用
□ 【隐私层】 ✅ 遥测数据已关闭
□ 【API层】 ✅ 公共API已禁用(如不需要)
□ 【审计层】 ✅ 定期审计已自动化
□ 【计算层】 ✅ 任务运行器已隔离
□ 【监控层】 ✅ 安全监控工作流已部署
□ 【备份层】 ✅ 数据备份计划已制定

完成度: _____ / 10

常见问题速查

Q1: 启用SSO后,本地管理员账号还能用吗?

A: 可以。你可以配置SSO为可选,员工可以用SSO登录,管理员保留本地账号作为备用。

Q2: 禁用公共API会影响工作流间的调用吗?

A: 不会。工作流间的调用不走公共API,只有外部系统的REST调用才会被禁用。

Q3: 我的n8n实例没有公网IP,还需要SSL吗?

A: 如果完全内网环境,SSL的优先级可以降低,但强烈建议至少配置自签名证书。

Q4: 多久运行一次安全审计合适?

A: 推荐每周运行一次,或在部署新工作流后立即运行。

Q5: 任务运行器崩溃会导致工作流失败吗?

A: 是的,但n8n会自动重试。如果需要高可用,可以部署多个运行器。


🎉 总结

你现在已经掌握了n8n的完整安全防护体系!从网络到应用层,从身份认证到持续监控,一个企业级的安全n8n部署已经在你手中。

记住:安全不是一次性的工作,而是持续的过程。定期审计、及时更新、持续监控——让你的自动化流程既高效又安全!

引用链接

[1] 官方文档: https://docs.n8n.io/hosting/securing/overview/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#