refactor: fw.conf JSON config replacing flat .env

This commit is contained in:
admin 2026-08-02 09:17:49 +00:00
parent 1c2dbb9540
commit 11dade0c5e

View file

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"encoding/json"
"flag" "flag"
"fmt" "fmt"
"os" "os"
@ -88,7 +89,7 @@ func showMenu() {
} }
} }
// ─── .env parsing with per-node keys ────────────────────────────────── // ─── Config (fw.conf JSON) ──────────────────────────────────────────
type nodeConfig struct { type nodeConfig struct {
Name string Name string
@ -98,18 +99,70 @@ type nodeConfig struct {
UpstreamIP string UpstreamIP string
UpstreamPort string UpstreamPort string
Labels string Labels string
BlockMode bool Mode string
}
type fwConfig struct {
Nodes map[string]struct {
Token string `json:"token"`
Cloud string `json:"cloud"`
Port string `json:"port"`
UpstreamIP string `json:"upstream_ip"`
UpstreamPort string `json:"upstream_port"`
Labels string `json:"labels"`
Mode string `json:"mode"`
} `json:"nodes"`
}
func loadConfig() (fwConfig, error) {
var cfg fwConfig
data, err := os.ReadFile("/opt/fw/fw.conf")
if os.IsNotExist(err) {
// Fall back to legacy .env
return fwConfig{}, fmt.Errorf("no fw.conf")
}
if err != nil {
return cfg, err
}
if err := json.Unmarshal(data, &cfg); err != nil {
return cfg, err
}
return cfg, nil
} }
func loadNodes() []nodeConfig { func loadNodes() []nodeConfig {
cfg, err := loadConfig()
if err != nil {
// Fall back to legacy .env
return loadNodesLegacy()
}
var nodes []nodeConfig
for name, n := range cfg.Nodes {
mode := n.Mode
if mode == "" { mode = "monitoring" }
nodes = append(nodes, nodeConfig{
Name: name,
Token: n.Token,
Cloud: n.Cloud,
Port: n.Port,
UpstreamIP: n.UpstreamIP,
UpstreamPort: n.UpstreamPort,
Labels: n.Labels,
Mode: mode,
})
}
return nodes
}
// loadNodesLegacy reads the old WALLARM_TOKEN_srv1=... format
func loadNodesLegacy() []nodeConfig {
data, _ := os.ReadFile("/opt/fw/.env") data, _ := os.ReadFile("/opt/fw/.env")
env := parseEnv(string(data)) env := parseEnv(string(data))
// First try NODES list
var names []string var names []string
if v := env["WALLARM_NODES"]; v != "" { if v := env["WALLARM_NODES"]; v != "" {
names = strings.Split(v, ",") names = strings.Split(v, ",")
} else if v := env["WALLARM_NODE"]; v != "" { } else if v := env["WALLARM_NODE"]; v != "" {
names = []string{v} // single node legacy names = []string{v}
} }
var nodes []nodeConfig var nodes []nodeConfig
for _, n := range names { for _, n := range names {
@ -123,12 +176,10 @@ func loadNodes() []nodeConfig {
UpstreamIP: env["WALLARM_UPSTREAM_IP_"+n], UpstreamIP: env["WALLARM_UPSTREAM_IP_"+n],
UpstreamPort: env["WALLARM_UPSTREAM_PORT_"+n], UpstreamPort: env["WALLARM_UPSTREAM_PORT_"+n],
Labels: env["WALLARM_LABELS_"+n], Labels: env["WALLARM_LABELS_"+n],
BlockMode: env["WALLARM_BLOCK_"+n] == "true", Mode: env["WALLARM_MODE_"+n],
}) })
} }
if len(nodes) == 0 { if len(nodes) == 0 && env["WALLARM_TOKEN"] != "" {
// Legacy single-node format
if env["WALLARM_TOKEN"] != "" {
nodes = append(nodes, nodeConfig{ nodes = append(nodes, nodeConfig{
Name: env["WALLARM_NODE"], Name: env["WALLARM_NODE"],
Token: env["WALLARM_TOKEN"], Token: env["WALLARM_TOKEN"],
@ -137,10 +188,9 @@ func loadNodes() []nodeConfig {
UpstreamIP: env["WALLARM_UPSTREAM_IP"], UpstreamIP: env["WALLARM_UPSTREAM_IP"],
UpstreamPort: env["WALLARM_UPSTREAM_PORT"], UpstreamPort: env["WALLARM_UPSTREAM_PORT"],
Labels: env["WALLARM_LABELS"], Labels: env["WALLARM_LABELS"],
BlockMode: env["WALLARM_BLOCK"] == "true", Mode: env["WALLARM_MODE"],
}) })
} }
}
return nodes return nodes
} }
@ -220,16 +270,19 @@ func deployOne(nc nodeConfig) {
// Ask for traffic mode // Ask for traffic mode
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
mode := "monitoring" mode := nc.Mode
if mode == "" { mode = "monitoring" }
def := "1"
switch mode {
case "safe_blocking": def = "2"
case "block": def = "3"
case "off": def = "4"
}
fmt.Println("\nTraffic processing mode:") fmt.Println("\nTraffic processing mode:")
fmt.Println(" [1] monitoring — detect attacks, do not block") fmt.Println(" [1] monitoring — detect attacks, do not block")
fmt.Println(" [2] safe_blocking — block only definitely malicious requests") fmt.Println(" [2] safe_blocking — block only definitely malicious requests")
fmt.Println(" [3] block — block all detected attacks") fmt.Println(" [3] block — block all detected attacks")
fmt.Println(" [4] off — disable traffic analysis") fmt.Println(" [4] off — disable traffic analysis")
def := "1"
if nc.BlockMode {
def = "3"
}
fmt.Printf("Choose mode [%s]: ", def) fmt.Printf("Choose mode [%s]: ", def)
ans, _ := reader.ReadString('\n') ans, _ := reader.ReadString('\n')
ans = strings.TrimSpace(ans) ans = strings.TrimSpace(ans)