Skip to content

Commit

Permalink
feat: support icmp rules (#2)
Browse files Browse the repository at this point in the history
**Issue #, if available:**

## Description of changes:

Allow ICMP rules to be defined, these rules do not use fixed ports and
the direction needs to go both ways.

**Checklist**

<!--- Leave unchecked if your change doesn't seem to apply -->

* [x] Update tests
* [ ] Update docs
* [x] PR title follows [conventional commit
semantics](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#commit-message-for-a-fix-using-an-optional-issue-number)

By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice.
  • Loading branch information
Nr18 authored Jul 24, 2023
1 parent fa73bc2 commit aa5d16f
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 7 deletions.
2 changes: 1 addition & 1 deletion aws_network_firewall/destination.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Destination:

description: str
protocol: str
port: int
port: Optional[int]
endpoint: Optional[str]
region: Optional[str]
cidr: Optional[str]
Expand Down
2 changes: 1 addition & 1 deletion aws_network_firewall/schemas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def destination_resolver(entry: dict) -> Destination:
return Destination(
description=entry["Description"],
protocol=entry["Protocol"],
port=entry["Port"],
port=entry.get("Port"),
endpoint=entry.get("Endpoint"),
region=entry.get("Region"),
cidr=entry.get("Cidr"),
Expand Down
4 changes: 2 additions & 2 deletions aws_network_firewall/schemas/environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,13 @@ $defs:
Region:
type: string
Protocol:
enum: [ "TCP", "TLS" ]
enum: [ "TCP", "TLS", "ICMP" ]
Port:
type: integer
additionalProperties: False
required:
- Description
- Protocol
- Port
anyOf:
- required: ["Endpoint", "Cidr"]
not: { required: ["Region"] }
Expand All @@ -99,3 +98,4 @@ $defs:
not: { required: ["Endpoint", "Region"] }
# - not: { required: ["Endpoint", "Region", "Cidr"] }
# - not: { required: ["Region", "Cidr"] }
# Port is not required when Protocol is ICMP
7 changes: 5 additions & 2 deletions aws_network_firewall/suricata/host.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from dataclasses import dataclass
from typing import Union
from typing import Union, Optional


@dataclass
Expand All @@ -11,7 +11,10 @@ class Host:
"""

address: str = "any"
port: Union[str, int] = "any"
port: Optional[int] = None

def __post_init__(self):
self.port = "any" if not self.port else self.port

def __str__(self):
return f"{self.address} {self.port}"
6 changes: 5 additions & 1 deletion aws_network_firewall/suricata/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class Rule:
def __post_init__(self):
self.protocol = self.protocol.lower()

@property
def direction(self) -> str:
return "<>" if self.protocol == "icmp" else "->"

@property
def source(self) -> str:
addresses = list(map(lambda host: host.address, self.sources))
Expand All @@ -47,4 +51,4 @@ def __str__(self) -> str:

post_rule = f"\n{self.action} tcp {self.source} <> {self.destination} ({handshake_options})"

return f"{self.action} {self.protocol} {self.source} -> {self.destination} ({options}){post_rule}"
return f"{self.action} {self.protocol} {self.source} {self.direction} {self.destination} ({options}){post_rule}"
24 changes: 24 additions & 0 deletions tests/test_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,27 @@ def test_rule_no_cidr() -> None:
)

assert "" == str(rule)


def test_icmp_rule() -> None:
rule = Rule(
workload="my-workload",
name="my-rule",
description="My description",
sources=[Source(description="my source", cidr="10.0.0.0/24", region=None)],
destinations=[
Destination(
description="my destination",
protocol="ICMP",
port=None,
cidr="10.0.1.0/24",
endpoint=None,
region=None,
)
],
)

assert (
'pass icmp 10.0.0.0/24 any <> 10.0.1.0/24 any (msg:"my-workload | my-rule"; rev:"1"; sid:"XXX")'
== str(rule)
)

0 comments on commit aa5d16f

Please sign in to comment.