Refactor protocol handling for firewall rules, add engine tests

This commit is contained in:
Givi Khojanashvili
2023-03-21 17:56:47 +04:00
parent 0abd05d51e
commit 64ad771099
10 changed files with 263 additions and 112 deletions
+1
View File
@@ -44,6 +44,7 @@ type Manager interface {
// rule ID as comment for the rule
AddFiltering(
ip net.IP,
proto Protocol,
port *Port,
direction Direction,
action Action,
+12 -11
View File
@@ -54,6 +54,7 @@ func Create() (*Manager, error) {
// If comment is empty rule ID is used as comment
func (m *Manager) AddFiltering(
ip net.IP,
protocol fw.Protocol,
port *fw.Port,
direction fw.Direction,
action fw.Action,
@@ -74,27 +75,27 @@ func (m *Manager) AddFiltering(
}
}
var portValue, protocolValue string
var portValue string
if port != nil && port.Values != nil {
// TODO: we support only one port per rule in current implementation of ACLs
portValue = strconv.Itoa(port.Values[0])
switch port.Proto {
case fw.PortProtocolTCP:
protocolValue = "tcp"
case fw.PortProtocolUDP:
protocolValue = "udp"
default:
return nil, fmt.Errorf("unsupported protocol: %s", port.Proto)
}
}
ruleID := uuid.New().String()
if comment == "" {
comment = ruleID
}
specs := m.filterRuleSpecs(
"filter", ChainFilterName, ip, protocolValue,
portValue, direction, action, comment)
"filter",
ChainFilterName,
ip,
string(protocol),
portValue,
direction,
action,
comment,
)
if err := client.AppendUnique("filter", ChainFilterName, specs...); err != nil {
return nil, err
}
@@ -22,8 +22,8 @@ func TestNewManager(t *testing.T) {
var rule1 fw.Rule
t.Run("add first rule", func(t *testing.T) {
ip := net.ParseIP("10.20.0.2")
port := &fw.Port{Proto: fw.PortProtocolTCP, Values: []int{8080}}
rule1, err = manager.AddFiltering(ip, port, fw.DirectionDst, fw.ActionAccept, "accept HTTP traffic")
port := &fw.Port{Values: []int{8080}}
rule1, err = manager.AddFiltering(ip, "tcp", port, fw.DirectionDst, fw.ActionAccept, "accept HTTP traffic")
if err != nil {
t.Errorf("failed to add rule: %v", err)
}
@@ -35,11 +35,10 @@ func TestNewManager(t *testing.T) {
t.Run("add second rule", func(t *testing.T) {
ip := net.ParseIP("10.20.0.3")
port := &fw.Port{
Proto: fw.PortProtocolTCP,
Values: []int{8043: 8046},
}
rule2, err = manager.AddFiltering(
ip, port, fw.DirectionDst, fw.ActionAccept, "accept HTTPS traffic from ports range")
ip, "tcp", port, fw.DirectionDst, fw.ActionAccept, "accept HTTPS traffic from ports range")
if err != nil {
t.Errorf("failed to add rule: %v", err)
}
@@ -66,8 +65,8 @@ func TestNewManager(t *testing.T) {
t.Run("reset check", func(t *testing.T) {
// add second rule
ip := net.ParseIP("10.20.0.3")
port := &fw.Port{Proto: fw.PortProtocolUDP, Values: []int{5353}}
_, err = manager.AddFiltering(ip, port, fw.DirectionDst, fw.ActionAccept, "accept Fake DNS traffic")
port := &fw.Port{Values: []int{5353}}
_, err = manager.AddFiltering(ip, "udp", port, fw.DirectionDst, fw.ActionAccept, "accept Fake DNS traffic")
if err != nil {
t.Errorf("failed to add rule: %v", err)
}
+9 -9
View File
@@ -1,14 +1,17 @@
package firewall
// PortProtocol is the protocol of the port
type PortProtocol string
// Protocol is the protocol of the port
type Protocol string
const (
// PortProtocolTCP is the TCP protocol
PortProtocolTCP PortProtocol = "tcp"
// ProtocolTCP is the TCP protocol
ProtocolTCP Protocol = "tcp"
// PortProtocolUDP is the UDP protocol
PortProtocolUDP PortProtocol = "udp"
// ProtocolUDP is the UDP protocol
ProtocolUDP Protocol = "udp"
// ProtocolICMP is the ICMP protocol
ProtocolICMP Protocol = "icmp"
)
// Port of the address for firewall rule
@@ -18,7 +21,4 @@ type Port struct {
// Values contains one value for single port, multiple values for the list of ports, or two values for the range of ports
Values []int
// Proto is the protocol of the port
Proto PortProtocol
}