mirror of
https://github.com/qdm12/gluetun.git
synced 2026-08-11 14:52:56 +02:00
moare fixes
This commit is contained in:
@@ -63,7 +63,7 @@ func (f *Firewall) AcceptInputToPort(_ context.Context, intf string, port uint16
|
|||||||
}
|
}
|
||||||
|
|
||||||
table, inputChain, _, _ := setupFilterWithBaseChains(conn)
|
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
|
const tcp, udp uint8 = 6, 17
|
||||||
protocols := []uint8{tcp, udp}
|
protocols := []uint8{tcp, udp}
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,126 @@ func (f *Firewall) AcceptOutputTrafficToVPN(_ context.Context, defaultInterface
|
|||||||
return nil
|
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,
|
func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, intf string,
|
||||||
source, destination netip.AddrPort, remove bool,
|
source, destination netip.AddrPort, remove bool,
|
||||||
) error {
|
) error {
|
||||||
@@ -228,7 +348,7 @@ func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, i
|
|||||||
|
|
||||||
table, _, _, outputChain := setupFilterWithBaseChains(conn)
|
table, _, _, outputChain := setupFilterWithBaseChains(conn)
|
||||||
|
|
||||||
const maxExprsLen = 10 //nolint:mnd
|
const maxExprsLen = 10
|
||||||
exprs := make([]expr.Any, 0, maxExprsLen)
|
exprs := make([]expr.Any, 0, maxExprsLen)
|
||||||
|
|
||||||
if intf != "" && intf != "*" {
|
if intf != "" && intf != "*" {
|
||||||
@@ -301,11 +421,11 @@ func (f *Firewall) AcceptOutputFromIPPortToIPPort(_ context.Context, protocol, i
|
|||||||
var protocolByte uint8
|
var protocolByte uint8
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
protocolByte = 6 //nolint:mnd
|
protocolByte = 6
|
||||||
case "udp":
|
case "udp":
|
||||||
protocolByte = 17 //nolint:mnd
|
protocolByte = 17
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported protocol: %s", protocol) //nolint:err113
|
return fmt.Errorf("unsupported protocol: %s", protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
exprs = append(exprs,
|
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
|
sourcePortBytes := []byte{byte(source.Port() >> 8), byte(source.Port())} //nolint:mnd,gosec
|
||||||
destinationPortBytes := []byte{byte(destination.Port() >> 8), byte(destination.Port())} //nolint:mnd
|
destinationPortBytes := []byte{byte(destination.Port() >> 8), byte(destination.Port())} //nolint:mnd,gosec
|
||||||
exprs = append(exprs,
|
exprs = append(exprs,
|
||||||
&expr.Payload{
|
&expr.Payload{
|
||||||
DestRegister: 1,
|
DestRegister: 1,
|
||||||
Base: expr.PayloadBaseTransportHeader,
|
Base: expr.PayloadBaseTransportHeader,
|
||||||
Offset: 0, //nolint:mnd
|
Offset: 0,
|
||||||
Len: 2, //nolint:mnd
|
Len: 2, //nolint:mnd
|
||||||
},
|
},
|
||||||
&expr.Cmp{
|
&expr.Cmp{
|
||||||
@@ -440,7 +560,7 @@ func (f *Firewall) AcceptOutputFromIPToSubnet(_ context.Context, intf string, as
|
|||||||
DestRegister: 1,
|
DestRegister: 1,
|
||||||
Len: 4, //nolint:mnd
|
Len: 4, //nolint:mnd
|
||||||
Mask: mask,
|
Mask: mask,
|
||||||
Xor: []byte{0, 0, 0, 0}, //nolint:mnd
|
Xor: []byte{0, 0, 0, 0},
|
||||||
},
|
},
|
||||||
&expr.Cmp{
|
&expr.Cmp{
|
||||||
Op: expr.CmpOpEq,
|
Op: expr.CmpOpEq,
|
||||||
@@ -463,7 +583,7 @@ func (f *Firewall) AcceptOutputFromIPToSubnet(_ context.Context, intf string, as
|
|||||||
DestRegister: 1,
|
DestRegister: 1,
|
||||||
Len: 16, //nolint:mnd
|
Len: 16, //nolint:mnd
|
||||||
Mask: mask,
|
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{
|
&expr.Cmp{
|
||||||
Op: expr.CmpOpEq,
|
Op: expr.CmpOpEq,
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ func (f *Firewall) RedirectPort(_ context.Context, intf string,
|
|||||||
Priority: nftables.ChainPriorityNATDest,
|
Priority: nftables.ChainPriorityNATDest,
|
||||||
})
|
})
|
||||||
|
|
||||||
sourcePortBytes := []byte{byte(sourcePort >> 8), byte(sourcePort)} //nolint:mnd
|
sourcePortBytes := []byte{byte(sourcePort >> 8), byte(sourcePort)} //nolint:mnd,gosec
|
||||||
destinationPortBytes := []byte{byte(destinationPort >> 8), byte(destinationPort)} //nolint:mnd
|
destinationPortBytes := []byte{byte(destinationPort >> 8), byte(destinationPort)} //nolint:mnd,gosec
|
||||||
const tcp, udp uint8 = 6, 17 //nolint:mnd
|
const tcp, udp uint8 = 6, 17 //nolint:mnd
|
||||||
protocols := []uint8{tcp, udp}
|
protocols := []uint8{tcp, udp}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (f *Firewall) Version(ctx context.Context) (string, error) {
|
|||||||
outputStr := strings.TrimSpace(string(output))
|
outputStr := strings.TrimSpace(string(output))
|
||||||
words := strings.Fields(outputStr)
|
words := strings.Fields(outputStr)
|
||||||
if len(words) == 0 {
|
if len(words) == 0 {
|
||||||
return "", errors.New(emptyVersionError) //nolint:err113
|
return "", errors.New(emptyVersionError)
|
||||||
}
|
}
|
||||||
return words[0], nil
|
return words[0], nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,16 +94,16 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
|
|||||||
// Match TCP protocol (6)
|
// Match TCP protocol (6)
|
||||||
exprs = append(exprs,
|
exprs = append(exprs,
|
||||||
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
|
&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
|
// 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,
|
exprs = append(exprs,
|
||||||
&expr.Payload{
|
&expr.Payload{
|
||||||
DestRegister: 1,
|
DestRegister: 1,
|
||||||
Base: expr.PayloadBaseTransportHeader,
|
Base: expr.PayloadBaseTransportHeader,
|
||||||
Offset: 0, //nolint:mnd
|
Offset: 0,
|
||||||
Len: 2, //nolint:mnd
|
Len: 2, //nolint:mnd
|
||||||
},
|
},
|
||||||
&expr.Cmp{
|
&expr.Cmp{
|
||||||
@@ -114,7 +114,7 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Match destination port
|
// 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,
|
exprs = append(exprs,
|
||||||
&expr.Payload{
|
&expr.Payload{
|
||||||
DestRegister: 1,
|
DestRegister: 1,
|
||||||
@@ -143,12 +143,12 @@ func (f *Firewall) TempDropOutputTCPRST(_ context.Context,
|
|||||||
&expr.Cmp{
|
&expr.Cmp{
|
||||||
Op: expr.CmpOpEq,
|
Op: expr.CmpOpEq,
|
||||||
Register: 1,
|
Register: 1,
|
||||||
Data: []byte{0x04}, //nolint:mnd
|
Data: []byte{0x04},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// Exclude packets with the mark using mark != excludeMark
|
// 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
|
byte(excludeMark), byte(excludeMark >> 8), byte(excludeMark >> 16), byte(excludeMark >> 24), //nolint:mnd
|
||||||
}
|
}
|
||||||
exprs = append(exprs,
|
exprs = append(exprs,
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ func Test_PathMTUDiscover(t *testing.T) {
|
|||||||
logger := log.New(log.SetLevel(log.LevelDebug))
|
logger := log.New(log.SetLevel(log.LevelDebug))
|
||||||
|
|
||||||
cmder := command.New()
|
cmder := command.New()
|
||||||
fw, err := firewall.NewConfig(t.Context(), logger, logger, cmder, nil, nil)
|
const implementation = "auto"
|
||||||
|
fw, err := firewall.NewConfig(t.Context(), implementation, logger, logger, cmder, nil, nil)
|
||||||
if errors.Is(err, iptables.ErrNotSupported) {
|
if errors.Is(err, iptables.ErrNotSupported) {
|
||||||
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ func getFirewall(t *testing.T) *firewall.Config {
|
|||||||
noopLogger := &noopLogger{}
|
noopLogger := &noopLogger{}
|
||||||
cmder := command.New()
|
cmder := command.New()
|
||||||
var err error
|
var err error
|
||||||
testFirewall, err = firewall.NewConfig(t.Context(), noopLogger, noopLogger, cmder, nil, nil)
|
const implementation = "auto"
|
||||||
|
testFirewall, err = firewall.NewConfig(t.Context(), implementation, noopLogger, noopLogger, cmder, nil, nil)
|
||||||
if errors.Is(err, iptables.ErrNotSupported) {
|
if errors.Is(err, iptables.ErrNotSupported) {
|
||||||
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ func Test_PathMTUDiscover(t *testing.T) {
|
|||||||
logger := log.New(log.SetLevel(log.LevelDebug))
|
logger := log.New(log.SetLevel(log.LevelDebug))
|
||||||
|
|
||||||
cmder := command.New()
|
cmder := command.New()
|
||||||
fw, err := firewall.NewConfig(t.Context(), logger, logger, cmder, nil, nil)
|
const implementation = "auto"
|
||||||
|
fw, err := firewall.NewConfig(t.Context(), implementation, logger, logger, cmder, nil, nil)
|
||||||
if errors.Is(err, iptables.ErrNotSupported) {
|
if errors.Is(err, iptables.ErrNotSupported) {
|
||||||
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
t.Skip("iptables not installed, skipping TCP PMTUD tests")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user