owned.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package firewall
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. // ownedPayload confines DebTik rules to dedicated chains. The host's chains,
  7. // policies and rules are left intact; only legacy DebTik ID rules are migrated.
  8. func ownedPayload(payload, live string) string {
  9. liveTables := map[string][]string{}
  10. table := ""
  11. for _, line := range strings.Split(live, "\n") {
  12. if strings.HasPrefix(line, "*") {
  13. table = line[1:]
  14. } else if strings.HasPrefix(line, "-A ") {
  15. liveTables[table] = append(liveTables[table], line)
  16. }
  17. }
  18. var out strings.Builder
  19. for _, block := range strings.Split(payload, "COMMIT") {
  20. lines := strings.Split(strings.TrimSpace(block), "\n")
  21. if len(lines) == 0 || !strings.HasPrefix(lines[0], "*") {
  22. continue
  23. }
  24. table = lines[0][1:]
  25. names := map[string]string{}
  26. var chains []string
  27. for _, line := range lines[1:] {
  28. if strings.HasPrefix(line, ":") {
  29. name := strings.Fields(line)[0][1:]
  30. names[name] = "DT_" + table + "_" + name
  31. chains = append(chains, name)
  32. }
  33. }
  34. fmt.Fprintf(&out, "*%s\n", table)
  35. for _, chain := range chains {
  36. fmt.Fprintf(&out, ":%s - [0:0]\n-F %s\n", names[chain], names[chain])
  37. }
  38. for _, line := range liveTables[table] {
  39. if !strings.HasPrefix(strings.Fields(line)[1], "DT_") && strings.Contains(line, "--comment") && (strings.Contains(line, "id:filter-") || strings.Contains(line, "id:nat-") || strings.Contains(line, "id:mangle-")) {
  40. out.WriteString("-D " + strings.TrimPrefix(line, "-A ") + "\n")
  41. }
  42. }
  43. for _, line := range lines[1:] {
  44. fields := strings.Fields(line)
  45. if len(fields) < 2 || fields[0] != "-A" {
  46. continue
  47. }
  48. line = strings.Replace(line, "-A "+fields[1]+" ", "-A "+names[fields[1]]+" ", 1)
  49. for original, owned := range names {
  50. line = strings.ReplaceAll(line, "-j "+original+" ", "-j "+owned+" ")
  51. if strings.HasSuffix(line, "-j "+original) {
  52. line = strings.TrimSuffix(line, "-j "+original) + "-j " + owned
  53. }
  54. }
  55. out.WriteString(line + "\n")
  56. }
  57. for _, chain := range chains {
  58. builtin := chain == "INPUT" || chain == "OUTPUT" || chain == "FORWARD" || chain == "PREROUTING" || chain == "POSTROUTING"
  59. if !builtin {
  60. continue
  61. }
  62. exists := false
  63. for _, line := range liveTables[table] {
  64. if strings.HasPrefix(line, "-A "+chain+" ") && strings.Contains(line, "debtik:hook") && strings.HasSuffix(line, "-j "+names[chain]) {
  65. exists = true
  66. break
  67. }
  68. }
  69. if !exists {
  70. fmt.Fprintf(&out, "-I %s 1 -m comment --comment debtik:hook -j %s\n", chain, names[chain])
  71. }
  72. }
  73. out.WriteString("COMMIT\n")
  74. }
  75. return out.String()
  76. }