diff --git a/internal/nftables/action.go b/internal/nftables/action.go new file mode 100644 index 0000000..353caab --- /dev/null +++ b/internal/nftables/action.go @@ -0,0 +1,14 @@ +package nftables + +import ( + "nfsense.net/nfsense/internal/definitions/config" + "nfsense.net/nfsense/internal/definitions/firewall" +) + +func GenerateDestinationNatAction(conf config.Config, rule firewall.DestinationNATRule) string { + return "" +} + +func GenerateSourceNatAction(conf config.Config, rule firewall.SourceNATRule) string { + return "" +} diff --git a/internal/nftables/match.go b/internal/nftables/match.go index 3dd05da..31b4c1f 100644 --- a/internal/nftables/match.go +++ b/internal/nftables/match.go @@ -8,58 +8,28 @@ import ( "nfsense.net/nfsense/internal/util" ) -func GenerateMatcher(services map[string]object.Service, addresses map[string]object.Address, match firewall.Match) (string, error) { - return GenerateAddressMatcher(addresses, match) + " " + GenerateServiceMatcher(services, match), nil -} - -func GenerateServiceMatcher(allServices map[string]object.Service, match firewall.Match) string { - serviceList := util.ResolveBaseServices(allServices, match.Services) - - tcpSPorts := []string{} - tcpDPorts := []string{} - udpSPorts := []string{} - udpDPorts := []string{} - icmpCodes := []string{} - - for _, service := range serviceList { - switch service.Type { - case object.TCP: - if service.GetSPort() != "" { - tcpSPorts = append(tcpSPorts, service.GetSPort()) - } - if service.GetDPort() != "" { - tcpDPorts = append(tcpDPorts, service.GetDPort()) - } - case object.UDP: - if service.GetSPort() != "" { - udpSPorts = append(udpSPorts, service.GetSPort()) - } - if service.GetDPort() != "" { - udpDPorts = append(udpDPorts, service.GetDPort()) - } - case object.ICMP: - icmpCodes = append(icmpCodes, fmt.Sprint(service.ICMPCode)) - default: - panic("invalid service type") - } - } - +func GenerateServiceMatcher(service object.Service) string { res := "" - if len(tcpSPorts) != 0 { - res += "tcp sport " + util.ConvertSliceToSetString(tcpSPorts) + " " - } - if len(tcpDPorts) != 0 { - res += "tcp dport " + util.ConvertSliceToSetString(tcpDPorts) + " " - } - if len(udpSPorts) != 0 { - res += "udp sport " + util.ConvertSliceToSetString(udpSPorts) + " " - } - if len(udpDPorts) != 0 { - res += "udp dport " + util.ConvertSliceToSetString(udpDPorts) + " " - } - if len(icmpCodes) != 0 { - res += "icmp codes " + util.ConvertSliceToSetString(icmpCodes) + " " + switch service.Type { + case object.TCP: + if service.GetSPort() != "" { + res = "tcp sport " + service.GetSPort() + } + if service.GetDPort() != "" { + res = res + "tcp dport " + service.GetDPort() + } + case object.UDP: + if service.GetSPort() != "" { + res = "udp sport " + service.GetSPort() + } + if service.GetDPort() != "" { + res = res + "udp dport " + service.GetDPort() + } + case object.ICMP: + res = "icmp codes " + fmt.Sprint(service.ICMPCode) + default: + panic("invalid service type") } return res diff --git a/internal/nftables/template.go b/internal/nftables/template.go index 6488436..e16f6ea 100644 --- a/internal/nftables/template.go +++ b/internal/nftables/template.go @@ -3,6 +3,8 @@ package nftables import ( "embed" "text/template" + + "nfsense.net/nfsense/internal/util" ) //go:embed template @@ -12,8 +14,11 @@ var templates *template.Template func init() { funcMap := template.FuncMap{ - // The name "title" is what the function will be called in the template text. - "matcher": GenerateMatcher, + "addressMatcher": GenerateAddressMatcher, + "serviceMatcher": GenerateServiceMatcher, + "destinationNatAction": GenerateDestinationNatAction, + "sourceNatAction": GenerateSourceNatAction, + "getBaseServices": util.ResolveBaseServices, } var err error diff --git a/internal/nftables/template/addresses.tmpl b/internal/nftables/template/addresses.tmpl deleted file mode 100644 index e69de29..0000000 diff --git a/internal/nftables/template/destination_nat_rules.tmpl b/internal/nftables/template/destination_nat_rules.tmpl deleted file mode 100644 index efec9b0..0000000 --- a/internal/nftables/template/destination_nat_rules.tmpl +++ /dev/null @@ -1,2 +0,0 @@ -{{ range $rule := .Firewall.DestinationNATRules }} - {{ matcher $.Object.Services $.Object.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} \ No newline at end of file diff --git a/internal/nftables/template/forward_rules.tmpl b/internal/nftables/template/forward_rules.tmpl deleted file mode 100644 index 0d7829a..0000000 --- a/internal/nftables/template/forward_rules.tmpl +++ /dev/null @@ -1,2 +0,0 @@ -{{range $rule := .Firewall.ForwardRules}} - {{ matcher $.Object.Services $.Object.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }} {{ $rule.Verdict.String }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} diff --git a/internal/nftables/template/inbound_rules.tmpl b/internal/nftables/template/inbound_rules.tmpl deleted file mode 100644 index 00a667c..0000000 --- a/internal/nftables/template/inbound_rules.tmpl +++ /dev/null @@ -1 +0,0 @@ -counter accept comment "temp inbound allow" \ No newline at end of file diff --git a/internal/nftables/template/nftables.tmpl b/internal/nftables/template/nftables.tmpl index f5b3a17..0d50db9 100644 --- a/internal/nftables/template/nftables.tmpl +++ b/internal/nftables/template/nftables.tmpl @@ -2,12 +2,36 @@ flush ruleset -# Address object ipsets -{{template "addresses.tmpl" .}} - # nfsense nftables inet (ipv4 + ipv6) table table inet nfsense_inet { + # Rule Counters for Forward Rules + {{- range $i, $rule := $.Firewall.ForwardRules }} + {{- if $rule.Counter }} + counter fw_{{ $i }} { + comment "{{ $rule.Name }}" + } + {{- end}} + {{- end}} + + # Rule Counters for Destination NAT Rules + {{- range $i, $rule := $.Firewall.DestinationNATRules }} + {{- if $rule.Counter }} + counter dnat_{{ $i }} { + comment "{{ $rule.Name }}" + } + {{- end}} + {{- end}} + + # Rule Counters for Source NAT Rules + {{- range $i, $rule := $.Firewall.SourceNATRules }} + {{- if $rule.Counter }} + counter snat_{{ $i }} { + comment "{{ $rule.Name }}" + } + {{- end}} + {{- end}} + # Inbound Rules chain inbound { type filter hook input priority 0; policy drop; @@ -15,9 +39,11 @@ table inet nfsense_inet { # Allow traffic from established and related packets, drop invalid ct state vmap { established : accept, related : accept, invalid : drop } - # allow loopback traffic + # Allow loopback traffic iifname lo accept - {{template "inbound_rules.tmpl" .}} + + # temp Allow Inbound traffic + counter accept comment "temp inbound allow" } # Forward Rules @@ -26,19 +52,46 @@ table inet nfsense_inet { # Allow traffic from established and related packets, drop invalid ct state vmap { established : accept, related : accept, invalid : drop } - {{template "forward_rules.tmpl" .}} + + # Generated Forward Rules + {{- range $i, $rule := $.Firewall.ForwardRules }} + {{ addressMatcher $.Object.Addresses $rule.Match }} jump { + {{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }} + {{- range $service := $baseServices }} + {{ serviceMatcher $service }}{{ if $rule.Counter }} counter name fw_{{ $i }}{{ end }} {{ $rule.Verdict.String }} + {{- end}} + } + {{- end}} } # Destination NAT Rules chain prerouting { type nat hook prerouting priority -100; policy accept; - {{template "destination_nat_rules.tmpl" .}} + + # Generated Destination NAT Rules + {{- range $i, $rule := $.Firewall.DestinationNATRules }} + {{ addressMatcher $.Object.Addresses $rule.Match }} jump { + {{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }} + {{- range $service := $baseServices }} + {{ serviceMatcher $service }}{{ if $rule.Counter }} counter name dnat_{{ $i }}{{ end }} {{ destinationNatAction $ $rule }} + {{- end}} + } + {{- end}} } # Source NAT Rules chain postrouting { type nat hook postrouting priority 100; policy accept; - {{template "source_nat_rules.tmpl" .}} + + # Generated Source NAT Rules + {{- range $i, $rule := $.Firewall.SourceNATRules }} + {{ addressMatcher $.Object.Addresses $rule.Match }} jump { + {{- $baseServices := getBaseServices $.Object.Services $rule.Match.Services }} + {{- range $service := $baseServices }} + {{ serviceMatcher $service }}{{ if $rule.Counter }} counter name snat_{{ $i }}{{ end }} {{ sourceNatAction $ $rule }} + {{- end}} + } + {{- end}} } } diff --git a/internal/nftables/template/source_nat_rules.tmpl b/internal/nftables/template/source_nat_rules.tmpl deleted file mode 100644 index a7898e9..0000000 --- a/internal/nftables/template/source_nat_rules.tmpl +++ /dev/null @@ -1,2 +0,0 @@ -{{ range $rule := .Firewall.SourceNATRules }} - {{ matcher $.Object.Services $.Object.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} \ No newline at end of file