Firewall added & some fixes
This commit is contained in:
100
handlers/firewall.go
Normal file
100
handlers/firewall.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
|
||||
"alpine-router/config"
|
||||
"alpine-router/nat"
|
||||
"alpine-router/network"
|
||||
)
|
||||
|
||||
func HandleFirewall(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
handleFirewallGet(w, r)
|
||||
case http.MethodPost:
|
||||
handleFirewallSave(w, r)
|
||||
default:
|
||||
fail(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func handleFirewallGet(w http.ResponseWriter, r *http.Request) {
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Collect interface names for the UI dropdowns.
|
||||
names, _ := network.GetInterfaces()
|
||||
|
||||
ok(w, map[string]interface{}{
|
||||
"installed": nat.IsInstalled(),
|
||||
"rules": cfg.Firewall.Rules,
|
||||
"vlan_isolation": cfg.Firewall.VLANIsolation,
|
||||
"interfaces": names,
|
||||
})
|
||||
}
|
||||
|
||||
func handleFirewallSave(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
Rules []config.FirewallRule `json:"rules"`
|
||||
VLANIsolation bool `json:"vlan_isolation"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
fail(w, http.StatusBadRequest, "invalid json: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Assign IDs to new rules that lack one.
|
||||
for i := range body.Rules {
|
||||
if body.Rules[i].ID == "" {
|
||||
body.Rules[i].ID = fmt.Sprintf("%x", rand.Int63())
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, "load config: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cfg.Firewall.Rules = body.Rules
|
||||
cfg.Firewall.VLANIsolation = body.VLANIsolation
|
||||
|
||||
if err := config.Save(cfg); err != nil {
|
||||
fail(w, http.StatusInternalServerError, "save config: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ok(w, map[string]string{"message": "saved"})
|
||||
}
|
||||
|
||||
func HandleFirewallApply(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
fail(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
|
||||
if !nat.IsInstalled() {
|
||||
fail(w, http.StatusServiceUnavailable, "nftables (nft) не установлен — выполните: apk add nftables")
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
fail(w, http.StatusInternalServerError, "load config: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := applyAllRules(cfg); err != nil {
|
||||
fail(w, http.StatusInternalServerError, "apply: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ok(w, map[string]string{"message": "firewall applied"})
|
||||
}
|
||||
Reference in New Issue
Block a user