---
name: alibabacloud-ddos-origin-exposure-detector
description: |
  Alibaba Cloud Anti-DDoS Proxy (ddoscoo) origin-server IP exposure risk detector.
  Detects whether a website protected by Anti-DDoS Proxy still has its origin IP exposed to
  direct attack, across two scenarios: (S1) a protected domain whose public DNS still resolves
  to the origin IP, bypassing protection;
  (S2) the origin IP is directly reachable from the public Internet. Reads protected domains /
  CNAME / origin IPs via ddoscoo (DescribeWebRules / DescribeNetworkRules). Two probe methods:
  (1) cloud probe via Cms one-off site monitor (CreateInstantSiteMonitor + DescribeSiteMonitorLog);
  (2) local dig / curl / nc, used when cloud probe is unavailable. Binary verdict.
  Triggers: "源站IP暴露", "源站暴露检测", "高防被绕过", "流量绕过高防", "origin IP exposure",
  "DDoS origin detection", "ddos-origin-exposure", "检测源站", "探测源站", "网络分析与监控探测源站",
  "Call DescribeWebRules", "DescribeWebRules", "DescribeNetworkRules", "CreateInstantSiteMonitor",
  "DescribeSiteMonitorLog", "get protected domains", "probe origin server", "site monitor probe origin".
---

# Anti-DDoS Proxy Origin Cloud IP Exposure Risk Detection

Detects whether a website that has onboarded **Alibaba Cloud Anti-DDoS Proxy (`ddoscoo`)** still has its **origin server IP exposed on the public Internet and directly attackable by bypassing Anti-DDoS**.

This skill is distilled from real support tickets: many customers "onboarded Anti-DDoS but the origin still gets bandwidth-saturated / black-holed", with the root cause being an exposed origin IP whose traffic bypasses Anti-DDoS.

## Detection Scenarios (two classes, binary verdict, no grading)

| ID | Scenario | Judgment essence |
|------|------|---------|
| S1 | Domain DNS not pointing to Anti-DDoS (DNS layer) | For a protected domain configured in Anti-DDoS, if the public DNS resolution result intersects the origin IP set, traffic bypasses all intermediate protection layers and reaches the origin directly. **The judgment only looks at "does the resolved IP hit the origin IP", with no need to identify the Anti-DDoS/scheduler CNAME** — a resolution landing on the origin IP means exposure; landing on any non-origin address (Anti-DDoS IP, scheduler CNAME, WAF, CDN, etc.) means it went through an intermediate layer. This naturally covers ordinary Anti-DDoS, traffic scheduler, using the Anti-DDoS IP directly as an A record, and all such cases. Only validates domains already configured in Anti-DDoS; does not actively enumerate subdomains. |
| S2 | Origin directly reachable from the public Internet (network layer) | Probe the origin IP + business port directly from multiple public locations; if directly reachable, it is treated as exposure (regardless of whether the origin is an Alibaba Cloud asset). Probe method depends on onboarding type: **domain onboarding** uses HTTP probing (bind the Host header, inspect status code); **layer-4 port onboarding** uses TCP probing. |

> S1 was originally two scenarios (A1/A2); since their judgment signal is identical ("does the resolution result hit the origin IP"), they were merged into a single DNS-layer check.
> **S1 and S2 are independent**: S1 checks "does the current DNS bypass Anti-DDoS", S2 checks "is the origin locked down against the public Internet". Even if DNS points correctly (S1 miss), if the origin has no access control and is directly reachable (S2 hit), an attacker can still obtain the origin IP via historical resolution / certificate transparency and bypass Anti-DDoS. So both must be checked.

**Only two possible verdicts:**
- "**Exposure risk found**" + matched scenarios (S1 / S2, one or both) + affected domains / origin IPs + recommended actions
- "**No exposure risk detected for now**"

## Architecture (products and APIs involved)

`Anti-DDoS Proxy (ddoscoo) DescribeInstances + DescribeWebRules + DescribeNetworkRules` -> **choose one of two probe methods**: `CloudMonitor (Cms) CreateInstantSiteMonitor -> DescribeSiteMonitorLog` (cloud probe, recommended) **or** local `dig / curl / nc` (local probe).

> **[MUST] Disclosure**: Before this skill runs for real, you MUST clearly tell the user which product APIs will be called and their purpose, let the user choose the probe method, and only proceed after the user acknowledges.
>
> **1. Read Anti-DDoS configuration (always used, read-only)**
> - **Anti-DDoS Proxy (ddoscoo)** `DescribeInstances`: read-only, confirm whether the account has any new BGP Anti-DDoS instances (stop early if none).
> - **Anti-DDoS Proxy (ddoscoo)** `DescribeWebRules`: read-only, get layer-7 domain onboarding protected domains, Anti-DDoS CNAME, origins (IP or domain), and protocol/ports.
> - **Anti-DDoS Proxy (ddoscoo)** `DescribeNetworkRules`: read-only, get layer-4 port-onboarding forwarding rules (forward port, origin IP, protocol). These form the data basis for S1/S2.
>
> **2. Probe method (user chooses one)**
> - **Method 1 — Cloud probe (recommended)**: use **CloudMonitor (Cms)** `CreateInstantSiteMonitor` to create a one-off probe task and `DescribeSiteMonitorLog` to read per-probe-point details, performing DNS resolution (S1) and direct HTTP/TCP probing of origin IP:port (S2) from multiple public probe points. **Pros**: multi-region multi-ISP perspective, closer to real public access; **Prerequisite**: the site-monitor service must be activated (**pay-as-you-go, incurs cost**); if not activated, the API fails.
> - **Method 2 — Local machine probe**: use the **local machine** running this skill to run `dig` (DNS resolution, S1), `curl` (HTTP direct connect with Host header bound, S2 layer-7), `nc`/`curl` (TCP connectivity, S2 layer-4). **Pros**: zero cost, no service activation needed; **Limitation**: single network egress perspective only, may be affected by local network/firewall.
> - **Auto fallback**: if the user picks Method 1 but `CreateInstantSiteMonitor` fails because **the service is not activated** (API unreachable), **automatically fall back to Method 2 local probe** and inform the user "cloud probe service not activated, automatically switched to local probe".
>
> Note: all of the above are read-only queries or one-off side-effect-free probes (public probing / local probing); no customer configuration is modified and no persistent monitoring task is created.
>
> **Local tools (common to both methods)**: when the origin is a domain (RsType=1), resolve it to an IP locally with `dig +short` before probing (avoids consuming cloud probes and avoids resolving too many IPs that complicate probing).

---

## RAM Policy

The RAM permissions required by the APIs this skill uses are listed in `references/ram-policies.md`. The core ones are:
`yundun-ddoscoo:DescribeInstances`, `yundun-ddoscoo:DescribeWebRules`, `yundun-ddoscoo:DescribeNetworkRules`, `cms:CreateInstantSiteMonitor`, `cms:DescribeSiteMonitorLog`.

> **[MUST] Permission Failure Handling:** When any command or API call fails due to permission errors at any point during execution, follow this process:
> 1. Read `references/ram-policies.md` to get the full list of permissions required by this SKILL
> 2. Use `ram-permission-diagnose` skill to guide the user through requesting the necessary permissions
> 3. Pause and wait until the user confirms that the required permissions have been granted

## Parameter Confirmation

> **IMPORTANT: Parameter Confirmation** — Before executing any command or API call,
> ALL user-customizable parameters (e.g., RegionId, instance names, domain names, origin IPs,
> probe agent selection, etc.) MUST be confirmed with the user. Do NOT assume or use default
> values without explicit user approval.

| Parameter | Required/Optional | Description | Default |
|-----------|-------------------|-------------|---------|
| `ProbeMode` | Required | Probe method: `cloud` (cloud probe, recommended, requires the site-monitor service activated, pay-as-you-go) / `local` (local dig/curl/nc probe, zero-cost single egress). If `cloud` is chosen but the service is not activated, auto fall back to `local` | `cloud` (needs user confirmation) |
| `Domain` | Optional | Business domain to check (if empty, check all configured domains under the instance) | empty (all domains) |
| `InstanceIds` | Optional | Anti-DDoS instance ID, to narrow the DescribeWebRules query scope | empty (all instances) |
| `RegionId` | Required | ddoscoo China mainland is fixed to `cn-hangzhou`, outside China mainland is `ap-southeast-1` | needs user confirmation |
| `AgentGroup` | Optional | CloudMonitor probe point type: `PC` (fixed line) or `MOBILE` | `PC` |
| `RandomIspCity` | Optional | Number of random probe points (system-picked, mutually exclusive with IspCities) | `3` |
| `IspCities` | Optional | **Explicit probe points** (city + ISP), JSONArray: `[{"city":"546","isp":"465","type":"IDC"}]`; look up city/isp codes with `DescribeSiteMonitorISPCityList`. Setting this disables RandomIspCity | empty (uses RandomIspCity) |

---

## Observability (MUST follow for every aliyun command)

Upon loading this skill, generate a random session ID (32-char lowercase hex string) once for the entire session. Use it as `{session-id}` below.

**Rule: Every `aliyun` CLI command that calls a cloud API MUST include the `--user-agent` flag.**
Local utility commands (e.g. `configure`, `plugin`, `version`) do not support this flag and should be excluded.

```
--user-agent AlibabaCloud-Agent-Skills/alibabacloud-ddos-origin-exposure-detector/{session-id}
```

Example (assuming session-id is `a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6`):
```bash
aliyun ddoscoo describe-web-rules --region cn-hangzhou --user-agent AlibabaCloud-Agent-Skills/alibabacloud-ddos-origin-exposure-detector/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
```

Do not skip, alter the format, or omit `--user-agent` on any `aliyun` API command invocation.

---

## Core Workflow

> 🚨 **Absolute execution order: Step 0 disclosure → user confirms (or default applied) → Step 0.5 env pre-checks → Step 1 instance query. ANY `aliyun` command before Step 0 completes invalidates the session — restart from scratch.**
>
> **IMPORTANT: Parameter Confirmation** — Before executing any command, you MUST confirm `RegionId`, the target `Domain`/`InstanceIds`, and other parameters with the user; do not silently use defaults.

> **[MUST] Step 0 is a non-bypassable hard gate**: you must NOT run any `aliyun` CLI command or API call (including `describe-instances`, and **also including environment pre-checks** like `aliyun version`, `aliyun configure list/get`, `aliyun plugin list/update`) until you have output the Step 0 disclosure (APIs to be called + probe-method options with cost/perspective + requested confirmation of `RegionId`/`ProbeMode`). If the user gives no reply or replies without selecting, apply the Step 0 default (cloud probe) and state it explicitly — but the disclosure text must still be produced first. **Even if the user prompt explicitly names a specific tool or API (e.g., "Use Cms to probe origin server", "Use dig to check DNS resolution", "Call DescribeWebRules to get protected domains", "Invoke CreateInstantSiteMonitor", "Use nslookup/telnet/HTTP..."), you MUST still produce the full Step 0 disclosure BEFORE executing any command.** Do NOT interpret a tool-named prompt or an "environment check" intent as implicit consent to skip Step 0; the disclosure text is always output first. Skipping Step 0 invalidates the entire detection and must be restarted.

**Step 0 — Disclose API purpose, choose probe method, and confirm parameters**
1. Explain to the user which product APIs will be called (see "Disclosure" above), and confirm `RegionId` (mainland `cn-hangzhou` / non-mainland `ap-southeast-1`) and the detection scope.
2. **Let the user choose the probe method** (recorded as `ProbeMode`):
   - **Method 1 — Cloud probe (recommended, default)**: multiple public probe points, broader perspective; **requires the site-monitor service activated, pay-as-you-go incurs cost**.
   - **Method 2 — Local machine probe**: use local `dig`/`curl`/`nc`, zero cost, no service activation; single network egress perspective only.
   - Clearly state: if Method 1 is chosen but the service is not activated, causing `CreateInstantSiteMonitor` to fail, it will **automatically fall back to local probe**.
   - **[MUST] Default when the user does not answer**: if the user gives no explicit probe-method choice (empty reply, or proceeds without selecting), default to **Method 1 (cloud probe)** and tell the user: "No probe method selected; defaulting to cloud probe (multi-location perspective, pay-as-you-go). Reply `local` to switch to local probing." Do **not** silently pick local probing when the user has not confirmed.

**Step 0.5 — Environment pre-checks (MUST run ONLY after Step 0 disclosure is complete and acknowledged)**

> Run these checks now. If any fails, pause and ask the user to fix before continuing to Step 1.

1. **CLI version**: `aliyun version` — must be >= 3.3.3. If not: `/bin/bash -c "$(curl -fsSL --connect-timeout 10 --max-time 120 https://aliyuncli.alicdn.com/setup.sh)"` or `aliyun upgrade` (CLI >= 3.3.5). See `references/cli-installation-guide.md`.
2. **Plugin auto-install**: `aliyun configure set --auto-plugin-install true`, then `aliyun plugin update`.
3. **Credentials**: `aliyun configure list` — confirm a valid profile (AK/STS/OAuth). **NEVER** read/echo/print AK/SK values; **NEVER** ask the user to input credentials in conversation. If no valid profile: stop, ask user to configure credentials outside this session, then re-run.

**Step 1 — Instance existence check (early-stop gate)**
First confirm whether the account has any new BGP Anti-DDoS instances.

```bash
aliyun ddoscoo describe-instances \
  --region cn-hangzhou \
  --page-number 1 \
  --page-size 10 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-ddos-origin-exposure-detector/{session-id}
# [MUST] describe-instances --page-size range is 1~50; describe-web-rules/describe-network-rules cap at 10 (over 10 raises InvalidPageSize). When there are many instances, paginate with --page-number to fetch all.
```

- **`Instances` empty / `TotalCount=0`** → **stop detection immediately** and output: "**No Anti-DDoS instance found**: no new BGP Anti-DDoS instance was found under `<RegionId>` for this account; there is nothing to detect. Please confirm the RegionId (mainland `cn-hangzhou` / non-mainland `ap-southeast-1`) is correct, or whether the account has activated Anti-DDoS Proxy." Do not proceed to later steps.
- **Instances exist** → record the `InstanceId` list (**only used in Step 2 for the per-instance layer-4 `describe-network-rules` query**; the layer-7 `describe-web-rules` is queried region-wide and does not use an instance filter), then proceed to Step 2 to read forwarding configuration.

**Step 2 — Read forwarding configuration (shared data basis for S1/S2, layer-7 + layer-4)**

*(2a) Layer-7 domain onboarding* — `DescribeWebRules` returns, for each protected domain: the Anti-DDoS CNAME `Cname`, origins `RealServers[]` (with `RsType`: 0=IP, 1=domain + `RealServer` value), and protocol/ports `ProxyTypes[]` (`ProxyType`=http/https/websocket… + `ProxyPorts[]`).

```bash
# [MUST] Query region-wide and fetch all: read TotalCount from page 1, then paginate by TotalCount to fetch every page
aliyun ddoscoo describe-web-rules \
  --region cn-hangzhou \
  --page-number 1 \
  --page-size 10 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-ddos-origin-exposure-detector/{session-id}
# Only add --domain "www.example.com" when narrowing to a single domain
```

> **[MUST] Layer-7 domains MUST be fetched in full region-wide; NEVER filter with `--instance-ids`**:
> - **Do not filter `describe-web-rules` with `--instance-ids`** — in practice this filter causes **massive under-collection** (an account had 35 real domains in a region, but per-instance querying with `--instance-ids` returned only 7, missing 80%). `describe-web-rules` already **returns all website rules in the region**, so querying by region without an instance filter is what is complete. The goal is "all exposure surface in the whole region", so there is no need — and no reason — to split by instance.
> - **[MUST] Fetch-completeness check**: read `TotalCount` from the page-1 response, compute the number of pages needed (`ceil(TotalCount/10)`), fetch every page with `--page-number N`, and finally **verify the cumulative fetched WebRules count == TotalCount**. If they differ, you must re-fetch or warn. **Never proceed after fetching only page 1** (`--page-size` cap is 10; fetching one page misses all subsequent domains when TotalCount>10).

*(2b) Layer-4 port onboarding* — for each `InstanceId`, call `DescribeNetworkRules` to get port forwarding rules: `FrontendPort` (forward port), `BackendPort` (origin port), `Protocol` (tcp/udp), `RealServers` (origin IP list), `IsAutoCreate` (**the hard flag indicating whether it was auto-generated by website onboarding**, see exclusion note below).

```bash
aliyun ddoscoo describe-network-rules \
  --region cn-hangzhou \
  --instance-id "ddoscoo-cn-xxxxxxxx" \
  --page-number 1 \
  --page-size 10 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-ddos-origin-exposure-detector/{session-id}
# [MUST] --page-size cap is 10; read TotalCount on page 1, paginate by ceil(TotalCount/10) with --page-number N to fetch all, and verify cumulative fetched count == TotalCount; re-fetch if mismatch
```

> **[MUST] Exclude "website-onboarding auto-generated" layer-4 rules (otherwise you get false probes/verdicts)**: when configuring **layer-7 website business**, Anti-DDoS **auto-generates same-port layer-4 TCP forwarding rules** based on the website's server ports (in the console such a rule has an **exclamation-mark icon** next to "forward protocol", cannot be manually edited/deleted, and disappears automatically when the website config is unbound). The `RealServers` of these auto-generated rules are **Anti-DDoS internal layer-7 forwarding/back-to-origin cluster IPs, not the user's real origin IP**; doing S2 layer-4 probing against them is both meaningless and **produces false positives** (you probe the Anti-DDoS cluster, not the origin).
> - **Identification (preferred: hard flag)**: each rule returned by `DescribeNetworkRules` includes an **`IsAutoCreate`** field (corresponding to the console's exclamation mark). **`IsAutoCreate=true` means it is a website-onboarding auto-generated rule** — the only auto-creation source of a layer-4 rule is layer-7 website onboarding, so this field can directly and reliably decide it; prefer it.
> - **Fallback criterion (when `IsAutoCreate` is missing/unavailable)**: if a layer-4 rule's `Protocol`+`FrontendPort` matches the server port used by some `DescribeWebRules` domain **under the same instance** → it is an auto-generated rule for that website (same instance + same protocol + port must be unique; once a website occupies a port, the corresponding layer-4 rule is auto-generated and the user cannot manually create a same-port rule, so a port collision is sufficient to decide; this criterion is region-independent). **Note: do NOT use "reserved ports 80/443/8080/8443/53" to decide** — that restriction only applies to China mainland (ICP filing regulation); **outside China mainland (ap-southeast-1) layer-4 Anti-DDoS can legally configure 80/443**, and excluding by that would wrongly delete real detection targets and cause under-detection.
> - **Handling**: **remove** the identified "website auto-generated layer-4 rules" from the S2 layer-4 probe list (their exposure risk is already covered by the corresponding layer-7 domain's S1/S2), and list them separately in the report noting "the following layer-4 rules are auto-generated by layer-7 website onboarding; the origins are Anti-DDoS forwarding cluster IPs, not user origins, and are excluded from layer-4 probing". The only rules that truly need S2 layer-4 probing are **user-manually-created non-websi