Skip to content

Commit 8322aed

Browse files
Make dns and snmpv3 authorized hosts region-based (#12)
1 parent 00ea681 commit 8322aed

File tree

8 files changed

+48
-16
lines changed

8 files changed

+48
-16
lines changed

audit_settings.yaml.example

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,18 +329,26 @@ login_security:
329329
DefaultConfigurationLanguage: English
330330

331331
# DNS Servers (Configure > Network > DNS)
332+
# Nest under the region. Region should be defined in inventory
332333
dns_servers:
333-
- 4.2.2.1
334-
- 4.2.2.2
334+
na:
335+
- 4.2.2.1
336+
- 4.2.2.2
337+
emea:
338+
- 1.1.1.1
335339

336340
# SNMPv3 (System > Administration > SNMP)
337341
snmpv3:
338342
Username: snmpv3_user
339343
AcceptQueries: Enable
340344
SendTraps: Enable
341-
AuthorizedHosts:
342-
- 10.1.100.101
343-
- 10.1.100.102
345+
AuthorizedHosts:
346+
na:
347+
- 10.1.100.101
348+
- 10.1.100.102
349+
emea:
350+
- 10.2.100.101
351+
- 10.2.100.102
344352

345353
# Time Settings (System > Administration > Time)
346354
time:

firewalls.yaml.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- hostname: example-host.network.sophos.com
22
port: 4444
3+
region: na
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
query {
22
devices (manufacturer: "Sophos", tags: "SFOS", tags__n: "Auxillary", status: "Active") {
33
name
4+
location {
5+
parent {
6+
parent {
7+
name
8+
}
9+
}
10+
}
411
}
512
}

nautobot_query/location_query.gql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
query {
22
devices(location: ["Abingdon", "Vancouver"], manufacturer:"Sophos", tags: "SFOS", tags__n:"Auxillary", status:"Active") {
33
name
4+
location {
5+
parent {
6+
parent {
7+
name
8+
}
9+
}
10+
}
411
}
512
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "sophos-firewall-audit"
3-
version = "1.0.15"
3+
version = "1.0.16"
44
description = "Sophos Firewall Audit"
55
authors = ["Matt Mullen <matt.mullen@sophos.com>"]
66
readme = "README.md"

sophos_firewall_audit/rules/dnsservers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def eval_dns_servers(fw_obj: SophosFirewall,
2727
dict: Audit results and output table(s)
2828
"""
2929

30-
expected_servers = sorted(settings["dns_servers"])
30+
expected_servers = sorted(settings["dns_servers"].get(fw_obj.region))
3131

3232
for i in range(1,3):
3333
try:

sophos_firewall_audit/rules/snmpv3.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def eval_snmpv3(fw_obj: SophosFirewall,
3030

3131
for i in range(1,3):
3232
try:
33-
result = fw_obj.get_tag_with_filter(xml_tag="SNMPv3User", key="Username", value=expected["Username"])
33+
result = fw_obj.get_tag_with_filter(xml_tag="SNMPv3User", key="Username", value=expected["Username"], operator="=")
3434
except SophosFirewallZeroRecords:
3535
result = None
3636
break
@@ -61,21 +61,25 @@ def eval_snmpv3(fw_obj: SophosFirewall,
6161

6262
# Changes for v22
6363
if result:
64-
if result["Response"]["@APIVersion"][:2] >= "22":
64+
if int(result["Response"]["@APIVersion"][:2]) >= 22:
6565
# Remove Name key since it did not exist pre-v22
6666
actual.pop("Name")
67-
# Rename "AuthorizedHosts" to "AuthorizedHostsIpv4" in expected
68-
expected["AuthorizedHostsIpv4"] = expected.pop("AuthorizedHosts")
67+
# Rename "AuthorizedHostsIpv4" to "AuthorizedHosts" to in actual
68+
actual["AuthorizedHosts"] = actual.pop("AuthorizedHostsIpv4")
6969
# Convert SendTraps and AcceptQueries from "Enabled/Disabled" to True/False
7070
expected["SendTraps"] = "true" if expected["SendTraps"] == "Enabled" else "false"
7171
expected["AcceptQueries"] = "true" if expected["AcceptQueries"] == "Enabled" else "false"
7272

73-
7473
output = []
7574
for key in expected:
7675
status = "AUDIT_PASS"
7776
if key in actual:
78-
if not expected[key] == actual[key]:
77+
if key == "AuthorizedHosts":
78+
if not expected[key].get(fw_obj.region) == actual[key]:
79+
status = "AUDIT_FAIL"
80+
result_dict["audit_result"] = "FAIL"
81+
result_dict["fail_ct"] += 1
82+
elif not expected[key] == actual[key]:
7983
status = "AUDIT_FAIL"
8084
result_dict["audit_result"] = "FAIL"
8185
result_dict["fail_ct"] += 1
@@ -88,7 +92,7 @@ def eval_snmpv3(fw_obj: SophosFirewall,
8892
result_dict["fail_ct"] += 1
8993

9094
if key == "AuthorizedHosts" and not actual.get(key) == "None" and status == "AUDIT_FAIL":
91-
actual_output = '\n'.join(format_diff(unified_diff(sorted(expected[key]), sorted(actual.get(key)), n=1000000000)))
95+
actual_output = '\n'.join(format_diff(unified_diff(sorted(expected[key].get(fw_obj.region)), sorted(actual.get(key)), n=1000000000)))
9296
elif key == "AuthorizedHosts" and not actual.get(key) == "None" and status == "AUDIT_PASS":
9397
actual_output = '\n'.join(actual.get(key))
9498
else:
@@ -98,7 +102,7 @@ def eval_snmpv3(fw_obj: SophosFirewall,
98102
"SNMPv3",
99103
"System > Administration > SNMP",
100104
key,
101-
'\n'.join(expected[key]) if key == "AuthorizedHosts" else expected[key],
105+
'\n'.join(expected[key].get(fw_obj.region)) if key == "AuthorizedHosts" else expected[key],
102106
actual_output,
103107
html_status(status)
104108
])

sophos_firewall_audit/sophosfirewallaudit.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ def nb_graphql_query(query, verify):
5858
token = os.environ.get("NAUTOBOT_TOKEN")
5959
nautobot = api(url=url, token=token, verify=verify)
6060
graphql_response = nautobot.graphql.query(query=query)
61-
return [{"hostname": firewall["name"], "port": "4444"} for firewall in graphql_response.json["data"]["devices"]]
61+
return [{"hostname": firewall["name"], "port": "4444",
62+
"region": firewall["location"]["parent"]["parent"]["name"].lower()}
63+
for firewall in graphql_response.json["data"]["devices"]
64+
if firewall["location"]["parent"].get("parent")
65+
]
6266

6367
def device_query(environ, devices):
6468
"""Generate GraphQL query
@@ -182,6 +186,7 @@ def main():
182186
port=firewall['port'],
183187
verify=False
184188
)
189+
fw.region = firewall.get("region")
185190
try:
186191
fw.login()
187192
except Exception as Error:

0 commit comments

Comments
 (0)