Files
orca/internal/emitter/nft_test.go
T
Jon Chery 8d1cdceb5c feat(P15.5): threat model (C-19) + ingress hybrid (R-017, REQ-099..102) + doctor mTLS (REQ-118)
Sub-wave 1: internal/emitter/nft.go (nftables emitter, DNAT :443→127.0.0.1:8443, rate-limit, SYN-flood filter); Traefik static config 127.0.0.1:8443 binding (D-220); orca doctor nft; orca nft CLI (show/diff/doctor/country-block/rate-limit).
Sub-wave 2: docs/threat-model.md (R-017 trust boundary, R-020 deadlock, D-234 secret exclusion, orca user blast radius, step-ca SPOF); orca doctor mTLS (chain verification + live handshake probe, C5).

---ci---
project: orca
phase: 15.5
milestone: v0.11
status: execute
---/ci---
2026-08-07 08:35:06 +00:00

93 lines
2.6 KiB
Go

package emitter
import (
"strings"
"testing"
)
func TestNftEmitter_RenderBasic(t *testing.T) {
files, err := (NftEmitter{}).RenderNftConfig(NftClusterConfig{})
if err != nil {
t.Fatalf("RenderNftConfig: %v", err)
}
if len(files) != 1 {
t.Fatalf("got %d files, want 1", len(files))
}
f := files[0]
if f.Path != "/etc/nftables.d/orca.nft" {
t.Errorf("Path = %q, want /etc/nftables.d/orca.nft", f.Path)
}
if f.Mode != "0644" {
t.Errorf("Mode = %q, want 0644", f.Mode)
}
c := f.Content
for _, want := range []string{
"#!/usr/sbin/nft -f",
"table inet orca-ingress",
"set orca_trusted_probes",
"type ipv4_addr",
"flags interval",
"127.0.0.1",
"::1",
"chain input",
"tcp dport 443 tcp-flags != syn,rst,ack,fin notrack drop",
"chain prerouting",
"tcp dport 443 dnat to 127.0.0.1:8443",
"tcp dport 80 dnat to 127.0.0.1:8080",
"chain forward",
"rate 100/second burst 200 packets",
"ora_rl",
} {
if !strings.Contains(c, want) {
t.Errorf("content missing %q:\n%s", want, c)
}
}
}
func TestNftEmitter_DefaultsApplied(t *testing.T) {
files, err := (NftEmitter{}).RenderNftConfig(NftClusterConfig{RateLimit: 0, RateBurst: 0})
if err != nil {
t.Fatalf("Render: %v", err)
}
if !strings.Contains(files[0].Content, "rate 100/second burst 200 packets") {
t.Errorf("defaults not applied:\n%s", files[0].Content)
}
}
func TestNftEmitter_CustomRate(t *testing.T) {
files, err := (NftEmitter{}).RenderNftConfig(NftClusterConfig{RateLimit: 50, RateBurst: 150})
if err != nil {
t.Fatalf("Render: %v", err)
}
if !strings.Contains(files[0].Content, "rate 50/second burst 150 packets") {
t.Errorf("custom rate not rendered:\n%s", files[0].Content)
}
}
func TestNftEmitter_CustomTrustedProbes(t *testing.T) {
files, err := (NftEmitter{}).RenderNftConfig(NftClusterConfig{TrustedProbes: []string{"10.0.0.5", "192.168.1.1"}})
if err != nil {
t.Fatalf("Render: %v", err)
}
c := files[0].Content
if !strings.Contains(c, "10.0.0.5, 192.168.1.1") {
t.Errorf("custom probes not rendered:\n%s", c)
}
if strings.Contains(c, "::1") {
t.Errorf("default ::1 should not be present when custom probes set:\n%s", c)
}
}
func TestNftEmitter_NegativeRateRejected(t *testing.T) {
if _, err := (NftEmitter{}).RenderNftConfig(NftClusterConfig{RateLimit: -1}); err == nil {
t.Fatal("expected error for negative rate, got nil")
}
}
func TestNftEmitter_ShebangFirst(t *testing.T) {
files, _ := (NftEmitter{}).RenderNftConfig(NftClusterConfig{})
if !strings.HasPrefix(files[0].Content, "#!/usr/sbin/nft -f\n") {
t.Errorf("shebang not first:\n%s", files[0].Content[:40])
}
}