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
53
internal/definitions/address.go
Normal file
53
internal/definitions/address.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package definitions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/netip"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
type Address struct {
|
||||
Type AddressType `json:"type" validate:"min=0,max=3"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
Host *netip.Addr `json:"host,omitempty" validate:"excluded_unless=Type 0"`
|
||||
Range *netipx.IPRange `json:"range,omitempty" validate:"excluded_unless=Type 1"`
|
||||
Network *IPNet `json:"network,omitempty" validate:"excluded_unless=Type 2"`
|
||||
Children *[]string `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
type AddressType int
|
||||
|
||||
const (
|
||||
Host AddressType = iota
|
||||
Range
|
||||
Network
|
||||
AddressGroup
|
||||
)
|
||||
|
||||
func (t AddressType) String() string {
|
||||
return [...]string{"host", "range", "network", "group"}[t]
|
||||
}
|
||||
|
||||
func (t *AddressType) FromString(input string) AddressType {
|
||||
return map[string]AddressType{
|
||||
"host": Host,
|
||||
"range": Range,
|
||||
"network": Network,
|
||||
"group": AddressGroup,
|
||||
}[input]
|
||||
}
|
||||
|
||||
func (t AddressType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
func (t *AddressType) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = t.FromString(s)
|
||||
return nil
|
||||
}
|
36
internal/definitions/config.go
Normal file
36
internal/definitions/config.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package definitions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ConfigVersion uint64 `json:"config_version" validate:"required,eq=1"`
|
||||
Firewall Firewall `json:"firewall" validate:"required,dive"`
|
||||
}
|
||||
|
||||
func ValidateConfig(conf *Config) error {
|
||||
val := validator.New()
|
||||
val.RegisterValidation("test", nilIfOtherNil)
|
||||
return val.Struct(conf)
|
||||
}
|
||||
|
||||
func nilIfOtherNil(fl validator.FieldLevel) bool {
|
||||
slog.Info("Start", "field", fl.FieldName(), "param", fl.Param())
|
||||
if !fl.Field().IsNil() {
|
||||
slog.Info("Field is not nil", "field", fl.FieldName())
|
||||
f := fl.Parent().FieldByName(fl.Param())
|
||||
if f.IsZero() {
|
||||
panic(fmt.Errorf("Param %v is not a Valid Field", fl.Param()))
|
||||
}
|
||||
if !f.IsNil() {
|
||||
slog.Info("Fail", "field", fl.FieldName(), "param", fl.Param())
|
||||
return false
|
||||
}
|
||||
}
|
||||
slog.Info("Success", "field", fl.FieldName(), "param", fl.Param())
|
||||
return true
|
||||
}
|
7
internal/definitions/destination_nat.go
Normal file
7
internal/definitions/destination_nat.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package definitions
|
||||
|
||||
type DestinationNATRule struct {
|
||||
Rule
|
||||
Address string `json:"address,omitempty"`
|
||||
Service string `json:"service,omitempty"`
|
||||
}
|
9
internal/definitions/firewall.go
Normal file
9
internal/definitions/firewall.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package definitions
|
||||
|
||||
type Firewall struct {
|
||||
ForwardRules []ForwardRule `json:"forward_rules" validate:"required,dive"`
|
||||
DestinationNATRules []DestinationNATRule `json:"destination_nat_rules" validate:"required,dive"`
|
||||
SourceNATRules []SourceNATRule `json:"source_nat_rules" validate:"required,dive"`
|
||||
Addresses map[string]Address `json:"addresses" validate:"required,dive"`
|
||||
Services map[string]Service `json:"services" validate:"required,dive"`
|
||||
}
|
30
internal/definitions/ipnet.go
Normal file
30
internal/definitions/ipnet.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package definitions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
)
|
||||
|
||||
type IPNet struct {
|
||||
net.IPNet
|
||||
}
|
||||
|
||||
// MarshalJSON for IPNet
|
||||
func (i IPNet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(i.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON for IPNet
|
||||
func (i *IPNet) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, ipnet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.IPNet = *ipnet
|
||||
return nil
|
||||
}
|
8
internal/definitions/match.go
Normal file
8
internal/definitions/match.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package definitions
|
||||
|
||||
type Match struct {
|
||||
TCPDestinationPort uint64 `json:"tcp_destination_port,omitempty"`
|
||||
Services []string `json:"services,omitempty"`
|
||||
SourceAddresses []string `json:"source_addresses,omitempty"`
|
||||
DestinationAddresses []string `json:"destination_addresses,omitempty"`
|
||||
}
|
50
internal/definitions/rule.go
Normal file
50
internal/definitions/rule.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package definitions
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type Rule struct {
|
||||
ID uint64 `json:"id" validate:"required,gt=0"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Match Match `json:"match" validate:"required,dive"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
Counter bool `json:"counter,omitempty"`
|
||||
}
|
||||
|
||||
type ForwardRule struct {
|
||||
Rule
|
||||
Verdict Verdict `json:"verdict" validate:"min=0,max=2"`
|
||||
}
|
||||
|
||||
type Verdict int
|
||||
|
||||
const (
|
||||
Accept Verdict = iota
|
||||
Drop
|
||||
Continue
|
||||
)
|
||||
|
||||
func (t Verdict) String() string {
|
||||
return [...]string{"accept", "drop", "continue"}[t]
|
||||
}
|
||||
|
||||
func (t *Verdict) FromString(input string) Verdict {
|
||||
return map[string]Verdict{
|
||||
"accept": Accept,
|
||||
"drop": Drop,
|
||||
"continue": Continue,
|
||||
}[input]
|
||||
}
|
||||
|
||||
func (t Verdict) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
func (t *Verdict) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = t.FromString(s)
|
||||
return nil
|
||||
}
|
71
internal/definitions/service.go
Normal file
71
internal/definitions/service.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
package definitions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
Type ServiceType `json:"type" validate:"min=0,max=3"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
SPortStart *uint32 `json:"sport_start,omitempty" validate:"excluded_unless=Type 0|excluded_unless=Type 1"`
|
||||
SPortEnd *uint32 `json:"sport_end,omitempty"`
|
||||
DPortStart *uint32 `json:"dport_start,omitempty" validate:"excluded_unless=Type 0|excluded_unless=Type 1"`
|
||||
DPortEnd *uint32 `json:"dport_end,omitempty"`
|
||||
ICMPCode *uint32 `json:"icmp_code,omitempty" validate:"excluded_unless=Type 2"`
|
||||
Children *[]string `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
func (s Service) GetSPort() string {
|
||||
if s.SPortStart == nil || *s.SPortStart == 0 {
|
||||
return ""
|
||||
} else if s.SPortEnd == nil || *s.SPortEnd == 0 {
|
||||
return fmt.Sprintf("%d", *s.SPortStart)
|
||||
}
|
||||
return fmt.Sprintf("%d - %d", *s.SPortStart, *s.SPortEnd)
|
||||
}
|
||||
|
||||
func (s Service) GetDPort() string {
|
||||
if s.DPortStart == nil || *s.DPortStart == 0 {
|
||||
return ""
|
||||
} else if s.DPortEnd == nil || *s.DPortEnd == 0 {
|
||||
return fmt.Sprintf("%d", *s.DPortStart)
|
||||
}
|
||||
return fmt.Sprintf("%d - %d", *s.DPortStart, *s.DPortEnd)
|
||||
}
|
||||
|
||||
type ServiceType int
|
||||
|
||||
const (
|
||||
TCP ServiceType = iota
|
||||
UDP
|
||||
ICMP
|
||||
ServiceGroup
|
||||
)
|
||||
|
||||
func (t ServiceType) String() string {
|
||||
return [...]string{"tcp", "udp", "icmp", "group"}[t]
|
||||
}
|
||||
|
||||
func (t *ServiceType) FromString(input string) ServiceType {
|
||||
return map[string]ServiceType{
|
||||
"tcp": TCP,
|
||||
"udp": UDP,
|
||||
"icmp": ICMP,
|
||||
"group": ServiceGroup,
|
||||
}[input]
|
||||
}
|
||||
|
||||
func (t ServiceType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
func (t *ServiceType) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = t.FromString(s)
|
||||
return nil
|
||||
}
|
42
internal/definitions/source_nat.go
Normal file
42
internal/definitions/source_nat.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package definitions
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type SourceNATRule struct {
|
||||
Rule
|
||||
Type SnatType `json:"type" validate:"min=0,max=1"`
|
||||
Address string `json:"address,omitempty"`
|
||||
Service string `json:"service,omitempty"`
|
||||
}
|
||||
|
||||
type SnatType int
|
||||
|
||||
const (
|
||||
Snat SnatType = iota
|
||||
Masquerade
|
||||
)
|
||||
|
||||
func (t SnatType) String() string {
|
||||
return [...]string{"snat", "masquerade"}[t]
|
||||
}
|
||||
|
||||
func (t *SnatType) FromString(input string) SnatType {
|
||||
return map[string]SnatType{
|
||||
"snat": Snat,
|
||||
"masquerade": Masquerade,
|
||||
}[input]
|
||||
}
|
||||
|
||||
func (t SnatType) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(t.String())
|
||||
}
|
||||
|
||||
func (t *SnatType) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
err := json.Unmarshal(b, &s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = t.FromString(s)
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue