diff --git a/internal/nftables/apply.go b/internal/nftables/apply.go new file mode 100644 index 0000000..c75da3a --- /dev/null +++ b/internal/nftables/apply.go @@ -0,0 +1,35 @@ +package nftables + +import ( + "context" + "fmt" + + systemctl "github.com/coreos/go-systemd/v22/dbus" + "nfsense.net/nfsense/internal/definitions/config" + "nfsense.net/nfsense/internal/util" +) + +const nftablesFile = "/etc/nftables/nfsense.conf" + +func ApplyNFTablesConfiguration(currentConfig config.Config, pendingConfig config.Config) error { + nftablesConf, err := GenerateNfTablesConfig(pendingConfig) + if err != nil { + return fmt.Errorf("Generating nftables Configuration: %w", err) + } + + err = util.OverwriteFile(nftablesFile, nftablesConf) + if err != nil { + return fmt.Errorf("Writing nftables Configuration: %w", err) + } + + conn, err := systemctl.NewSystemConnectionContext(context.Background()) + if err != nil { + return fmt.Errorf("Opening Dbus Connection: %w", err) + } + + _, err = conn.ReloadOrRestartUnitContext(context.Background(), "nftables.service", "replace", nil) + if err != nil { + return fmt.Errorf("restarting unbound.service: %w", err) + } + return nil +} diff --git a/internal/nftables/config.go b/internal/nftables/config.go index 4787c2d..c538d42 100644 --- a/internal/nftables/config.go +++ b/internal/nftables/config.go @@ -3,12 +3,11 @@ package nftables import ( "bytes" "fmt" - "os" "nfsense.net/nfsense/internal/definitions/config" ) -func GenerateNfTablesFile(conf config.Config) (string, error) { +func GenerateNfTablesConfig(conf config.Config) (string, error) { buf := new(bytes.Buffer) err := templates.ExecuteTemplate(buf, "nftables.tmpl", conf) if err != nil { @@ -16,21 +15,3 @@ func GenerateNfTablesFile(conf config.Config) (string, error) { } return buf.String(), nil } - -func ApplyNfTablesFile(content string) error { - f, err := os.Create("nftables.conf") - if err != nil { - return fmt.Errorf("creating File: %w", err) - } - - _, err = f.WriteString(content + "\n") - if err != nil { - return fmt.Errorf("writing File: %w", err) - } - - err = f.Sync() - if err != nil { - return fmt.Errorf("syncing File: %w", err) - } - return nil -} diff --git a/internal/nftables/match.go b/internal/nftables/match.go index 6fb6d28..3dd05da 100644 --- a/internal/nftables/match.go +++ b/internal/nftables/match.go @@ -3,15 +3,16 @@ package nftables import ( "fmt" - "nfsense.net/nfsense/internal/definitions" + "nfsense.net/nfsense/internal/definitions/firewall" + "nfsense.net/nfsense/internal/definitions/object" "nfsense.net/nfsense/internal/util" ) -func GenerateMatcher(services map[string]definitions.Service, addresses map[string]definitions.Address, match definitions.Match) (string, error) { +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]definitions.Service, match definitions.Match) string { +func GenerateServiceMatcher(allServices map[string]object.Service, match firewall.Match) string { serviceList := util.ResolveBaseServices(allServices, match.Services) tcpSPorts := []string{} @@ -22,21 +23,21 @@ func GenerateServiceMatcher(allServices map[string]definitions.Service, match de for _, service := range serviceList { switch service.Type { - case definitions.TCP: + case object.TCP: if service.GetSPort() != "" { tcpSPorts = append(tcpSPorts, service.GetSPort()) } if service.GetDPort() != "" { tcpDPorts = append(tcpDPorts, service.GetDPort()) } - case definitions.UDP: + case object.UDP: if service.GetSPort() != "" { udpSPorts = append(udpSPorts, service.GetSPort()) } if service.GetDPort() != "" { udpDPorts = append(udpDPorts, service.GetDPort()) } - case definitions.ICMP: + case object.ICMP: icmpCodes = append(icmpCodes, fmt.Sprint(service.ICMPCode)) default: panic("invalid service type") @@ -64,7 +65,7 @@ func GenerateServiceMatcher(allServices map[string]definitions.Service, match de return res } -func GenerateAddressMatcher(allAddresses map[string]definitions.Address, match definitions.Match) string { +func GenerateAddressMatcher(allAddresses map[string]object.Address, match firewall.Match) string { sourceAddressList := util.ResolveBaseAddresses(allAddresses, match.SourceAddresses) destinationAddressList := util.ResolveBaseAddresses(allAddresses, match.DestinationAddresses) @@ -73,11 +74,11 @@ func GenerateAddressMatcher(allAddresses map[string]definitions.Address, match d for _, address := range sourceAddressList { switch address.Type { - case definitions.Host: + case object.Host: sourceAddresses = append(sourceAddresses, address.Host.String()) - case definitions.Range: + case object.Range: sourceAddresses = append(sourceAddresses, address.Range.String()) - case definitions.NetworkAddress: + case object.NetworkAddress: sourceAddresses = append(sourceAddresses, address.NetworkAddress.String()) default: panic("invalid address type") @@ -86,11 +87,11 @@ func GenerateAddressMatcher(allAddresses map[string]definitions.Address, match d for _, address := range destinationAddressList { switch address.Type { - case definitions.Host: + case object.Host: destinationAddresses = append(destinationAddresses, address.Host.String()) - case definitions.Range: + case object.Range: destinationAddresses = append(destinationAddresses, address.Range.String()) - case definitions.NetworkAddress: + case object.NetworkAddress: destinationAddresses = append(destinationAddresses, address.NetworkAddress.String()) default: panic("invalid address type") diff --git a/internal/nftables/template/destination_nat_rules.tmpl b/internal/nftables/template/destination_nat_rules.tmpl index 72a6ba7..efec9b0 100644 --- a/internal/nftables/template/destination_nat_rules.tmpl +++ b/internal/nftables/template/destination_nat_rules.tmpl @@ -1,2 +1,2 @@ {{ range $rule := .Firewall.DestinationNATRules }} - {{ matcher $.Firewall.Services $.Firewall.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} \ No newline at end of file + {{ 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 index 31e56ee..0d7829a 100644 --- a/internal/nftables/template/forward_rules.tmpl +++ b/internal/nftables/template/forward_rules.tmpl @@ -1,2 +1,2 @@ {{range $rule := .Firewall.ForwardRules}} - {{ matcher $.Firewall.Services $.Firewall.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }} {{ $rule.Verdict.String }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} + {{ 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/source_nat_rules.tmpl b/internal/nftables/template/source_nat_rules.tmpl index d0da2fb..a7898e9 100644 --- a/internal/nftables/template/source_nat_rules.tmpl +++ b/internal/nftables/template/source_nat_rules.tmpl @@ -1,2 +1,2 @@ {{ range $rule := .Firewall.SourceNATRules }} - {{ matcher $.Firewall.Services $.Firewall.Addresses $rule.Match }}{{ if $rule.Counter }} counter{{ end }}{{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}"{{ end }}{{ end }} \ No newline at end of file + {{ 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/main.go b/main.go index 8f607b6..5302532 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( dhcp "nfsense.net/nfsense/internal/dhcp_server" "nfsense.net/nfsense/internal/jsonrpc" "nfsense.net/nfsense/internal/networkd" + "nfsense.net/nfsense/internal/nftables" "nfsense.net/nfsense/internal/server" "nfsense.net/nfsense/internal/unbound" ) @@ -108,4 +109,5 @@ func RegisterApplyFunctions(configManager *config.ConfigManager) { configManager.RegisterApplyFunction(dhcp.ApplyDHCPServerConfiguration) configManager.RegisterApplyFunction(chrony.ApplyNTPConfiguration) configManager.RegisterApplyFunction(unbound.ApplyDNSServerConfiguration) + configManager.RegisterApplyFunction(nftables.ApplyNFTablesConfiguration) }