moare fixes

This commit is contained in:
Quentin McGaw
2026-08-06 20:19:10 +00:00
parent a10285d874
commit c463c56f86
8 changed files with 145 additions and 22 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ func (f *Firewall) AcceptInputToPort(_ context.Context, intf string, port uint16
}
table, inputChain, _, _ := setupFilterWithBaseChains(conn)
portBytes := []byte{byte(port >> 8), byte(port)} //nolint:mnd
portBytes := []byte{byte(port >> 8), byte(port)} //nolint:mnd,gosec // network byte order
const tcp, udp uint8 = 6, 17
protocols := []uint8{tcp, udp}
+129 -9
View File
@@ -215,6 +215,126 @@ func (f *Firewall) AcceptOutputTrafficToVPN(_ context.Context, defaultInterface
return nil
}
func (f *Firewall) AcceptOutput(_ context.Context, protocol, intf string,
ip netip.Addr, port uint16, remove bool,
) error {
f.mutex.Lock()
defer f.mutex.Unlock()
conn, err := nftables.New()
if err != nil {
return fmt.Errorf("creating nftables connection: %w", err)
}
table, _, _, outputChain := setupFilterWithBaseChains(conn)
const maxExprsLen = 7
exprs := make([]expr.Any, 0, maxExprsLen)
if intf != "" && intf != "*" {
exprs = append(exprs,
&expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1},
&expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte(intf + "\x00")},
)
}
if ip.Is4() {
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseNetworkHeader,
Offset: 16, //nolint:mnd
Len: 4, //nolint:mnd
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ip.AsSlice(),
},
)
} else {
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseNetworkHeader,
Offset: 24, //nolint:mnd
Len: 16, //nolint:mnd
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ip.AsSlice(),
},
)
}
var protocolByte uint8
switch protocol {
case "tcp":
protocolByte = 6
case "udp":
protocolByte = 17
default:
return fmt.Errorf("unsupported protocol: %s", protocol)
}
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 3, //nolint:mnd
Len: 1,
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{protocolByte},
},
)
portBytes := []byte{byte(port >> 8), byte(port)} //nolint:mnd,gosec
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 2, //nolint:mnd
Len: 2, //nolint:mnd
},
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: portBytes,
},
&expr.Verdict{Kind: expr.VerdictAccept},
)
rule := &nftables.Rule{
Table: table,
Chain: outputChain,
Exprs: exprs,
}
if !remove {
conn.AddRule(rule)
f.rules = append(f.rules, rule)
} else {
err = f.deleteRule(conn, rule)
if err != nil {
return fmt.Errorf("deleting rule: %w", err)
}
}
err = conn.Flush()
if err != nil {
if !remove {
f.rules = f.rules[:len(f.rules)-1]
}
return fmt.Errorf("flushing: %w", err)
}
return nil
}
func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, intf string,
source, destination netip.AddrPort, remove bool,
) error {
@@ -228,7 +348,7 @@ func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, i
table, _, _, outputChain := setupFilterWithBaseChains(conn)
const maxExprsLen = 10 //nolint:mnd
const maxExprsLen = 10
exprs := make([]expr.Any, 0, maxExprsLen)
if intf != "" && intf != "*" {
@@ -301,11 +421,11 @@ func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, i
var protocolByte uint8
switch protocol {
case "tcp":
protocolByte = 6 //nolint:mnd
protocolByte = 6
case "udp":
protocolByte = 17 //nolint:mnd
protocolByte = 17
default:
return fmt.Errorf("unsupported protocol: %s", protocol) //nolint:err113
return fmt.Errorf("unsupported protocol: %s", protocol)
}
exprs = append(exprs,
@@ -317,13 +437,13 @@ func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, i
},
)
sourcePortBytes := []byte{byte(source.Port() >> 8), byte(source.Port())} //nolint:mnd
destinationPortBytes := []byte{byte(destination.Port() >> 8), byte(destination.Port())} //nolint:mnd
sourcePortBytes := []byte{byte(source.Port() >> 8), byte(source.Port())} //nolint:mnd,gosec
destinationPortBytes := []byte{byte(destination.Port() >> 8), byte(destination.Port())} //nolint:mnd,gosec
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 0, //nolint:mnd
Offset: 0,
Len: 2, //nolint:mnd
},
&expr.Cmp{
@@ -440,7 +560,7 @@ func (f *Firewall) AcceptOutputFromIPToSubnet(_ context.Context, intf string, as
DestRegister: 1,
Len: 4, //nolint:mnd
Mask: mask,
Xor: []byte{0, 0, 0, 0}, //nolint:mnd
Xor: []byte{0, 0, 0, 0},
},
&expr.Cmp{
Op: expr.CmpOpEq,
@@ -463,7 +583,7 @@ func (f *Firewall) AcceptOutputFromIPToSubnet(_ context.Context, intf string, as
DestRegister: 1,
Len: 16, //nolint:mnd
Mask: mask,
Xor: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, //nolint:mnd
Xor: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
},
&expr.Cmp{
Op: expr.CmpOpEq,
+2 -2
View File
@@ -42,8 +42,8 @@ func (f *Firewall) RedirectPort(_ context.Context, intf string,
Priority: nftables.ChainPriorityNATDest,
})
sourcePortBytes := []byte{byte(sourcePort >> 8), byte(sourcePort)} //nolint:mnd
destinationPortBytes := []byte{byte(destinationPort >> 8), byte(destinationPort)} //nolint:mnd
sourcePortBytes := []byte{byte(sourcePort >> 8), byte(sourcePort)} //nolint:mnd,gosec
destinationPortBytes := []byte{byte(destinationPort >> 8), byte(destinationPort)} //nolint:mnd,gosec
const tcp, udp uint8 = 6, 17 //nolint:mnd
protocols := []uint8{tcp, udp}
+1 -1
View File
@@ -33,7 +33,7 @@ func (f *Firewall) Version(ctx context.Context) (string, error) {
outputStr := strings.TrimSpace(string(output))
words := strings.Fields(outputStr)
if len(words) == 0 {
return "", errors.New(emptyVersionError) //nolint:err113
return "", errors.New(emptyVersionError)
}
return words[0], nil
}
+6 -6
View File
@@ -94,16 +94,16 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
// Match TCP protocol (6)
exprs = append(exprs,
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
&expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte{6}}, //nolint:mnd
&expr.Cmp{Op: expr.CmpOpEq, Register: 1, Data: []byte{6}},
)
// Match source port
srcPortBytes := []byte{byte(src.Port() >> 8), byte(src.Port())} //nolint:mnd
srcPortBytes := []byte{byte(src.Port() >> 8), byte(src.Port())} //nolint:mnd,gosec // network byte order
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 0, //nolint:mnd
Offset: 0,
Len: 2, //nolint:mnd
},
&expr.Cmp{
@@ -114,7 +114,7 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
)
// Match destination port
dstPortBytes := []byte{byte(dst.Port() >> 8), byte(dst.Port())} //nolint:mnd
dstPortBytes := []byte{byte(dst.Port() >> 8), byte(dst.Port())} //nolint:mnd,gosec // network byte order
exprs = append(exprs,
&expr.Payload{
DestRegister: 1,
@@ -143,12 +143,12 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{0x04}, //nolint:mnd
Data: []byte{0x04},
},
)
// Exclude packets with the mark using mark != excludeMark
markData := []byte{
markData := []byte{ //nolint:gosec // mark is int (32-bit), byte conversions are intentional
byte(excludeMark), byte(excludeMark >> 8), byte(excludeMark >> 16), byte(excludeMark >> 24), //nolint:mnd
}
exprs = append(exprs,