mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-07 17:18:21 +00:00
initial nftables config generation test
This commit is contained in:
parent
ba99844ae4
commit
b279746017
17 changed files with 215 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
config.json
|
||||
nftables.conf
|
||||
go.work
|
||||
bin/*
|
27
api/config.go
Normal file
27
api/config.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.con/speatzle/nfsense/pkg/definitions"
|
||||
)
|
||||
|
||||
func LoadConfiguration(file string) (*definitions.Config, error) {
|
||||
var config definitions.Config
|
||||
configFile, err := os.Open(file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening Config File %w", err)
|
||||
}
|
||||
defer configFile.Close()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
jsonParser := json.NewDecoder(configFile)
|
||||
err = jsonParser.Decode(&config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding Config File %w", err)
|
||||
}
|
||||
return &config, nil
|
||||
}
|
29
api/main.go
Normal file
29
api/main.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.con/speatzle/nfsense/pkg/nftables"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
slog.Info("Starting...")
|
||||
conf, err := LoadConfiguration("config.json")
|
||||
if err != nil {
|
||||
slog.Error("Loading Config", err)
|
||||
return
|
||||
}
|
||||
slog.Info("Config Loaded", "config", conf)
|
||||
|
||||
fileContent, err := nftables.GenerateNfTablesFile(*conf)
|
||||
if err != nil {
|
||||
slog.Error("Generating nftables file", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = nftables.ApplyNfTablesFile(fileContent)
|
||||
if err != nil {
|
||||
slog.Error("Applying nftables", err)
|
||||
return
|
||||
}
|
||||
slog.Info("Wrote nftables File!")
|
||||
}
|
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
|||
module github.con/speatzle/nfsense
|
||||
|
||||
go 1.19
|
||||
|
||||
require golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
|||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
|
||||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
6
pkg/definitions/config.go
Normal file
6
pkg/definitions/config.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package definitions
|
||||
|
||||
type Config struct {
|
||||
ConfigVersion int64 `json:"config_version"`
|
||||
Netfilter Netfilter `json:"netfilter"`
|
||||
}
|
7
pkg/definitions/netfilter.go
Normal file
7
pkg/definitions/netfilter.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package definitions
|
||||
|
||||
type Netfilter struct {
|
||||
ForwardRules []ForwardRule `json:"forward_rules"`
|
||||
DestinationNATRules []DestinationNATRule `json:"destination_nat_rules"`
|
||||
SourceNATRules []SourceNATRule `json:"source_nat_rules"`
|
||||
}
|
23
pkg/definitions/rules.go
Normal file
23
pkg/definitions/rules.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package definitions
|
||||
|
||||
type Rule struct {
|
||||
Match RuleMatch `json:"match"`
|
||||
Comment string `json:"comment"`
|
||||
Counter bool `json:"counter"`
|
||||
}
|
||||
|
||||
type RuleMatch struct {
|
||||
TCPDestinationPort uint64 `json:"tcp_destination_port"`
|
||||
}
|
||||
|
||||
type ForwardRule struct {
|
||||
Rule
|
||||
}
|
||||
|
||||
type DestinationNATRule struct {
|
||||
Rule
|
||||
}
|
||||
|
||||
type SourceNATRule struct {
|
||||
Rule
|
||||
}
|
36
pkg/nftables/config.go
Normal file
36
pkg/nftables/config.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package nftables
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.con/speatzle/nfsense/pkg/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
|
||||
}
|
18
pkg/nftables/template.go
Normal file
18
pkg/nftables/template.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package nftables
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
//go:embed template
|
||||
var templateFS embed.FS
|
||||
var templates *template.Template
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
templates, err = template.ParseFS(templateFS, "template/*.tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
0
pkg/nftables/template/addresses.tmpl
Normal file
0
pkg/nftables/template/addresses.tmpl
Normal file
3
pkg/nftables/template/destination_nat_rules.tmpl
Normal file
3
pkg/nftables/template/destination_nat_rules.tmpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{range $rule := .Netfilter.DestinationNATRules}}
|
||||
{{template "rule_match.tmpl" .Match}} {{ if $rule.Counter }} counter {{ end }} {{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}" {{ end }}
|
||||
{{end}}
|
3
pkg/nftables/template/forward_rules.tmpl
Normal file
3
pkg/nftables/template/forward_rules.tmpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{range $rule := .Netfilter.ForwardRules}}
|
||||
{{template "rule_match.tmpl" .Match}} {{ if $rule.Counter }} counter {{ end }} {{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}" {{ end }}
|
||||
{{end}}
|
0
pkg/nftables/template/inbound_rules.tmpl
Normal file
0
pkg/nftables/template/inbound_rules.tmpl
Normal file
48
pkg/nftables/template/nftables.tmpl
Normal file
48
pkg/nftables/template/nftables.tmpl
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/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, anything else jump to chain for further evaluation
|
||||
iifname vmap { lo : accept, $DEV_WORLD : jump inbound_world, $DEV_PRIVATE : jump inbound_private }
|
||||
|
||||
{{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" .}}
|
||||
}
|
||||
}
|
||||
|
1
pkg/nftables/template/rule_match.tmpl
Normal file
1
pkg/nftables/template/rule_match.tmpl
Normal file
|
@ -0,0 +1 @@
|
|||
tcp dport {{ .TCPDestinationPort }}
|
3
pkg/nftables/template/source_nat_rules.tmpl
Normal file
3
pkg/nftables/template/source_nat_rules.tmpl
Normal file
|
@ -0,0 +1,3 @@
|
|||
{{range $rule := .Netfilter.SourceNATRules}}
|
||||
{{template "rule_match.tmpl" .Match}} {{ if $rule.Counter }} counter {{ end }} {{ if ne $rule.Comment "" }} comment "{{ $rule.Comment }}" {{ end }}
|
||||
{{end}}
|
Loading…
Add table
Reference in a new issue