diff --git a/pkg/definitions/address.go b/pkg/definitions/address.go index 77f4742..27f947a 100644 --- a/pkg/definitions/address.go +++ b/pkg/definitions/address.go @@ -2,6 +2,7 @@ package definitions import ( "encoding/json" + "net" "net/netip" "go4.org/netipx" @@ -12,6 +13,7 @@ type Address struct { Comment string `json:"comment,omitempty"` Host *netip.Addr `json:"host,omitempty"` Range *netipx.IPRange `json:"range,omitempty"` + Network *net.IPNet `json:"network,omitempty"` Children *[]string `json:"children,omitempty"` } diff --git a/pkg/definitions/match.go b/pkg/definitions/match.go index 1aad192..75efbc7 100644 --- a/pkg/definitions/match.go +++ b/pkg/definitions/match.go @@ -1,6 +1,8 @@ package definitions type Match struct { - TCPDestinationPort uint64 `json:"tcp_destination_port,omitempty"` - Services []string `json:"services,omitempty"` + TCPDestinationPort uint64 `json:"tcp_destination_port,omitempty"` + Services []string `json:"services,omitempty"` + SourceAddresses []string `json:"source_addresses,omitempty"` + DestinationAddresses []string `json:"destination_addresses,omitempty"` } diff --git a/pkg/nftables/match.go b/pkg/nftables/match.go index 15f50fc..cbf5258 100644 --- a/pkg/nftables/match.go +++ b/pkg/nftables/match.go @@ -63,3 +63,48 @@ func GenerateServiceMatcher(allServices map[string]definitions.Service, match de return res } + +func GenerateAddressMatcher(allAddresses map[string]definitions.Address, match definitions.Match) string { + sourceAddressList := util.ResolveBaseAddresses(allAddresses, match.SourceAddresses) + destinationAddressList := util.ResolveBaseAddresses(allAddresses, match.DestinationAddresses) + + sourceAddresses := []string{} + destinationAddresses := []string{} + + for _, address := range sourceAddressList { + switch address.Type { + case definitions.Host: + sourceAddresses = append(sourceAddresses, address.Host.String()) + case definitions.Range: + sourceAddresses = append(sourceAddresses, address.Range.String()) + case definitions.Network: + sourceAddresses = append(sourceAddresses, address.Network.String()) + default: + panic("invalid address type") + } + } + + for _, address := range destinationAddressList { + switch address.Type { + case definitions.Host: + destinationAddresses = append(destinationAddresses, address.Host.String()) + case definitions.Range: + destinationAddresses = append(destinationAddresses, address.Range.String()) + case definitions.Network: + destinationAddresses = append(destinationAddresses, address.Network.String()) + default: + panic("invalid address type") + } + } + + res := "" + + if len(sourceAddresses) != 0 { + res += "ip saddr " + util.ConvertSliceToSetString(sourceAddresses) + " " + } + if len(destinationAddresses) != 0 { + res += "ip daddr " + util.ConvertSliceToSetString(destinationAddresses) + " " + } + + return res +} diff --git a/pkg/util/address.go b/pkg/util/address.go new file mode 100644 index 0000000..1c1f70e --- /dev/null +++ b/pkg/util/address.go @@ -0,0 +1,35 @@ +package util + +import "github.con/speatzle/nfsense/pkg/definitions" + +// ResolveBaseAddresses Resolves all groups to their base Addresses +func ResolveBaseAddresses(allAddresses map[string]definitions.Address, addressNames []string) []definitions.Address { + baseAddresses := []definitions.Address{} + + for _, addressName := range addressNames { + address := allAddresses[addressName] + + if address.Type == definitions.AddressGroup { + baseAddresses = append(baseAddresses, resolveAddressChildren(allAddresses, address)...) + } else { + baseAddresses = append(baseAddresses, address) + } + + } + + return baseAddresses +} + +func resolveAddressChildren(allAddresses map[string]definitions.Address, a definitions.Address) []definitions.Address { + addressList := []definitions.Address{} + for _, addressName := range *a.Children { + address := allAddresses[addressName] + + if address.Type == definitions.AddressGroup { + addressList = append(addressList, resolveAddressChildren(allAddresses, address)...) + } else { + addressList = append(addressList, address) + } + } + return addressList +} diff --git a/pkg/util/service.go b/pkg/util/service.go index 8b5df46..48a8f29 100644 --- a/pkg/util/service.go +++ b/pkg/util/service.go @@ -10,7 +10,7 @@ func ResolveBaseServices(allServices map[string]definitions.Service, serviceName service := allServices[serviceName] if service.Type == definitions.ServiceGroup { - baseServices = append(baseServices, resolveChildren(allServices, service)...) + baseServices = append(baseServices, resolveServiceChildren(allServices, service)...) } else { baseServices = append(baseServices, service) } @@ -20,36 +20,16 @@ func ResolveBaseServices(allServices map[string]definitions.Service, serviceName return baseServices } -func resolveChildren(allServices map[string]definitions.Service, s definitions.Service) []definitions.Service { +func resolveServiceChildren(allServices map[string]definitions.Service, s definitions.Service) []definitions.Service { serviceList := []definitions.Service{} for _, serviceName := range *s.Children { service := allServices[serviceName] if service.Type == definitions.ServiceGroup { - serviceList = append(serviceList, resolveChildren(allServices, service)...) + serviceList = append(serviceList, resolveServiceChildren(allServices, service)...) } else { serviceList = append(serviceList, service) } } return serviceList } - -func ConvertSliceToSetString(slice []string) string { - if len(slice) == 0 { - return "" - } else if len(slice) == 1 { - return slice[0] - } - - res := "{ " - - for i := range slice { - res += " " + slice[i] - if i < len(slice)-1 { - res += "," - } - } - - res += " }" - return res -} diff --git a/pkg/util/set.go b/pkg/util/set.go new file mode 100644 index 0000000..6e36e7a --- /dev/null +++ b/pkg/util/set.go @@ -0,0 +1,21 @@ +package util + +func ConvertSliceToSetString(slice []string) string { + if len(slice) == 0 { + return "" + } else if len(slice) == 1 { + return slice[0] + } + + res := "{ " + + for i := range slice { + res += " " + slice[i] + if i < len(slice)-1 { + res += "," + } + } + + res += " }" + return res +}