{"id":50706183,"url":"https://github.com/jenting/vallum","last_synced_at":"2026-06-09T12:01:45.460Z","repository":{"id":363024037,"uuid":"1261637657","full_name":"jenting/vallum","owner":"jenting","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-07T09:22:07.000Z","size":99,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T10:13:43.193Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jenting.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-07T00:42:48.000Z","updated_at":"2026-06-07T09:22:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jenting/vallum","commit_stats":null,"previous_names":["jenting/sz","jenting/vallum"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jenting/vallum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenting%2Fvallum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenting%2Fvallum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenting%2Fvallum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenting%2Fvallum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jenting","download_url":"https://codeload.github.com/jenting/vallum/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jenting%2Fvallum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34105565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-09T12:01:40.736Z","updated_at":"2026-06-09T12:01:45.455Z","avatar_url":"https://github.com/jenting.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vallum — 100.x 東西向防火牆集中管控平台\n\n\u003e *Vallum*：羅馬的防禦長城（如 Hadrian's Wall）。跨異質環境（k8s + Linux + Windows VM）\n\u003e 拉一道統一的東西向防火牆 —— 不靠底層（kubevirt/VMware），規則做在 guest OS 與 k8s namespace。\n\n自建（in-house，不買商用），預設 **deny `100.0.0.0/8`** 東西向、嚴格 allowlist。\n\n## 模組（全部完成，皆在 Azure 端到端實測通過）\n\n| # | 模組 | 技術 | 狀態 |\n|---|---|---|---|\n| 1 | 控制面 zone UI + generator | static HTML（zone×zone 矩陣）+ Python（model→規則） | ✅ |\n| 2 | k8s 強制 | Cilium **CNP**（deny-only + except，namespaced） | ✅ |\n| 2b | k8s 自動覆蓋 | **Kyverno** generate + Argo CD（含 bypass 還原） | ✅ |\n| 3 | Linux VM 強制 | **nftables** + Ansible（push / apply-on-change） | ✅ |\n| 4 | Windows VM 強制 | **Windows Defender Firewall**（補集 block，PowerShell） | ✅ |\n| 5 | 合規 dashboard | Python 蒐集 + 靜態 HTML（五態，含 bypass/未納管偵測） | ✅ |\n\n**核心閉環**：中央 zone model → generator 編譯 → k8s + Linux + Windows 三種強制 → 合規可視化。\n\n---\n\n# 入口：控制面（Zone UI + Generator）\n\n集中以 **zone（label 群組）+ zone×zone 矩陣**管理東西向政策，編譯成各強制點的設定，走 GitOps 套用。\n\n```bash\n./scripts/serve-ui.sh                 # 開 http://localhost:8765/ui/ 編矩陣、匯出 model.json\npython3 controlplane/generate.py      # model.json → 各強制目標的設定檔\ncd controlplane \u0026\u0026 python3 -m unittest test_generate -v   # 編譯邏輯單元測試\n```\n\n- **Source of truth**：`controlplane/model.json` —— `zones`、`members`（entity↔zone↔CIDR mapping）、`allow`（zone×zone 對稱矩陣）。\n- entity 的 allowlist = 其 zone 經矩陣可達的所有 zone 的 CIDR 聯集。\n- **generator 一次產出三種強制目標**：\n\n| member kind | 產出 | 套用 |\n|---|---|---|\n| `k8s-ns` | Cilium CNP → `gitops/generated/k8s/\u003ccluster\u003e/` | Argo / kubectl |\n| `linux-vm` | nftables allowlist → `ansible/host_vars/\u003chost\u003e.yml` | `ansible/apply.sh` |\n| `windows-vm` | Windows FW 腳本 → `gitops/generated/windows/\u003chost\u003e.ps1` | `RunPowerShellScript` |\n\n設計: `docs/superpowers/specs/2026-06-07-vallum-zone-controlplane-design.md`\n\n![Vallum zone UI](docs/images/zone-ui.png)\n\n\u003e 跨域 allow（例如 Windows ↔ Linux）需**兩端各自套用** —— host-based 各自強制是本質，不是 bug。\n\n---\n\n# 強制目標 ① k8s（Cilium CNP）\n\n每個 in-scope namespace 各部署一份 CNP：`foo=bar` namespace 可雙向通指定 peer，其餘 100.x 全擋。\n\n- deny-only + `except`，並設 `enableDefaultDeny:{ingress,egress}=false` —— 只扣 100.x，不誤傷 DNS / 叢集內流量。\n- CNP 是 **namespaced**；`foo=bar` 與否由「部署哪份 CNP」決定。\n\n真值表（PoC 場景，vm-02=`100.64.2.0/24`）:\n\n| 流量 | 結果 |\n|---|---|\n| `foo=bar` ns ↔ vm-02 | ✅ 雙向 |\n| `foo=bar` ns → vm-01 / 其餘 100.x | ⛔ |\n| 其他 ns → 任何 100.x | ⛔ |\n| 叢集內 node↔node / pod↔apiserver / DNS | ✅ 不受影響 |\n\n### Provisioning（每叢集，在 Azure node 上）\n```bash\nROLE=server ./provision/k3s-install.sh                 # k3s（關 flannel）\n# 多 node: ROLE=agent K3S_URL=https://\u003cserver-ip\u003e:6443 K3S_TOKEN=\u003ctoken\u003e ./provision/k3s-install.sh\nCILIUM_VERSION=1.16.3 ./provision/cilium-install.sh    # 對該叢集 kubeconfig 裝 Cilium\n```\n\n### 套用 + 驗收\n```bash\nCONTEXT=\u003ckube-context\u003e ./scripts/apply.sh                                   # 套 namespace/CNP/netshoot\nCONTEXT=\u003ckube-context\u003e VM02=100.64.2.4 VM01=100.64.1.4 ./scripts/verify.sh  # egress 真值表\nCONTEXT=\u003ckube-context\u003e ./scripts/verify-reverse.sh                          # 反向（VM→pod，NodePort+eTP=Local）\n```\n\u003e 反向需 NodePort + `externalTrafficPolicy: Local` 保留來源 IP，Cilium 才能用 CIDR identity 比對 `except`。\n\n### 自動覆蓋（Kyverno + Argo CD）— #2b\n手動逐 ns 部署有覆蓋率漏洞。Kyverno `generate` 自動補：非系統 ns 一律拿到對的 CNP，新 ns 即時覆蓋，被改/刪的 CNP 由 `synchronize:true` 還原（順便抓 bypass）。\n```bash\nhelm repo add kyverno https://kyverno.github.io/kyverno/ \u0026\u0026 helm repo update\nhelm upgrade --install kyverno kyverno/kyverno -n kyverno --create-namespace --version 3.2.6\nkubectl --context \u003cctx\u003e apply -f gitops/kyverno/          # RBAC + ClusterPolicy\nCONTEXT=\u003cctx\u003e ./scripts/verify-gitops.sh                  # 自動覆蓋 / label 切換 / bypass 還原\n```\n正式以 Argo CD 交付: `gitops/argocd/appset-eastwest.yaml`。\n設計: `…/specs/2026-06-07-k8s-cilium-eastwest-adapter-design.md`、`…/2026-06-07-eastwest-cnp-gitops-kyverno-design.md`\n\n---\n\n# 強制目標 ② Linux VM（nftables，host-based）\n\nCNP 只在 k8s 內執行，管不到 VM↔VM。Linux VM 用 nftables 補上：專屬 table 只 drop `100.0.0.0/8`，嚴格 allowlist（host_vars 指定放行的 100.x peer），其餘 100.x（含 k3s node）全擋，對外/管理面不受影響。\n\n```bash\n# 在 VM 上（PoC 用 az run-command 推；正式由 CI/AWX 經 SSH）\nsudo REPO=https://github.com/jenting/vallum.git bash ansible/apply.sh\nALLOW=\u003cpeer-ip\u003e DENY_K3S=100.64.11.4 ./scripts/verify-vm.sh   # ALLOW 對端需開 :80 監聽\n```\n設計取捨: apply-on-change 推一次，**不做 reconcile、無 cron、無自寫 systemd**；規則重開機後需重推。\n設計: `…/specs/2026-06-07-linux-nftables-eastwest-ansible-design.md`\n\n---\n\n# 強制目標 ③ Windows VM（Windows Defender Firewall）\n\nWindows FW 沒有 except 且 Block 優先於 Allow，故 generator 預算 `100.0.0.0/8 − allowlist` **補集**，產 PowerShell 建 Inbound/Outbound Block 規則（Group `Vallum`）。\n\n```bash\n./provision/win-vm-create.sh          # 建 Windows Server 2022 VM（PoC）\npython3 controlplane/generate.py      # model.json → gitops/generated/windows/\u003chost\u003e.ps1\naz vm run-command invoke -g JENTING-RESOURCE-GROUP -n jenting-win-01 \\\n  --command-id RunPowerShellScript --scripts @gitops/generated/windows/jenting-win-01.ps1\nVM=jenting-win-01 ALLOW=100.64.2.4 DENY=100.64.1.4 ./scripts/verify-win.sh\n```\n設計: `…/specs/2026-06-07-windows-defender-fw-eastwest-design.md`\n\n---\n\n# 合規 Dashboard — #5\n\n唯讀稽核全機隊東西向狀態（k8s CNP + VM nft + Windows FW），對比 model.json 的 expected，加上發現未納管 entity，產靜態 HTML。\n\n```bash\npython3 controlplane/audit.py         # 蒐集→比對→ controlplane/out/compliance.html\n./scripts/serve-report.sh             # 開 http://localhost:8766/compliance.html\ncd controlplane \u0026\u0026 python3 -m unittest test_dashboard -v   # 純函式單元測試\n```\n五態: 🟢COMPLIANT 🔴MISSING 🟠DRIFT 🟣BYPASS ⚪UNMANAGED（後二者對應「誰繞過 / 誰沒設好」）。\n設計: `…/specs/2026-06-07-vallum-compliance-dashboard-design.md`\n\n![Vallum 合規 dashboard](docs/images/compliance-dashboard.png)\n\n---\n\n## 參考：IP 分配（Azure `jenting-vnet` = `100.64.0.0/16`，PoC 環境）\n\n| Entity | subnet / IP | zone | 角色 |\n|---|---|---|---|\n| jenting-k3s-host-01（k8s-01） | `100.64.11.0/24` / `.11.4` | k8s-web | 叢集 node（不受 CIDR 政策影響） |\n| jenting-k3s-host-02（k8s-02） | `100.64.12.0/24` / `.12.4` | — | 叢集 node |\n| jenting-vm-01 | `100.64.1.0/24` / `.1.4` | vm-a | Linux VM |\n| jenting-vm-02 | `100.64.2.0/24` / `.2.4` | vm-b | Linux VM |\n| jenting-win-01 | `100.64.3.0/24` / `.3.4` | win-prod | Windows VM |\n\n## Caveats\n- **k8s 覆蓋率**: 沒部署 CNP 的 namespace 不會被擋 → 用 Kyverno 自動覆蓋（#2b）。\n- **Cilium**: 若啟用 `policy-cidr-match-mode: nodes`，deny 100.x 會誤擋 node↔node；本 PoC 維持預設（空）。\n- **Linux/Windows**: apply-on-change，無持續 reconcile；被竄改的自動還原靠合規面（#5）偵測，或中央排程重推。\n- **跨域 allow**: 兩個 host 間互通需兩端各自放行（host-based 本質）。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenting%2Fvallum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjenting%2Fvallum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjenting%2Fvallum/lists"}