ffho_netfilter.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #
  2. # FFHO netfilter helper functions
  3. #
  4. import ipaddress
  5. def generate_service_rules (services, acls, af):
  6. rules = []
  7. for srv in services:
  8. rule = ""
  9. comment = srv['descr']
  10. src_prefixes = []
  11. # If there are no DST IPs set at all or DST IPs for this AF set, we have a rule to build,
  12. # if this is NOT the case, there is no rule for this AF to generate, carry on.
  13. if not ((not srv['ips']['4'] and not srv['ips']['6']) or srv['ips'][str(af)]):
  14. continue
  15. # Is/are IP(s) set for this service?
  16. if srv['ips'][str(af)]:
  17. rule += "ip" if af == 4 else "ip6"
  18. dst_ips = srv['ips'][str(af)]
  19. if len (dst_ips) == 1:
  20. rule += " daddr %s " % dst_ips[0]
  21. else:
  22. rule += " daddr { %s } " % ", ".join (dst_ips)
  23. # ACLs defined for this service?
  24. if srv['acl']:
  25. srv_acl = sorted (srv['acl'])
  26. for ace in srv_acl:
  27. ace_pfx = (acls[ace][af])
  28. # Many entries
  29. if type (ace_pfx) == list:
  30. src_prefixes.extend (ace_pfx)
  31. else:
  32. src_prefixes.append (ace_pfx)
  33. acl_comment = "acl: %s" % ", ".join (srv_acl)
  34. # Additional prefixes defined for this service?
  35. if srv['additional_prefixes']:
  36. add_pfx = []
  37. # Additional prefixes are given as a space separated list
  38. for entry in srv['additional_prefixes'].split ():
  39. # Strip commas and spaces, just in case
  40. pfx_str = entry.strip (" ,")
  41. pfx_obj = ipaddress.ip_network (pfx_str)
  42. # We only care for additional pfx for this AF
  43. if pfx_obj.version != af:
  44. continue
  45. add_pfx.append (pfx_str)
  46. if add_pfx:
  47. src_prefixes.extend (add_pfx)
  48. if acl_comment:
  49. acl_comment += ", "
  50. acl_comment += "additional pfx"
  51. # Combine ACL + additional prefixes (if any)
  52. if src_prefixes:
  53. rule += "ip" if af == 4 else "ip6"
  54. if len (src_prefixes) > 1:
  55. rule += " saddr { %s } " % ", ".join (src_prefixes)
  56. else:
  57. rule += " saddr %s " % src_prefixes[0]
  58. if acl_comment:
  59. comment += " (%s)" % acl_comment
  60. # Multiple ports?
  61. if len (srv['ports']) > 1:
  62. ports = "{ %s }" % ", ".join (map (str, sorted (srv['ports'])))
  63. else:
  64. ports = srv['ports'][0]
  65. rule += "%s dport %s counter accept comment \"%s\"" % (srv['proto'], ports, comment)
  66. rules.append (rule)
  67. return rules