Skip to content

feat(firewall): prepare cloud engines' firewalls for running ic-gateway as a side-car to the replica#10500

Open
pierugo-dfinity wants to merge 9 commits into
masterfrom
pierugo/orchestrator-with-more-processes/firewall
Open

feat(firewall): prepare cloud engines' firewalls for running ic-gateway as a side-car to the replica#10500
pierugo-dfinity wants to merge 9 commits into
masterfrom
pierugo/orchestrator-with-more-processes/firewall

Conversation

@pierugo-dfinity

@pierugo-dfinity pierugo-dfinity commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

To make cloud engines self-contained, this PR prepares each of their nodes' firewalls to support running ic-gateway next to the replica, with the former routing external traffic to the latter.

Cloud engines now have their own firewall config in ic.json5. The only differences with a normal replica is that it additionally opens port 80 (for ic-gateway, can be later changed to 443 when supporting TLS). Port 9314 (for ic-gateway's metrics) can be open through a proposal, which also justifies the newly-added CloudEngines firewall scope.
You can visualize the introduced changes by looking at nftables_assigned_cloud_engine.conf.golden. These apply only to assigned cloud engine nodes, i.e. based on their subnet type and not their node reward type (see how nftables_unassigned_cloud_engine.conf.golden is unchanged). Indeed, ic-gateway will run only when nodes are assigned so it makes sense to open the firewall only then.

Naturally, we also include port 9314 to the HTTP adapter blacklist. While we're at it, we also include ports 9324 (ic-boundary's metrics) and port 19522 (disk encryption's key exchange server during upgrades) to the list, which were likely forgotten by mistake.

The motivation for using a separate template than the replica's is that it will diverge even more in the future when adding ic-boundary and will include parts of the boundary_node_firewall. The cloud engine's firewall will be mid-way between the replica's and the API BN's so they might as well have their own template.

@pierugo-dfinity pierugo-dfinity added the CI_ALL_BAZEL_TARGETS Runs all bazel targets label Jun 17, 2026
@github-actions github-actions Bot added the feat label Jun 17, 2026
@pierugo-dfinity pierugo-dfinity force-pushed the pierugo/orchestrator-with-more-processes/firewall branch 2 times, most recently from 97466e1 to f05b111 Compare June 17, 2026 15:53
@pierugo-dfinity pierugo-dfinity force-pushed the pierugo/orchestrator-with-more-processes/firewall branch from f05b111 to 032d24a Compare June 17, 2026 16:06
@pierugo-dfinity pierugo-dfinity changed the title feat(firewall): prepare cloud engines' firewalls for ic-gateway feat(firewall): prepare cloud engines' firewalls for running ic-gateway as a side-car to the replica Jun 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the registry + orchestrator firewall machinery to support a dedicated firewall configuration for cloud engine nodes, preparing them to run ic-gateway alongside the replica (including opening port 80 on assigned cloud engine nodes). It introduces a new registry firewall rules scope (CloudEngines) and wires cloud-engine-specific nftables templates/config into orchestrator role detection and config compilation.

Changes:

  • Add CloudEngines as a first-class FirewallRulesScope across registry keys, candid interface, invariants, and admin tooling.
  • Teach the orchestrator firewall to detect assigned cloud engine nodes via SubnetType and apply a cloud-engine-specific firewall template/config.
  • Update nftables golden outputs and ic.json5 template defaults (including additional HTTP adapter blacklist ports).

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
rs/registry/keys/src/lib.rs Adds CloudEngines scope to FirewallRulesScope parsing/formatting + tests.
rs/registry/helpers/src/node.rs Extends node→subnet lookup helper to also return SubnetType.
rs/registry/canister/src/mutations/firewall.rs Ensures firewall mutation tests cover the new CloudEngines scope.
rs/registry/canister/src/invariants/firewall.rs Adds invariant validation for CloudEngines firewall ruleset.
rs/registry/canister/canister/registry.did Extends candid FirewallRulesScope with CloudEngines.
rs/registry/canister/canister/registry_test.did Mirrors candid scope change for tests.
rs/registry/admin/bin/main.rs Updates CLI help text to document cloud_engines scope.
rs/orchestrator/testdata/nftables_unassigned_replica.conf.golden Updates HTTP adapter blacklist ports in golden output.
rs/orchestrator/testdata/nftables_unassigned_cloud_engine.conf.golden Updates HTTP adapter blacklist ports in golden output.
rs/orchestrator/testdata/nftables_assigned_replica.conf.golden Updates HTTP adapter blacklist ports in golden output.
rs/orchestrator/testdata/nftables_assigned_cloud_engine.conf.golden Updates golden output for new scope + port 80 + blacklist changes.
rs/orchestrator/src/upgrade.rs Refactors subnet-id derivation helper to use RegistryHelper.
rs/orchestrator/src/registry_helper.rs Adds get_subnet_id_and_type_from_node_id and keeps subnet-id-only wrapper.
rs/orchestrator/src/orchestrator.rs Wires cloud engine firewall config into Firewall::new.
rs/orchestrator/src/firewall.rs Adds cloud engine role + config selection + CloudEngines scope fetching and tests.
rs/ic_os/config/tool/templates/ic.json5.template Adds cloud_engine_firewall config block + port 80 accept + blacklist updates.
rs/config/src/firewall.rs Introduces CloudEngineConfig for firewall templating/serialization.
rs/config/src/config.rs Adds cloud_engine_firewall to main config + defaults/loading behavior.
rs/config/src/config_sample.rs Extends sample config with cloud_engine_firewall section.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rs/ic_os/config/tool/templates/ic.json5.template
Comment thread rs/ic_os/config/tool/templates/ic.json5.template
@pierugo-dfinity pierugo-dfinity marked this pull request as ready for review June 18, 2026 14:10
@pierugo-dfinity pierugo-dfinity requested review from a team as code owners June 18, 2026 14:10

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request changes code owned by the Governance team. Therefore, make sure that
you have considered the following (for Governance-owned code):

  1. Update unreleased_changelog.md (if there are behavior changes, even if they are
    non-breaking).

  2. Are there BREAKING changes?

  3. Is a data migration needed?

  4. Security review?

How to Satisfy This Automatic Review

  1. Go to the bottom of the pull request page.

  2. Look for where it says this bot is requesting changes.

  3. Click the three dots to the right.

  4. Select "Dismiss review".

  5. In the text entry box, respond to each of the numbered items in the previous
    section, declare one of the following:

  • Done.

  • $REASON_WHY_NO_NEED. E.g. for unreleased_changelog.md, "No
    canister behavior changes.", or for item 2, "Existing APIs
    behave as before.".

Brief Guide to "Externally Visible" Changes

"Externally visible behavior change" is very often due to some NEW canister API.

Changes to EXISTING APIs are more likely to be "breaking".

If these changes are breaking, make sure that clients know how to migrate, how to
maintain their continuity of operations.

If your changes are behind a feature flag, then, do NOT add entrie(s) to
unreleased_changelog.md in this PR! But rather, add entrie(s) later, in the PR
that enables these changes in production.

Reference(s)

For a more comprehensive checklist, see here.

GOVERNANCE_CHECKLIST_REMINDER_DEDUP

@zeropath-ai

zeropath-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 440bc0c.

Security Overview
Detected Code Changes

| Change Type | Relevant files

... (code changes summary truncated to fit VCS comment limits.)

@zeropath-ai

zeropath-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 440bc0c.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► rs/config/src/config.rs
    Add CloudEngineConfig and related fields to Config
► rs/config/src/config_sample.rs
    Add sample configuration for cloud_engine_firewall
► rs/config/src/firewall.rs
    Introduce CloudEngineConfig and AssignedNodePortLists structs
► rs/ic_os/config/tool/templates/ic.json5.template
    Add cloud_engine_firewall configuration to the template
► rs/orchestrator/src/firewall.rs
    Add support for CloudEngineConfig and its role
    Update Role enum to include AssignedCloudEngine and Unassigned
    Implement FirewallConfigTemplate for CloudEngineFirewallConfig
    Adjust get_subnet_id_and_type_from_node_id usage
► rs/orchestrator/src/orchestrator.rs
    Pass CloudEngineFirewallConfig to Orchestrator
► rs/orchestrator/src/registry_helper.rs
    Update get_subnet_id_from_node_id to also return subnet type

@zeropath-ai

zeropath-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 440bc0c.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► rs/config/src/config.rs
    Add CloudEngineConfig and related fields to Config
► rs/config/src/config_sample.rs
    Add sample configuration for cloud_engine_firewall
► rs/config/src/firewall.rs
    Introduce CloudEngineConfig and AssignedNodePortLists structs
► rs/ic_os/config/tool/templates/ic.json5.template
    Add cloud_engine_firewall configuration to the template
► rs/orchestrator/src/firewall.rs
    Add support for CloudEngineConfig and its role
    Update Role enum to include AssignedCloudEngine and Unassigned
    Implement FirewallConfigTemplate for CloudEngineFirewallConfig
    Adjust get_subnet_id_and_type_from_node_id usage
► rs/orchestrator/src/orchestrator.rs
    Pass CloudEngineFirewallConfig to Orchestrator
► rs/orchestrator/src/registry_helper.rs
    Update get_subnet_id_from_node_id to also return subnet type

@pierugo-dfinity pierugo-dfinity dismissed github-actions[bot]’s stale review June 18, 2026 14:25
  1. Done.
  2. No breaking changes. Just adding a new scope.
  3. No data migration needed.
  4. No security review needed.
Comment thread rs/orchestrator/src/firewall.rs Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Governance-owned code, this seems more or less harmless (and I assume, adds a new feature). I see some test code, but am not sure about coverage, but not being familiar with firewall (since it is not an "architectural" level aspect of Registry, but rather a "subdomain" issue), I assume it's sufficient -> approve.

chain OUTPUT {\n\
type filter hook output priority 0; policy accept;\n\
meta skuid ic-http-adapter fib daddr type local ct state { new } tcp dport { 1-19999 } reject # Block restricted local addresses ic-http-adapter HTTPS access\n\
meta skuid ic-http-adapter ip6 daddr { 2a00:fb01:400:42::/64, 2602:fb2b:110::/48, 2602:fb2b:100::/48, 2602:fb2b:120::/48 } ct state { new } tcp dport { 1-19999 } reject # Block restricted outbound ic-http-adapter HTTPS access\n\

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, here we should also add the prefix of tp1: 2600:3007:4401::/48

# DHCPv6\n\
udp dport { 546 } accept\n\
# TCP ports required for GuestOS functionality\n\
ip6 saddr { {{ ipv6_prefix }} } ct state { new } tcp dport { 7070, 9090, 9091, 9100, 9314, 19531, 19100, 19522 } accept\n\

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you omit 9324 on purpose? This rule allows the node provider to scrape metrics/logs from the same prefix as the one within that node runs.

chain OUTPUT {\n\
type filter hook output priority 0; policy accept;\n\
meta skuid ic-http-adapter fib daddr type local ct state { new } tcp dport { 1-19999 } reject # Block restricted local addresses ic-http-adapter HTTPS access\n\
meta skuid ic-http-adapter ip6 daddr { 2a00:fb01:400:42::/64, 2602:fb2b:110::/48, 2602:fb2b:100::/48, 2602:fb2b:120::/48 } ct state { new } tcp dport { 1-19999 } reject # Block restricted outbound ic-http-adapter HTTPS access\n\

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well, let's add the tp1 prefix: 2600:3007:4401::/48

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants