mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-10 18:38:22 +00:00
Rework nftables Generation using anonymous chains for multi service matching
This commit is contained in:
parent
e2aad5ec97
commit
9c1114e189
9 changed files with 102 additions and 67 deletions
14
internal/nftables/action.go
Normal file
14
internal/nftables/action.go
Normal file
|
@ -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 ""
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }}
|
|
@ -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 }}
|
|
@ -1 +0,0 @@
|
|||
counter accept comment "temp inbound allow"
|
|
@ -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}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }}
|
Loading…
Add table
Reference in a new issue