Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ PastureStack is an independent community effort to preserve, audit, and moderniz

Earlier prerelease coordinates are retired from current release references;
their reviewed source commits remain in Git history. This source tree targets
the pure numeric coordinate `v0.3.9`; the GitHub tag and Release, rather than
the pure numeric coordinate `v0.3.10`; the GitHub tag and Release, rather than
this README, determine when it is published. Product identity is carried by
the repository, catalog metadata, and provenance rather than the version tag.

Expand Down Expand Up @@ -68,9 +68,12 @@ health-reporting, and encrypted-workload gates. The scheduler passed source,
build, security, public distribution, live Metadata, idempotent reservation,
managed allocation, and restart gates. Version `v0.8.15` additionally remained
healthy through repeated Metadata long-poll windows in production without a
second container start. Network Services version `5` moves to `v0.8.17`,
second container start. Network Services version `6` moves to `v0.8.18`,
rejects malformed per-host subnet labels before applying host firewall rules,
and preserves routed container source IPs between validated active peers.
and preserves routed container source IPs between validated active peers. It
also fixes bidirectional VXLAN traffic when published host ports coexist with
the overlay. Layer 2 Flat Network version `4` moves to `v0.14.36` so the CNI
preserves an operator-configured bridge address.
Restored-data provisioning, complete multi-host
scheduler lifecycle, and complete project-template upgrade and rollback remain
release-candidate gates. The two alternative network drivers passed packaged
Expand Down
39 changes: 39 additions & 0 deletions catalog-images.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,25 @@
"secrets": 0
}
},
{
"reference": "ghcr.io/pasturestack/ipsec-vxlan-overlay-network:v0.14.36",
"manifestDigest": "sha256:50c93f759fd1d2881701ae9d4ef17d91eaaeac715750c1d3ad6f586cd9fd658d",
"sourceRepository": "https://github.com/PastureStack/ipsec-vxlan-overlay-network",
"sourceCommit": "f754bab6dc63c4e51b849a106fcdc792f644b9ef",
"sourcePath": "package/Dockerfile",
"registryPage": "https://github.com/orgs/PastureStack/packages/container/package/ipsec-vxlan-overlay-network",
"licenseBoundary": "Apache-2.0 source and image; bundled Ubuntu, strongSwan, CNI, Weave, and other packages retain their upstream licenses and notices",
"reviewedAt": "2026-09-14",
"platforms": ["linux/amd64"],
"vulnerabilityScan": {
"scanner": "Trivy 0.74.0",
"reportCreatedAt": "2026-09-14",
"scope": "published runtime image",
"high": 0,
"critical": 0,
"secrets": 0
}
},
{
"reference": "ghcr.io/pasturestack/network-plugin-manager:v0.6.34",
"sourceRepository": "https://github.com/PastureStack/network-plugin-manager",
Expand Down Expand Up @@ -319,6 +338,26 @@
"critical": 0
}
},
{
"reference": "ghcr.io/pasturestack/network-plugin-manager:v0.8.18",
"manifestDigest": "sha256:1f5d44de03648a771ec9e7bc448e456ef6b21a5fcd4cc51f59f99df96a804822",
"sourceRepository": "https://github.com/PastureStack/network-plugin-manager",
"sourceCommit": "b52eddfa948a3f862c4d9ed78bce0fe1fe5dc22b",
"sourcePath": "package/Dockerfile",
"registryPage": "https://github.com/orgs/PastureStack/packages/container/package/network-plugin-manager",
"licenseBoundary": "Apache-2.0 source and image; bundled Alpine, Docker CLI, and other packages retain their upstream licenses and notices",
"reviewedAt": "2026-09-14",
"platforms": [
"linux/amd64"
],
"vulnerabilityScan": {
"scanner": "Trivy 0.74.0",
"reportCreatedAt": "2026-09-14",
"scope": "published runtime image",
"high": 0,
"critical": 0
}
},
{
"reference": "ghcr.io/pasturestack/network-diagnostics-agent:v0.2.0",
"sourceRepository": "https://github.com/PastureStack/network-diagnostics-agent",
Expand Down
26 changes: 26 additions & 0 deletions infra-templates/layer-2-flat-network/4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# PastureStack Layer 2 Flat Network

This infrastructure template connects managed workloads directly to a shared
physical Layer 2 subnet. Every participating host must reach the same subnet
and gateway, and the selected workload range must not overlap DHCP, host, or
infrastructure addresses.

Automatic bridge setup is disabled by default because moving a host's physical
interface into a bridge can interrupt remote access when the interface, subnet,
or gateway is wrong. Prepare the bridge through the operating system first, or
verify out-of-band console access before enabling automatic setup.

The template uses
`ghcr.io/pasturestack/ipsec-vxlan-overlay-network:v0.14.36`, which contains the
reviewed `pasture-bridge` and `flat-cni-ipam` executables. The image source is
[`PastureStack/ipsec-vxlan-overlay-network@f754bab6dc63c4e51b849a106fcdc792f644b9ef`](https://github.com/PastureStack/ipsec-vxlan-overlay-network/tree/f754bab6dc63c4e51b849a106fcdc792f644b9ef);
the Flat CNI IPAM source is
[`PastureStack/flat-cni-ipam@047eb2ffc5a985810fbc8a9a25150698facc6ae6`](https://github.com/PastureStack/flat-cni-ipam/tree/047eb2ffc5a985810fbc8a9a25150698facc6ae6).

The template files and icon are MIT licensed. The runtime projects are
Apache-2.0; operating-system packages and bundled components retain their own
upstream licenses and notices.

This version packages a bridge CNI that honors `skipBridgeConfigureIP`, leaving a preconfigured bridge address unchanged. It does not change host bridge
ownership or enable automatic physical-interface migration. Verify the real
Layer 2 path and rollback before enabling this optional driver on a host.
23 changes: 23 additions & 0 deletions infra-templates/layer-2-flat-network/4/README.zh-TW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# PastureStack 第 2 層平面網路

此基礎架構範本會透過主機網橋,將受管工作負載直接連接到共用的實體
第 2 層子網路。每台參與主機都必須能連上相同的子網路與閘道,而且
選定的工作負載位址範圍不得與 DHCP、主機或基礎架構位址重疊。

自動設定網橋預設為停用。若實體介面、子網路或閘道設定錯誤,把主機
實體介面移入網橋可能會中斷遠端連線。請優先透過作業系統準備網橋;
若要啟用自動設定,請先確認具備頻外主控台存取方式。

此範本使用
`ghcr.io/pasturestack/ipsec-vxlan-overlay-network:v0.14.36`,
其中包含經審核的 `pasture-bridge` 與 `flat-cni-ipam` 執行檔。
映像原始碼位於
[`PastureStack/ipsec-vxlan-overlay-network@f754bab6dc63c4e51b849a106fcdc792f644b9ef`](https://github.com/PastureStack/ipsec-vxlan-overlay-network/tree/f754bab6dc63c4e51b849a106fcdc792f644b9ef),
Flat CNI IPAM 原始碼位於
[`PastureStack/flat-cni-ipam@047eb2ffc5a985810fbc8a9a25150698facc6ae6`](https://github.com/PastureStack/flat-cni-ipam/tree/047eb2ffc5a985810fbc8a9a25150698facc6ae6)。

範本檔案與圖示採 MIT 授權;執行專案採 Apache-2.0 授權。作業系統
套件及隨附元件保留各自的上游授權及聲明。

此版隨附會遵守 `skipBridgeConfigureIP` 的橋接 CNI,保留已設定的網橋位址;不改變主機網橋權責,也不自動搬移實體網路
介面。啟用此選用驅動程式前,仍須驗證真實第 2 層連線及回復方式。
70 changes: 70 additions & 0 deletions infra-templates/layer-2-flat-network/4/docker-compose.yml.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# SPDX-License-Identifier: MIT
version: '2'

services:
layer-2-flat-cni:
image: ghcr.io/pasturestack/ipsec-vxlan-overlay-network:v0.14.36
privileged: true
network_mode: host
pid: host
{{- if eq .Values.AUTO_SETUP_LAYER_2_BRIDGE "true" }}
command:
- /bin/bash
- -ceu
- start-flat.sh && exec start-cni-driver.sh
{{- else }}
command: start-cni-driver.sh
{{- end }}
environment:
PASTURESTACK_DEBUG: '${PASTURESTACK_DEBUG}'
PASTURESTACK_METADATA_ADDRESS: '${PASTURESTACK_METADATA_ADDRESS}'
FLAT_IF: '${FLAT_INTERFACE}'
FLAT_BRIDGE: '${LAYER_2_BRIDGE}'
MTU: '${MTU}'
labels:
io.pasturestack.component: layer-2-flat-cni
io.rancher.network.cni.binary: pasture-bridge
io.rancher.container.dns: 'true'
io.rancher.scheduler.global: 'true'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- rancher-cni-driver:/opt/cni-driver
logging:
driver: json-file
options:
max-size: 25m
max-file: '2'
network_driver:
name: PastureStack Layer 2 Flat Network
default_network:
name: layer-2-flat
host_ports: {{ .Values.HOST_PORTS }}
subnets:
- network_address: ${SUBNET}
start_address: ${START_ADDRESS}
end_address: ${END_ADDRESS}
dns:
- 169.254.169.250
dns_search:
- pasture.internal
cni_config:
'10-pasturestack-layer-2-flat.conf':
name: pasturestack-layer-2-flat-network
type: pasture-bridge
bridge: ${LAYER_2_BRIDGE}
bridgeSubnet: ${SUBNET}
logToFile: /var/log/pasturestack-cni.log
isDebugLevel: ${PASTURESTACK_DEBUG}
hostNat: false
mtu: ${MTU}
skipBridgeConfigureIP: true
skipFastPath: true
ipam:
type: flat-cni-ipam
metadataURL: http://169.254.169.250/2015-12-19
metadataAddress: 169.254.169.250
logToFile: /var/log/pasturestack-cni.log
isDebugLevel: ${PASTURESTACK_DEBUG}
routes:
- dst: 0.0.0.0/0
gw: ${GATEWAY}
96 changes: 96 additions & 0 deletions infra-templates/layer-2-flat-network/4/rancher-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# SPDX-License-Identifier: MIT
.catalog:
name: PastureStack Layer 2 Flat Network
version: v0.3.2
description: Connect managed workloads directly to a shared Layer 2 subnet through a host bridge.
minimum_rancher_version: v1.6.26-rc1
labels:
io.pasturestack.catalog.question.layer_2_bridge.label.zh-tw: '第 2 層網橋'
io.pasturestack.catalog.question.layer_2_bridge.description.zh-tw: '共用第 2 層網路使用的既有或自動設定主機網橋。'
io.pasturestack.catalog.question.flat_interface.label.zh-tw: '實體網路介面'
io.pasturestack.catalog.question.flat_interface.description.zh-tw: '只有啟用自動網橋設定時,才會把此主機實體介面加入網橋。'
io.pasturestack.catalog.question.auto_setup_layer_2_bridge.label.zh-tw: '自動設定網橋'
io.pasturestack.catalog.question.auto_setup_layer_2_bridge.description.zh-tw: '把實體介面的位址移到第 2 層網橋;啟用前請先確認可使用主控台連線。'
io.pasturestack.catalog.question.subnet.label.zh-tw: '共用子網路'
io.pasturestack.catalog.question.subnet.description.zh-tw: '主機、網橋、閘道與受管工作負載共用的 IPv4 子網路。'
io.pasturestack.catalog.question.start_address.label.zh-tw: '第一個工作負載位址'
io.pasturestack.catalog.question.start_address.description.zh-tw: '控制平面可分配給受管工作負載的第一個 IPv4 位址。'
io.pasturestack.catalog.question.end_address.label.zh-tw: '最後一個工作負載位址'
io.pasturestack.catalog.question.end_address.description.zh-tw: '控制平面可分配給受管工作負載的最後一個 IPv4 位址。'
io.pasturestack.catalog.question.gateway.label.zh-tw: '預設閘道'
io.pasturestack.catalog.question.gateway.description.zh-tw: '共用子網路中受管工作負載使用的 IPv4 閘道。'
io.pasturestack.catalog.question.mtu.label.zh-tw: '網路 MTU'
io.pasturestack.catalog.question.mtu.description.zh-tw: '實體第 2 層網路端對端支援的 MTU。'
io.pasturestack.catalog.question.host_ports.label.zh-tw: '啟用主機連接埠'
io.pasturestack.catalog.question.host_ports.description.zh-tw: '允許受管工作負載在主機上公開連接埠。'
io.pasturestack.catalog.question.pasturestack_metadata_address.label.zh-tw: '中繼資料服務位址'
io.pasturestack.catalog.question.pasturestack_metadata_address.description.zh-tw: '相容中繼資料服務使用的連結本機 IPv4 位址。'
io.pasturestack.catalog.question.pasturestack_debug.label.zh-tw: '啟用除錯日誌'
io.pasturestack.catalog.question.pasturestack_debug.description.zh-tw: '記錄較詳細的網橋設定與 CNI 操作診斷資訊。'
questions:
- variable: LAYER_2_BRIDGE
label: Layer 2 bridge
description: Existing or automatically configured host bridge used by the shared Layer 2 network.
type: string
default: flatbr0
required: true
- variable: FLAT_INTERFACE
label: Physical interface
description: Physical host interface to attach to the bridge only when automatic bridge setup is enabled.
type: string
default: eth0
required: true
- variable: AUTO_SETUP_LAYER_2_BRIDGE
label: Configure the bridge automatically
description: Move the physical interface address onto the Layer 2 bridge. Verify console access before enabling this option.
type: boolean
default: 'false'
required: true
- variable: SUBNET
label: Shared subnet
description: IPv4 subnet shared by the hosts, bridge, gateway, and managed workloads.
type: string
default: 192.0.2.0/24
required: true
- variable: START_ADDRESS
label: First workload address
description: First IPv4 address that the control plane may assign to a managed workload.
type: string
default: 192.0.2.100
required: true
- variable: END_ADDRESS
label: Last workload address
description: Last IPv4 address that the control plane may assign to a managed workload.
type: string
default: 192.0.2.199
required: true
- variable: GATEWAY
label: Default gateway
description: IPv4 gateway for managed workloads on the shared subnet.
type: string
default: 192.0.2.1
required: true
- variable: MTU
label: Network MTU
description: MTU supported end to end by the physical Layer 2 network.
type: int
default: 1500
required: true
- variable: HOST_PORTS
label: Enable host ports
description: Allow managed workloads to publish ports on their hosts.
type: boolean
default: 'true'
required: true
- variable: PASTURESTACK_METADATA_ADDRESS
label: Metadata address
description: Link-local IPv4 address of the compatible metadata service.
type: string
default: 169.254.169.250
required: true
- variable: PASTURESTACK_DEBUG
label: Enable debug logs
description: Enable verbose diagnostics for bridge setup and CNI operations.
type: boolean
default: 'false'
required: true
2 changes: 1 addition & 1 deletion infra-templates/layer-2-flat-network/config.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
name: Layer 2 Flat Network
description: Connect managed workloads directly to a shared Layer 2 subnet through a host bridge.
version: v0.3.1
version: v0.3.2
category: Networking
maintainer: PastureStack contributors
license: MIT template; Apache-2.0 image and bundled component licenses apply
Expand Down
39 changes: 39 additions & 0 deletions infra-templates/network-services/6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!-- SPDX-License-Identifier: MIT -->

# PastureStack Network Services

Version 6 uses Network Plugin Manager `v0.8.18`. It retains single-backend selection and unchanged Metadata Service and Internal DNS images. It also restores bidirectional VXLAN forwarding when published host ports coexist with the overlay. The manager rejects malformed per-host subnet labels before touching host firewall rules; the optional per-host-subnet network preserves container source IPs across active peers and permits only peer-to-local-subnet forwarding. The image's release provenance and digest are recorded in `catalog-images.json`.

## Firewall backend

`FIREWALL_BACKEND` defaults to `auto`. It reads Docker's actual firewall driver: Docker's native `nftables` driver uses native nft rules, while Docker's `iptables` driver selects the frontend that owns Docker's active NAT chain. That may be `iptables-nft` or `iptables-legacy` on **any supported host**, including Ubuntu 26.04 and later. The OS release, installed executable, or unloaded kernel module alone never selects a backend. To pin one path, choose:

- `nftables`: Docker's native nftables firewall backend. This is **not** the same as the iptables-nft compatibility CLI.
- `iptables-nft`: xtables compatibility CLI backed by nf_tables, for Docker's iptables firewall driver.
- `iptables-legacy`: legacy xtables, only when the running Docker daemon actually owns the active rules through that frontend.

The manager refuses a mismatched or ambiguous selection and does not fall back, switch Docker's backend, or load legacy modules. An Ubuntu 26.04+ host already using `iptables-legacy` or `iptables-nft` must keep its live Docker path; do not turn on native nftables merely because the OS is new. A deliberate migration requires a separate host change, rollback point, and network lifecycle test.

This manager alone owns the host NAT and host-port `CATTLE_*` chains. Its
masquerade rules exclude destinations inside the managed overlay subnet in
all three backends; the IPsec host-XFRM router must not patch these chains.
For the per-host-subnet driver, the manager also excludes other active hosts'
validated subnets from masquerade and adds a bounded forwarding exception.
Inactive registrations are ignored; missing or overlapping labels on an active
host fail closed. This is a routed, unencrypted network; protect the host
transport separately.
Upgrade Network Services first and verify manager health on every host before
upgrading the matching IPsec Overlay version.

For Docker's native nftables driver, configure Docker itself with `"firewall-backend": "nftables"` and `"bridge-accept-fwmark": "0x1068/0x1068"` before upgrading this stack. Persist `net.ipv4.ip_forward=1` on the host and verify it remains enabled after a reboot: Docker's native nftables backend does not enable IPv4 forwarding for you. The mark allows Docker's bridge forwarding rules to accept the manager's published-host-port traffic; the template cannot configure the host daemon or kernel settings. Check and explicitly migrate any stale `iptables-nft` `FORWARD DROP` policy or previous platform hooks before switching Docker. The manager refuses that mixed state rather than changing the host's global firewall policy. Docker's native nftables backend remains an experimental Docker feature; qualify it against the installed Docker release before production use.

## Other configuration

- `DOCKER_BRIDGE`: host bridge for managed workload traffic.
- `DNS_RECURSER_TIMEOUT`, `TTL`: upstream DNS timeout and service-discovery cache time.
- `CPU_PERIOD`, `CPU_QUOTA`: Metadata Service CPU scheduling limits.
- `RELOAD_INTERVAL_LIMIT`, `ARP_SYNC_INTERVAL`: metadata reload and host ARP reconciliation intervals.

Network Plugin Manager still requires host networking, host PID visibility, the Docker socket, Docker state, kernel-module and runtime mounts, and the shared CNI volume. Metadata Service starts as root only to assign its link-local address, then drops to UID/GID 10001. Internal DNS shares its namespace. The `rancher-compose.yml` filename, `io.rancher.*` labels, `CATTLE_*` fallback variables, `/var/lib/rancher` CA path, and `rancher-cni-driver` volume are compatibility contracts, not a request to use legacy firewall rules.

These template files are MIT-licensed. The manager, metadata service, and internal DNS retain their Apache-2.0 licenses and bundled dependency notices. Verify image source and the recorded manifest digest in `catalog-images.json` before deployment.
Loading