ipset.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package firewall
  2. import (
  3. "os/exec"
  4. "strings"
  5. )
  6. // SyncAddressLists updates Linux ipsets to match the configured AddressList entries
  7. func SyncAddressLists(entries []AddressListEntry) error {
  8. // Group addresses by list name
  9. listMap := make(map[string][]string)
  10. for _, e := range entries {
  11. if e.Disabled || e.Name == "" || e.Address == "" {
  12. continue
  13. }
  14. listMap[e.Name] = append(listMap[e.Name], e.Address)
  15. }
  16. // Clean up any mk_ sets that no longer exist or are now empty
  17. if out, err := exec.Command("ipset", "list", "-name").Output(); err == nil {
  18. lines := strings.Split(string(out), "\n")
  19. for _, line := range lines {
  20. line = strings.TrimSpace(line)
  21. if strings.HasPrefix(line, "mk_") {
  22. name := strings.TrimPrefix(line, "mk_")
  23. if _, ok := listMap[name]; !ok {
  24. _ = exec.Command("ipset", "flush", line).Run()
  25. _ = exec.Command("ipset", "destroy", line).Run()
  26. }
  27. }
  28. }
  29. }
  30. for name, addrs := range listMap {
  31. setName := "mk_" + strings.ReplaceAll(name, " ", "_")
  32. // Create set if not exists
  33. _ = exec.Command("ipset", "create", setName, "hash:net", "-exist").Run()
  34. _ = exec.Command("ipset", "flush", setName).Run()
  35. for _, a := range addrs {
  36. _ = exec.Command("ipset", "add", setName, a, "-exist").Run()
  37. }
  38. }
  39. return nil
  40. }
  41. // GetIPSetName returns the internal ipset name for an address list
  42. func GetIPSetName(listName string) string {
  43. if listName == "" {
  44. return ""
  45. }
  46. return "mk_" + strings.ReplaceAll(listName, " ", "_")
  47. }