mirror of
https://github.com/speatzle/nfsense.git
synced 2025-09-13 15:19:08 +00:00
restructure project
This commit is contained in:
parent
dd2db438f3
commit
2ca35d4461
46 changed files with 158 additions and 84 deletions
36
internal/nftables/config.go
Normal file
36
internal/nftables/config.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package nftables
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"nfsense.net/nfsense/internal/definitions"
|
||||
)
|
||||
|
||||
func GenerateNfTablesFile(conf definitions.Config) (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
err := templates.ExecuteTemplate(buf, "nftables.tmpl", conf)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("executing template: %w", err)
|
||||
}
|
||||
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
|
||||
}
|
110
internal/nftables/match.go
Normal file
110
internal/nftables/match.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package nftables
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"nfsense.net/nfsense/internal/definitions"
|
||||
"nfsense.net/nfsense/internal/util"
|
||||
)
|
||||
|
||||
func GenerateMatcher(services map[string]definitions.Service, addresses map[string]definitions.Address, match definitions.Match) (string, error) {
|
||||
return GenerateAddressMatcher(addresses, match) + " " + GenerateServiceMatcher(services, match), nil
|
||||
}
|
||||
|
||||
func GenerateServiceMatcher(allServices map[string]definitions.Service, match definitions.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 definitions.TCP:
|
||||
if service.GetSPort() != "" {
|
||||
tcpSPorts = append(tcpSPorts, service.GetSPort())
|
||||
}
|
||||
if service.GetDPort() != "" {
|
||||
tcpDPorts = append(tcpDPorts, service.GetDPort())
|
||||
}
|
||||
case definitions.UDP:
|
||||
if service.GetSPort() != "" {
|
||||
udpSPorts = append(udpSPorts, service.GetSPort())
|
||||
}
|
||||
if service.GetDPort() != "" {
|
||||
udpDPorts = append(udpDPorts, service.GetDPort())
|
||||
}
|
||||
case definitions.ICMP:
|
||||
icmpCodes = append(icmpCodes, fmt.Sprint(service.ICMPCode))
|
||||
default:
|
||||
panic("invalid service type")
|
||||
}
|
||||
}
|
||||
|
||||
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) + " "
|
||||
}
|
||||
|
||||
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
|
||||
}
|
24
internal/nftables/template.go
Normal file
24
internal/nftables/template.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package nftables
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
//go:embed template
|
||||
var templateFS embed.FS
|
||||
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,
|
||||
}
|
||||
|
||||
var err error
|
||||
templates, err = template.New("").Funcs(funcMap).ParseFS(templateFS, "template/*.tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
0
internal/nftables/template/addresses.tmpl
Normal file
0
internal/nftables/template/addresses.tmpl
Normal file
2
internal/nftables/template/destination_nat_rules.tmpl
Normal file
2
internal/nftables/template/destination_nat_rules.tmpl
Normal file
|
@ -0,0 +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 }}
|
2
internal/nftables/template/forward_rules.tmpl
Normal file
2
internal/nftables/template/forward_rules.tmpl
Normal file
|
@ -0,0 +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 }}
|
0
internal/nftables/template/inbound_rules.tmpl
Normal file
0
internal/nftables/template/inbound_rules.tmpl
Normal file
44
internal/nftables/template/nftables.tmpl
Normal file
44
internal/nftables/template/nftables.tmpl
Normal file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/sbin/nft -f
|
||||
|
||||
flush ruleset
|
||||
|
||||
# Address object ipsets
|
||||
{{template "addresses.tmpl" .}}
|
||||
|
||||
# nfsense nftables inet (ipv4 + ipv6) table
|
||||
table inet nfsense_inet {
|
||||
|
||||
# Inbound Rules
|
||||
chain inbound {
|
||||
type filter hook input priority 0; policy drop;
|
||||
|
||||
# Allow traffic from established and related packets, drop invalid
|
||||
ct state vmap { established : accept, related : accept, invalid : drop }
|
||||
|
||||
# allow loopback traffic
|
||||
iifname lo accept
|
||||
{{template "inbound_rules.tmpl" .}}
|
||||
}
|
||||
|
||||
# Forward Rules
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy drop;
|
||||
|
||||
# Allow traffic from established and related packets, drop invalid
|
||||
ct state vmap { established : accept, related : accept, invalid : drop }
|
||||
{{template "forward_rules.tmpl" .}}
|
||||
}
|
||||
|
||||
# Destination NAT Rules
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority -100; policy accept;
|
||||
{{template "destination_nat_rules.tmpl" .}}
|
||||
}
|
||||
|
||||
# Source NAT Rules
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100; policy accept;
|
||||
{{template "source_nat_rules.tmpl" .}}
|
||||
}
|
||||
}
|
||||
|
2
internal/nftables/template/source_nat_rules.tmpl
Normal file
2
internal/nftables/template/source_nat_rules.tmpl
Normal file
|
@ -0,0 +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 }}
|
Loading…
Add table
Add a link
Reference in a new issue