doctena-org/octorules-sync

GitHub: doctena-org/octorules-sync

一个用于在 GitHub Actions 中自动规划、审计并同步 WAF 及安全规则配置到多家云提供商的自动化部署组件。

Stars: 1 | Forks: 0

# octorules-sync 此 action 运行来自 [doctena-org/octorules](https://github.com/doctena-org/octorules) 的 `octorules` 来部署您的 WAF 规则配置。 octorules 允许您将 WAF 和安全规则(重定向、重写、标头、缓存、WAF、速率限制等)作为 YAML 文件进行管理,并通过您的提供商 API 发布更改。支持的提供商:[Cloudflare](https://github.com/doctena-org/octorules-cloudflare)、[AWS WAF](https://github.com/doctena-org/octorules-aws)、[Google Cloud Armor](https://github.com/doctena-org/octorules-google)、[Azure WAF](https://github.com/doctena-org/octorules-azure)、[Bunny.net](https://github.com/doctena-org/octorules-bunny)。 当您在 GitHub 仓库中管理 octorules 配置时,此 [GitHub Action](https://help.github.com/actions/getting-started-with-github-actions/about-github-actions) 允许您使用自定义的 [workflow](https://help.github.com/actions/configuring-and-managing-workflows) 自动测试并发布更改。 ## 示例 workflow ### Cloudflare ``` name: octorules-sync on: push: branches: - main paths: - 'rules/**' - 'config.yaml' jobs: publish: name: Publish rules from main runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install octorules-cloudflare - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} ``` ### AWS WAF ``` - run: pip install octorules-aws - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: eu-central-1 ``` ### Google Cloud Armor ``` - run: pip install octorules-google - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} ``` ### Azure WAF ``` - run: pip install octorules-azure - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} ``` ### Bunny.net ``` - run: pip install octorules-bunny - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: BUNNY_API_KEY: ${{ secrets.BUNNY_API_KEY }} ``` ### 多提供商 安装您的配置中使用的所有提供商包: ``` - run: pip install octorules-cloudflare octorules-aws octorules-google octorules-azure octorules-bunny ``` ## 输入 ### Secrets 提供商凭证通过环境变量传递,使用的是 [encrypted secrets](https://help.github.com/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#about-encrypted-secrets)。 Secret 名称和配置语法取决于您的提供商: | 提供商 | Secret 示例 | 配置语法 | |----------|---------------|---------------| | [Cloudflare](https://github.com/doctena-org/octorules-cloudflare) | `CLOUDFLARE_API_TOKEN` | `token: env/CLOUDFLARE_API_TOKEN` | | [AWS WAF](https://github.com/doctena-org/octorules-aws) | 标准 boto3 凭证 (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) 或 IAM role | 不需要 `token` — 使用 boto3 凭证链 | | [Google Cloud Armor](https://github.com/doctena-org/octorules-google) | `GOOGLE_APPLICATION_CREDENTIALS` 或 Workload Identity | 不需要 `token` — 使用 Application Default Credentials | | [Azure WAF](https://github.com/doctena-org/octorules-azure) | `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` | 不需要 `token` — 使用 Azure SDK 凭证链 | | [Bunny.net](https://github.com/doctena-org/octorules-bunny) | `BUNNY_API_KEY` | `token: env/BUNNY_API_KEY` | 配置值中的 `env/` 前缀会在运行时解析环境变量。有关完整的身份验证详细信息,请参阅各个提供商的 README。 ### `config_path` 您希望 octorules 使用的配置文件相对于仓库根目录的路径。 默认 `"config.yaml"`。 ### `doit` 设置为 `"--doit"` 以应用更改,留空则仅执行计划。仅接受 `""` 和 `"--doit"` — 任何其他值都会立即失败。 默认 `""`(仅计划)。 ### `force` 设置为 `"Yes"` 以绕过安全阈值,留空则强制执行它们。仅接受 `""` 和 `"Yes"`。 默认 `""`(强制执行阈值)。 ### `checksum` 将计划校验和传递给 `octorules sync` 以进行漂移保护。workflow 如下: 1. `octorules plan` 计算计划更改的 SHA-256 哈希值,并在其日志输出中 打印 `checksum=`。 2. 在计划 (plan) 和同步 (sync) 之间,远程状态可能会发生变化(另一次部署、 手动编辑、API 端更新)。这就是“漂移”。 3. `octorules sync --checksum ` 会在内部重新计划,并将新的 哈希值与提供的哈希值进行比较。如果它们不同,同步将报错并中止, 而不是应用过期的更改。 仅在 `doit` 为 `"--doit"` 时使用。默认 `""`(空字符串,无 校验和验证)。 示例 workflow: ``` - uses: doctena-org/octorules-sync@v1 id: plan with: config_path: config.yaml - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: "--doit" checksum: ${{ steps.plan.outputs.checksum }} ``` ### `phases` 以空格分隔的要同步的规则阶段列表。留空则同步配置文件中的所有阶段。用于针对特定的规则类型。 可用的阶段取决于配置的提供商。有关完整列表,请参阅每个提供商的 README: [Cloudflare](https://github.com/doctena-org/octorules-cloudflare) (23 个阶段) | [AWS WAF](https://github.com/doctena-org/octorules-aws) (4 个阶段) | [Google Cloud Armor](https://github.com/doctena-org/octorules-google) (4 个阶段) | [Azure WAF](https://github.com/doctena-org/octorules-azure) (3 个阶段) | [Bunny.net](https://github.com/doctena-org/octorules-bunny) (4 个阶段) 默认 `""`(空字符串,所有阶段)。 ### `zones` 以空格分隔的要同步的 zone 列表,留空则同步配置文件中的所有 zone。 默认 `""`(空字符串,所有 zone)。 ### `lint` 在计划/同步之前运行 `octorules lint`?设置为 `"Yes"` 以启用。启用后,linter 将在计划/同步步骤之前运行。Lint 错误(退出代码 1)会阻止同步模式应用更改;警告则不会。 默认 `"No"`。 ### `lint_severity` 要报告的最低 lint 严重级别:`"error"`、`"warning"` 或 `"info"`。 默认 `"warning"`。 ### `lint_plan` 用于 Cloudflare lint 权限检查的 Plan 层级覆盖:`"free"`、`"pro"`、`"business"`、`"enterprise"`。非 Cloudflare 提供商会忽略此设置。 默认 `""`(默认为 `"enterprise"`)。 ### `add_pr_comment` 当由 pull request 触发时,是否将计划作为评论添加?设置为 `"Yes"` 以启用。 启用后,此 action 将创建一个包含计划输出的单一 PR 评论,并在后续运行时**就地更新**(而不是每次都创建新评论)。 默认 `"No"`。 ### `pr_comment_token` 如果您将 `add_pr_comment` 设置为 `"Yes"`,请提供一个要使用的 token。 **重要提示:** 不会自动注入任何 token — 您必须显式传递一个 token(例如 `${{ github.token }}`)。默认的 `github.token` 对于同仓库 PR 具有足够的权限。对于跨仓库或 fork PR,请使用具有 `pull_requests: write` scope 的 token。 默认 `""`(空字符串,当 `add_pr_comment` 为 `"Yes"` 时必须提供)。 ### `audit` 在计划/同步之前运行 `octorules audit`(IP 重叠、IP 遮蔽、CDN 范围、zone 漂移分析)?设置为 `"Yes"` 以启用。启用后,审计结果将在 action 输出中报告。只有错误(退出代码 1)会阻止同步;警告(退出代码 2)会被报告,但不会阻止部署。 默认 `"No"`。 ### `audit_checks` 要运行的以空格分隔的审计检查列表:`ip-overlap`、`ip-shadow`、`cdn-ranges`、`zone-drift`。留空则执行所有检查。 默认 `""`(所有检查)。 ### `audit_severity` 最低审计严重级别:`"error"`、`"warning"` 或 `"info"`。控制显示哪些结果。默认值:`"warning"`。 ### `audit_log` 写入同步结果的 JSON-lines 审计日志的路径。仅在 `doit` 为 `"--doit"`(同步模式)时使用。每一行都是一个包含同步操作详细信息的 JSON 对象(zone、阶段、action、结果)。可用于合规性和同步后分析。 默认 `""`(禁用)。 ## 输出 ### `plan` 来自 `octorules` 的计划更改输出。输出格式通过您的 octorules 配置文件中的 `manager.plan_outputs` 控制。同时也会写入到 `$GITHUB_WORKSPACE/octorules-sync.plan`。 ### `log` `octorules` 命令的日志输出。同时也会写入到 `$GITHUB_WORKSPACE/octorules-sync.log`。 ### `exit_code` `octorules` 命令的原始退出代码。可用于在后续步骤中进行分支控制: | 模式 | 代码 | 含义 | |------|------|---------| | plan | `0` | 未检测到更改 | | plan | `2` | 检测到更改 | | plan | `1` | 错误 | | sync | `0` | 成功应用 | | sync | `1` | 错误 | 在后续步骤中使用的示例: ``` - name: Notify on changes if: steps.octorules.outputs.exit_code == '2' run: echo "Changes were detected" ``` ### `checksum` 用于漂移保护的 SHA-256 计划校验和(仅限计划模式)。将此值通过 `checksum` 输入传递给后续的同步步骤,以确保状态在计划和应用之间没有发生漂移。在同步模式下运行或未发出校验和时为空。 ### `lint_exit_code` `octorules lint` 的退出代码:`0` = 干净,`1` = 错误,`2` = 仅有警告,空 = lint 已禁用。 ### `lint_results` Lint 结果文本。当 lint 被禁用或结果干净时为空。 ### `audit_exit_code` `octorules audit` 的退出代码:`0` = 干净,`1` = 错误,`2` = 仅有警告,空 = audit 已禁用。只有退出代码 `1`(错误)会阻止同步;警告会被报告,但不会阻止部署。 ### `audit_results` Audit 结果文本。当 audit 被禁用或结果干净时为空。 ## 审计 当 `audit` 设置为 `"Yes"` 时,action 会在计划/同步步骤之前运行 `octorules audit`。审计结果将包含在 PR 评论中(如果已启用),并通过 `audit_exit_code` 和 `audit_results` 输出暴露出来。 - **计划模式**:会报告审计错误,但计划仍会运行,因此您可以同时看到审计结果和计划更改。如果审计发现错误,action 将在最后失败。 - **同步模式**:审计错误会**完全阻止**同步步骤 — 更改不会被应用。警告不会阻止同步。 ## Linting 当 `lint` 设置为 `"Yes"` 时,action 会在计划/同步步骤之前运行 `octorules lint --exit-code`。Lint 结果将包含在 PR 评论中(如果已启用),并通过 `lint_exit_code` 和 `lint_results` 输出暴露出来。 - **计划模式**:会报告 lint 错误,但计划仍会运行,因此您可以同时看到 lint 问题和计划更改。如果 lint 发现错误,action 将在最后失败。 - **同步模式**:lint 错误会**完全阻止**同步步骤 — 更改不会被应用。警告不会阻止同步。 ### Wirefilter 支持 在 lint Cloudflare 规则时,表达式由 Cloudflare 真正的 [wirefilter](https://github.com/cloudflare/wirefilter) 引擎解析,该引擎作为 `octorules-cloudflare` 的必需依赖项发布 — 无需额外的安装步骤。这可以捕获语法错误、未知或拼写的字段、类型不匹配、无效的运算符使用以及未知的函数名,而这些是仅靠名称启发式方法无法发现的。 非 Cloudflare 提供商(AWS WAF、Google Cloud Armor、Azure WAF、Bunny.net)包含其各自的表达式验证,不需要 wirefilter。 ## Pull request 计划评论 要让此 action 将计划作为 PR 评论发布,请将您的 workflow 配置为: 1. 在 `pull_request` 事件上运行 2. 将 `add_pr_comment` 设置为 `"Yes"` 3. 提供一个 `pr_comment_token` 该 action 将创建一条评论,并在对同一个 PR 的后续推送中对其进行就地更新。评论去重使用一个隐藏的 HTML 标记 (``) 来查找和更新现有评论。 ``` name: octorules-plan on: pull_request: jobs: plan: name: Plan WAF rules changes runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install -r requirements.txt - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml lint: 'Yes' audit: 'Yes' add_pr_comment: 'Yes' pr_comment_token: '${{ github.token }}' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} ``` ## 完整 workflow 示例 一种常见的模式是在 pull request 时进行计划 (plan),并在合并到 main 分支时进行应用 (apply): ``` name: octorules-sync on: pull_request: paths: - 'rules/**' - 'config.yaml' push: branches: - main paths: - 'rules/**' - 'config.yaml' jobs: plan: if: github.event_name == 'pull_request' name: Plan changes runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install -r requirements.txt - uses: doctena-org/octorules-sync@v1 id: octorules with: config_path: config.yaml lint: 'Yes' audit: 'Yes' add_pr_comment: 'Yes' pr_comment_token: '${{ github.token }}' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} deploy: if: github.event_name == 'push' name: Deploy changes runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install -r requirements.txt - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} ``` ## 高级:阶段过滤 要仅同步特定的规则阶段,请使用 `phases` 输入: ``` - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' phases: 'cache_rules redirect_rules' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} ``` ## 高级:校验和漂移保护 该 action 会从 `octorules plan --checksum` 输出一个 `checksum`。将其传递给 后续的同步步骤,以确保状态在计划和应用之间没有发生漂移: ``` jobs: plan: name: Plan runs-on: ubuntu-latest outputs: checksum: ${{ steps.plan.outputs.checksum }} steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install -r requirements.txt - uses: doctena-org/octorules-sync@v1 id: plan with: config_path: config.yaml env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} deploy: needs: plan name: Deploy runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' - run: pip install -r requirements.txt - uses: doctena-org/octorules-sync@v1 with: config_path: config.yaml doit: '--doit' checksum: '${{ needs.plan.outputs.checksum }}' env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} ``` ## 故障排除 ### 在 PATH 上找不到 octorules 该 action 要求在运行之前安装 `octorules` 和提供商包。请在您的 workflow 中添加一个安装步骤: ``` # Cloudflare - run: pip install octorules-cloudflare # AWS WAF - run: pip install octorules-aws # Google Cloud Armor - run: pip install octorules-google # Azure WAF - run: pip install octorules-azure # Bunny.net - run: pip install octorules-bunny # 多个 providers - run: pip install octorules-cloudflare octorules-aws # 或使用 requirements.txt - run: pip install -r requirements.txt ``` ### 提供商 token / 无效 token 错误 确保您已为提供商凭证创建了仓库 secret,并将其作为环境变量传递。有关特定于提供商的示例,请参阅上面的 [Secrets](#secrets) 部分。引用环境变量的配置值必须使用 `env/` 前缀(例如 `token: env/CLOUDFLARE_API_TOKEN`)。 ### 未找到配置文件 `config_path` 输入默认为仓库根目录中的 `config.yaml`。如果您的配置位于其他位置,请相应地设置 `config_path`。该路径是相对于仓库根目录(工作区的。 ### PR 评论权限错误 如果 action 未能创建或更新 PR 评论,请检查: 1. 您是否通过 `pr_comment_token` 传递了有效的 token(例如 `${{ github.token }}`)。 2. 该 token 是否具有 `pull_requests: write` 权限。对于同仓库 PR,默认的 `github.token` 即可满足要求。 3. 对于 fork PR 或跨仓库 workflow,请使用具有适当 scope 的 Personal Access Token 或 GitHub App token。 ## 贡献 欢迎贡献! ### 开发设置 1. Fork 并克隆仓库。 2. 安装开发依赖项: # macOS brew install shellcheck yamllint bats-core # Debian / Ubuntu apt-get install shellcheck yamllint bats 3. 运行完整的检查套件: make ### 进行更改 1. 从 `main` 创建一个分支。 2. 进行更改。如果您修改了 `scripts/*.sh`,请在 `tests/` 中添加或更新相应的测试。 3. 在提交之前运行 linting 和测试: make lint # yamllint + shellcheck make test # bats tests/ 4. 发起一个针对 `main` 的 pull request。 ### 代码风格 - Shell 脚本遵循 [ShellCheck](https://www.shellcheck.net/) 建议。 - YAML 文件必须通过 `yamllint --no-warnings`。 - 在新脚本中使用 `set -euo pipefail`。 - 优先使用数组来构建命令(有关模式,请参见 `scripts/run.sh`)。 ### 发布 发布过程是自动化的。推送一个 semver 标签 (`v1.2.3`) 以创建 GitHub Release。发布该 Release 会自动更新主版本标签 (`v1`)。 在打标签之前,请在 `[Unreleased]` 部分下使用您的更改更新 `CHANGELOG.md`。 ## 许可证 octorules-sync 采用 [Apache License 2.0](LICENSE) 许可证。
标签:CDN, GitHub Actions, WAF, 自动化运维, 自动笔记, 逆向工具