137 lines
3.4 KiB
Go
137 lines
3.4 KiB
Go
package firewall
|
|
|
|
import (
|
|
"net/netip"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_parseIptablesInstruction(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := map[string]struct {
|
|
s string
|
|
instruction iptablesInstruction
|
|
errWrapped error
|
|
errMessage string
|
|
}{
|
|
"no_instruction": {
|
|
errWrapped: ErrIptablesCommandMalformed,
|
|
errMessage: "iptables command is malformed: empty instruction",
|
|
},
|
|
"uneven_fields": {
|
|
s: "-A",
|
|
errWrapped: ErrIptablesCommandMalformed,
|
|
errMessage: "iptables command is malformed: fields count 1 is not even: \"-A\"",
|
|
},
|
|
"unknown_key": {
|
|
s: "-x something",
|
|
errWrapped: ErrIptablesCommandMalformed,
|
|
errMessage: "parsing \"-x something\": iptables command is malformed: unknown key \"-x\"",
|
|
},
|
|
"one_pair": {
|
|
s: "-A INPUT",
|
|
instruction: iptablesInstruction{
|
|
table: "filter",
|
|
chain: "INPUT",
|
|
append: true,
|
|
},
|
|
},
|
|
"instruction_A": {
|
|
s: "-A INPUT -i tun0 -p tcp -m tcp -s 1.2.3.4/32 -d 5.6.7.8 --dport 10000 -j ACCEPT",
|
|
instruction: iptablesInstruction{
|
|
table: "filter",
|
|
chain: "INPUT",
|
|
append: true,
|
|
inputInterface: "tun0",
|
|
protocol: "tcp",
|
|
source: netip.MustParsePrefix("1.2.3.4/32"),
|
|
destination: netip.MustParsePrefix("5.6.7.8/32"),
|
|
destinationPort: 10000,
|
|
target: "ACCEPT",
|
|
},
|
|
},
|
|
"nat_redirection": {
|
|
s: "-t nat --delete PREROUTING -i tun0 -p tcp --dport 43716 -j REDIRECT --to-ports 5678",
|
|
instruction: iptablesInstruction{
|
|
table: "nat",
|
|
chain: "PREROUTING",
|
|
append: false,
|
|
inputInterface: "tun0",
|
|
protocol: "tcp",
|
|
destinationPort: 43716,
|
|
target: "REDIRECT",
|
|
toPorts: []uint16{5678},
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, testCase := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
rule, err := parseIptablesInstruction(testCase.s)
|
|
|
|
assert.Equal(t, testCase.instruction, rule)
|
|
assert.ErrorIs(t, err, testCase.errWrapped)
|
|
if testCase.errWrapped != nil {
|
|
assert.EqualError(t, err, testCase.errMessage)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_parseIPPrefix(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := map[string]struct {
|
|
value string
|
|
prefix netip.Prefix
|
|
errMessage string
|
|
}{
|
|
"empty": {
|
|
errMessage: `parsing IP address: ParseAddr(""): unable to parse IP`,
|
|
},
|
|
"invalid": {
|
|
value: "invalid",
|
|
errMessage: `parsing IP address: ParseAddr("invalid"): unable to parse IP`,
|
|
},
|
|
"valid_ipv4_with_bits": {
|
|
value: "10.0.0.0/16",
|
|
prefix: netip.PrefixFrom(netip.AddrFrom4([4]byte{10, 0, 0, 0}), 16),
|
|
},
|
|
"valid_ipv4_without_bits": {
|
|
value: "10.0.0.4",
|
|
prefix: netip.PrefixFrom(netip.AddrFrom4([4]byte{10, 0, 0, 4}), 32),
|
|
},
|
|
"valid_ipv6_with_bits": {
|
|
value: "2001:db8::/32",
|
|
prefix: netip.PrefixFrom(
|
|
netip.AddrFrom16([16]byte{0x20, 0x01, 0x0d, 0xb8}),
|
|
32),
|
|
},
|
|
"valid_ipv6_without_bits": {
|
|
value: "2001:db8::",
|
|
prefix: netip.PrefixFrom(
|
|
netip.AddrFrom16([16]byte{0x20, 0x01, 0x0d, 0xb8}),
|
|
128),
|
|
},
|
|
}
|
|
|
|
for name, testCase := range testCases {
|
|
t.Run(name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
prefix, err := parseIPPrefix(testCase.value)
|
|
|
|
assert.Equal(t, testCase.prefix, prefix)
|
|
if testCase.errMessage != "" {
|
|
assert.EqualError(t, err, testCase.errMessage)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|