8
n8n 中文网amn8n.com

EnumX:子域名自动 DNS 查询与 Markdown 导出

中级

这是一个SecOps领域的自动化工作流,包含 13 个节点。主要使用 Set, Code, Gmail, Merge, HttpRequest 等节点。 使用 HackerTarget API 和 Gmail 报告的自动化子域名 DNS 记录查询

前置要求
  • Google 账号和 Gmail API 凭证
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "RNNkYFKdsO7f3dSi",
  "meta": {
    "instanceId": "6feff41aadeb8409737e26476f9d0a45f95eec6a9c16afff8ef87a662455b6df",
    "templateCredsSetupCompleted": true
  },
  "name": "EnumX:子域名自动 DNS 查询与 Markdown 导出",
  "tags": [
    {
      "id": "gGA3sGFynnEJEGfZ",
      "name": "Enumeration Engine",
      "createdAt": "2025-07-24T00:23:37.375Z",
      "updatedAt": "2025-07-24T00:23:37.375Z"
    }
  ],
  "nodes": [
    {
      "id": "18df8e48-3d79-413e-bac0-a08fdd167866",
      "name": "点击\"执行工作流\"时",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2120,
        20
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2ec4a837-11f3-4af3-ac37-345ce4fa9947",
      "name": "🌐 目标域名",
      "type": "n8n-nodes-base.set",
      "position": [
        -1920,
        20
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0383ffe1-377f-48ad-a476-8e67eabdfefa",
              "name": "domain",
              "type": "string",
              "value": "example.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "8d9989c2-4f04-4a12-8eae-04a89152bae2",
      "name": "📡 子域名枚举",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1700,
        20
      ],
      "parameters": {
        "url": "=https://api.hackertarget.com/hostsearch/?q={{$json[\"domain\"]}}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": ""
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1b26f151-215a-4898-b5a0-5e6f0ed2d39d",
      "name": "🧠 解析子域名",
      "type": "n8n-nodes-base.code",
      "position": [
        -1480,
        20
      ],
      "parameters": {
        "jsCode": "// Get the first item (raw output from Subdomain Enum)\nconst item = $items(\"📡 Subdomain Enum\")[0];\nconst rawText = Object.values(item.json)[0]; // the unnamed field\n\nconst lines = rawText.split(\"\\n\");\n\nreturn lines\n  .filter(line => line.trim() !== \"\")\n  .map(line => {\n    const [subdomain, ip] = line.split(\",\");\n    return { json: { subdomain, ip } };\n  });"
      },
      "typeVersion": 2
    },
    {
      "id": "e9c560c3-4cb9-42f2-9cac-000f71c700d6",
      "name": "🌐 DNS 记录",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1240,
        160
      ],
      "parameters": {
        "url": "=https://api.hackertarget.com/dnslookup/?q={{$json[\"subdomain\"]}}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text",
              "outputPropertyName": "dns"
            }
          }
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "3e10f83e-3ec6-41fe-8a9f-c2a62d077f72",
      "name": "📝 格式化 DNS Markdown",
      "type": "n8n-nodes-base.code",
      "position": [
        -640,
        40
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const input = $input.item.json;\nconst subdomain = input.subdomain || \"unknown.subdomain\";\n\n// Explicitly access each DNS record type\nconst dnsRecords = {\n  A: input.a || [],\n  AAAA: input.aaaa || [],\n  CNAME: input.cname || [],\n  TXT: input.txt || [],\n  MX: input.mx || [],\n  NS: input.ns || [],\n  SOA: input.soa || []\n};\n\nlet markdown = `### DNS Records for: ${subdomain}\\n\\n`;\n\nfor (const [type, records] of Object.entries(dnsRecords)) {\n  if (Array.isArray(records) && records.length > 0) {\n    const formatted = records.map(r => `- ${r}`).join('\\n');\n    markdown += `**${type}**:\\n${formatted}\\n\\n`;\n  } else {\n    markdown += `**${type}**:\\n- No records found.\\n\\n`;\n  }\n}\n\nreturn {\n  json: {\n    subdomain,\n    dns_markdown: markdown.trim()\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c25357fb-a67b-49dc-8614-28d2d0760884",
      "name": "🔗 合并 DNS + 子域名",
      "type": "n8n-nodes-base.merge",
      "position": [
        -840,
        40
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "joinMode": "keepEverything",
        "fieldsToMatchString": "subdomain"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c55d3e8f-0d07-4e57-a2e7-6658f74edba7",
      "name": "🧠 解析 DNS 记录",
      "type": "n8n-nodes-base.code",
      "position": [
        -1020,
        160
      ],
      "parameters": {
        "jsCode": "// Get raw text from DNS Lookup node\nconst dnsText = $json.dns || \"No data\";\n\n// Prepare output object\nconst recordTypes = ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS', 'SOA'];\nconst result = {\n  subdomain: $json.subdomain || \"unknown.subdomain\"\n};\n\n// Initialize arrays for each type\nfor (const type of recordTypes) {\n  result[type.toLowerCase()] = [];\n}\n\n// Parse each line\ndnsText.split('\\n').forEach(line => {\n  const match = line.match(/^(\\w+)\\s*:\\s*(.*)$/);\n  if (match) {\n    const type = match[1].toUpperCase();\n    const value = match[2].trim();\n    if (recordTypes.includes(type)) {\n      result[type.toLowerCase()].push(value);\n    }\n  }\n});\n\n// If no values found, insert \"No records found\"\nfor (const type of recordTypes) {\n  if (result[type.toLowerCase()].length === 0) {\n    result[type.toLowerCase()].push(\"No records found.\");\n  }\n}\n\nreturn [ { json: result } ];"
      },
      "typeVersion": 2
    },
    {
      "id": "b4878f12-57b1-48ed-8662-d84227209abe",
      "name": "Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -240,
        40
      ],
      "webhookId": "e825199e-fc30-4a63-8b93-8a874b7755a7",
      "parameters": {
        "sendTo": "security-team@example.com",
        "message": "=<pre style=\"font-family: monospace; white-space: pre-wrap;\">{{$json[\"full_report\"]}}</pre>\n<p>—<br>This email was sent automatically with n8n<br><a href=\"https://n8n.io\">https://n8n.io</a></p>",
        "options": {},
        "subject": "=🧠 DNS Report: All Subdomains"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "wbHKmSEka16PTXzD",
          "name": "xiantani"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ff036e1c-a60a-471d-a094-9dad49df4b82",
      "name": "🧩 合并所有 Markdown",
      "type": "n8n-nodes-base.code",
      "position": [
        -440,
        40
      ],
      "parameters": {
        "jsCode": "const combinedMarkdown = items\n  .map(item => item.json.dns_markdown)\n  .join('\\n\\n---\\n\\n'); // separator for readability\n\nreturn [\n  {\n    json: {\n      full_report: combinedMarkdown.trim()\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "77583a90-95c4-4150-893f-c35c280e67d7",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 700,
        "height": 1280,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "c732eca8-5fb8-439b-900e-567e8f00f86e",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1980,
        -140
      ],
      "parameters": {
        "color": 7,
        "width": 260,
        "height": 340,
        "content": ""
      },
      "typeVersion": 1
    },
    {
      "id": "9f7c3150-286d-4c67-9230-312c72c119e3",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -300,
        -120
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 360,
        "content": ""
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "beedf29e-0d17-4c06-bb30-fdb9e35053bf",
  "connections": {
    "🌐 DNS Records": {
      "main": [
        [
          {
            "node": "🧠 Parse DNS Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🌐 Target Domain": {
      "main": [
        [
          {
            "node": "📡 Subdomain Enum",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📡 Subdomain Enum": {
      "main": [
        [
          {
            "node": "🧠 Parse Subdomains",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🧠 Parse Subdomains": {
      "main": [
        [
          {
            "node": "🌐 DNS Records",
            "type": "main",
            "index": 0
          },
          {
            "node": "🔗 Merge DNS + Subdomain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🧠 Parse DNS Records": {
      "main": [
        [
          {
            "node": "🔗 Merge DNS + Subdomain",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "🧩 Merge All Markdown": {
      "main": [
        [
          {
            "node": "Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Format DNS Markdown": {
      "main": [
        [
          {
            "node": "🧩 Merge All Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔗 Merge DNS + Subdomain": {
      "main": [
        [
          {
            "node": "📝 Format DNS Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "🌐 Target Domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 安全运维

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量13
分类1
节点类型7
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
Adnan Tariq

Adnan Tariq

@adnantariq

Founder of CYBERPULSE AI — helping security teams and SMEs eliminate repetitive tasks through modular n8n automations. I build workflows for vulnerability triage, compliance reporting, threat intel, and Red/Blue/GRC ops. Book a session if you'd like custom automation for your use case. https://linkedin.com/in/adnan-tariq-4b2a1a47

外部链接
在 n8n.io 查看

分享此工作流