Skip to content

Commit

Permalink
fix: #66 OoB mgmt security safeguard behavior change
Browse files Browse the repository at this point in the history
  • Loading branch information
takishida committed Aug 30, 2023
1 parent d2e5051 commit 4203b7e
Show file tree
Hide file tree
Showing 8 changed files with 805 additions and 1 deletion.
70 changes: 69 additions & 1 deletion aci-preupgrade-validation-script.py
Original file line number Diff line number Diff line change
Expand Up @@ -2722,6 +2722,74 @@ def uplink_limit_check(index, total_checks, cversion, tversion, **kwargs):
return result


def oob_mgmt_security_check(index, total_checks, cversion, tversion, **kwargs):
"""Implementation change due to CSCvx29282/CSCvz96117"""
title = "OoB Mgmt Security"
result = PASS
msg = ""
headers = ["ACI Node EPG", "External Instance (Subnets)", "OoB Contracts"]
data = []
recommended_action = (
"\n\tEnsure that ICMP, SSH and HTTPS access are allowed for the required subnets with the above config."
"\n\tOtherwise, APIC access will be limited to the above subnets and the same subnet as APIC OoB after the upgrade."
)
doc_url = "https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#oob-mgmt-security"

print_title(title, index, total_checks)

if not tversion:
print_result(title, MANUAL, "Target version not supplied. Skipping.")
return MANUAL

affected_versions = ["4.2(7)", "5.2(1)", "5.2(2)"]
if cversion.simple_version not in affected_versions or (
cversion.simple_version in affected_versions
and tversion.simple_version in affected_versions
):
print_result(title, NA)
return NA

# ACI Node EPGs (providers)
mgmtOoBs = icurl("class", "mgmtOoB.json?rsp-subtree=children")
# External Instant Profiles (consumers)
mgmtInstPs = icurl("class", "mgmtInstP.json?rsp-subtree=children")

contract_to_providers = defaultdict(list)
for mgmtOoB in mgmtOoBs:
for child in mgmtOoB["mgmtOoB"].get("children", []):
if child.get("mgmtRsOoBProv"):
epg_name = mgmtOoB["mgmtOoB"]["attributes"]["name"]
contract_name = child["mgmtRsOoBProv"]["attributes"]["tnVzOOBBrCPName"]
contract_to_providers[contract_name].append(epg_name)

for mgmtInstP in mgmtInstPs:
consumer = mgmtInstP["mgmtInstP"]["attributes"]["name"]
providers = defaultdict(list)
subnets = []
for child in mgmtInstP["mgmtInstP"].get("children", []):
if child.get("mgmtRsOoBCons"):
contract = child["mgmtRsOoBCons"]["attributes"]["tnVzOOBBrCPName"]
for prov in contract_to_providers.get(contract, []):
providers[prov].append(contract)
elif child.get("mgmtSubnet"):
subnets.append(child["mgmtSubnet"]["attributes"]["ip"])

if not subnets or not providers:
continue

for provider, contracts in providers.items():
data.append([
provider,
"{} ({})".format(consumer, ", ".join(subnets)),
", ".join(contracts)
])

if data:
result = MANUAL
print_result(title, result, msg, headers, data, recommended_action=recommended_action, doc_url=doc_url)
return result


if __name__ == "__main__":
prints(' ==== %s%s, Script Version %s ====\n' % (ts, tz, SCRIPT_VERSION))
prints('!!!! Check https://github.com/datacenter/ACI-Pre-Upgrade-Validation-Script for Latest Release !!!!\n')
Expand Down Expand Up @@ -2789,7 +2857,7 @@ def uplink_limit_check(index, total_checks, cversion, tversion, **kwargs):
bgp_golf_route_target_type_check,
docker0_subnet_overlap_check,
uplink_limit_check,

oob_mgmt_security_check,

# Bugs
ep_announce_check,
Expand Down
15 changes: 15 additions & 0 deletions docs/docs/validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Items | Faults | This Script
[BGP Route-target Type for GOLF over L2EVPN][c8] | :white_check_mark: | :no_entry_sign: | :white_check_mark:
[APIC Container Bridge IP Overlap with APIC TEP][c9] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:
[Per-Leaf Fabric Uplink Scale Validation][c10] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:
[OoB Mgmt Security][c11] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:

[c1]: #vpc-paired-leaf-switches
[c2]: #overlapping-vlan-pool
Expand All @@ -110,6 +111,7 @@ Items | Faults | This Script
[c8]: #bgp-route-target-type-for-golf-over-l2evpn
[c9]: #apic-container-bridge-ip-overlap-with-apic-tep
[c10]: #fabric-uplink-scale-cannot-exceed-56-uplinks-per-leaf
[c11]: #oob-mgmt-security


### Defect Condition Checks
Expand Down Expand Up @@ -1198,6 +1200,19 @@ To avoid this, explicitly modify the port profile uplink scale to be 56 or less
The script counts the amount of port-profile provisioned uplinks per leaf, and fails if any leaf is found to surpass 56.


### OoB Mgmt Security

In the configuration of APIC Out-of-Band Management EPG, users can limit the protocols and source IP addresses that can access APIC nodes.

To prevent accidental blocking of necessary access to APIC, essential access (ICMP, SSH, HTTP, and HTTPS) to APICs from the same subnet as the APIC OoB IP address is always permitted, regardless of the contracts and subnets configuration of the OoB Management EPG.

Starting from releases 4.2(7) and 5.2(1), this safeguard implementation was extended to allow ICMP, SSH, and HTTPS from any source. However, CSCvz96117 reverted this change in release 5.2(3) due to use cases where ICMP, SSH, and HTTPS should only be allowed from a known secure source — the same subnet as the APIC OoB IP address and other user-configured IP addresses.

This implies that for users running releases 4.2(7), 5.2(1), or 5.2(2), and when the OoB Management EPG is configured with contracts to restrict ICMP, SSH and HTTPS access to a specific subnet, OoB security is not honored, and those can still be allowed from any subnet. After upgrading to release 5.2(3) or a newer version, OoB Management access to APICs will only be permitted from the configured subnet or ICMP, SSH, HTTP and HTTPS from the same subnet as the APIC OoB IP addresses as it were before 4.2(7). This change might catch users by surprise if they were previously accessing APICs via ICMP, SSH, or HTTPS from a subnet other than the configured one.

The script checks whether you should be aware of this change in behavior prior to your ACI upgrade so that appropriate subnets can be added to the configuration or you can prepare a workstation that is within the configured subnet, which will continue to be accessible to APICs even after the upgrade.


## Defect Check Details

### EP Announce Compatibility
Expand Down
147 changes: 147 additions & 0 deletions tests/oob_mgmt_security_check/mgmtInstP.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
[
{
"mgmtInstP": {
"attributes": {
"annotation": "",
"childAction": "",
"configIssues": "",
"configSt": "applied",
"descr": "",
"dn": "uni/tn-mgmt/extmgmt-default/instp-EXTERNAL",
"extMngdBy": "",
"lcOwn": "local",
"modTs": "2023-08-21T14:28:13.899-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"name": "EXTERNAL",
"nameAlias": "",
"pcTag": "32770",
"pcTagAllocSrc": "idmanager",
"prio": "unspecified",
"scope": "2457600",
"status": "",
"uid": "15374",
"userdom": ":all:"
},
"children": [
{
"mgmtRsOoBCons": {
"attributes": {
"annotation": "",
"childAction": "",
"deplInfo": "",
"extMngdBy": "",
"forceResolve": "yes",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:19.174-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"prio": "unspecified",
"rType": "mo",
"rn": "rsooBCons-ssh",
"state": "formed",
"stateQual": "none",
"status": "",
"tCl": "vzOOBBrCP",
"tContextDn": "",
"tDn": "uni/tn-mgmt/oobbrc-ssh",
"tRn": "oobbrc-ssh",
"tType": "name",
"tnVzOOBBrCPName": "ssh",
"triggerSt": "triggerable",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtRsOoBCons": {
"attributes": {
"annotation": "",
"childAction": "",
"deplInfo": "",
"extMngdBy": "",
"forceResolve": "yes",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:12.598-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"prio": "unspecified",
"rType": "mo",
"rn": "rsooBCons-icmp",
"state": "formed",
"stateQual": "none",
"status": "",
"tCl": "vzOOBBrCP",
"tContextDn": "",
"tDn": "uni/tn-mgmt/oobbrc-icmp",
"tRn": "oobbrc-icmp",
"tType": "name",
"tnVzOOBBrCPName": "icmp",
"triggerSt": "triggerable",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtSubnet": {
"attributes": {
"annotation": "",
"childAction": "",
"descr": "",
"extMngdBy": "",
"ip": "192.168.1.0/24",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:41.662-07:00",
"name": "",
"nameAlias": "",
"rn": "subnet-[192.168.1.0/24]",
"status": "",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtSubnet": {
"attributes": {
"annotation": "",
"childAction": "",
"descr": "",
"extMngdBy": "",
"ip": "10.0.0.0/8",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:29.523-07:00",
"name": "",
"nameAlias": "",
"rn": "subnet-[10.0.0.0/8]",
"status": "",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtRsInstPCtx": {
"attributes": {
"childAction": "",
"forceResolve": "yes",
"lcOwn": "local",
"modTs": "2023-08-21T14:28:13.870-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"rType": "mo",
"rn": "rsinstPCtx",
"state": "formed",
"stateQual": "none",
"status": "",
"tCl": "fvCtx",
"tContextDn": "",
"tDn": "uni/tn-mgmt/ctx-oob",
"tRn": "ctx-oob",
"tType": "name",
"tnFvCtxName": ""
}
}
}
]
}
}
]
89 changes: 89 additions & 0 deletions tests/oob_mgmt_security_check/mgmtInstP_no_contracts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
[
{
"mgmtInstP": {
"attributes": {
"annotation": "",
"childAction": "",
"configIssues": "",
"configSt": "applied",
"descr": "",
"dn": "uni/tn-mgmt/extmgmt-default/instp-EXTERNAL",
"extMngdBy": "",
"lcOwn": "local",
"modTs": "2023-08-21T14:28:13.899-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"name": "EXTERNAL",
"nameAlias": "",
"pcTag": "32770",
"pcTagAllocSrc": "idmanager",
"prio": "unspecified",
"scope": "2457600",
"status": "",
"uid": "15374",
"userdom": ":all:"
},
"children": [
{
"mgmtSubnet": {
"attributes": {
"annotation": "",
"childAction": "",
"descr": "",
"extMngdBy": "",
"ip": "192.168.1.0/24",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:41.662-07:00",
"name": "",
"nameAlias": "",
"rn": "subnet-[192.168.1.0/24]",
"status": "",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtSubnet": {
"attributes": {
"annotation": "",
"childAction": "",
"descr": "",
"extMngdBy": "",
"ip": "10.0.0.0/8",
"lcOwn": "local",
"modTs": "2023-08-22T16:32:29.523-07:00",
"name": "",
"nameAlias": "",
"rn": "subnet-[10.0.0.0/8]",
"status": "",
"uid": "15374",
"userdom": ":all:"
}
}
},
{
"mgmtRsInstPCtx": {
"attributes": {
"childAction": "",
"forceResolve": "yes",
"lcOwn": "local",
"modTs": "2023-08-21T14:28:13.870-07:00",
"monPolDn": "uni/tn-common/monepg-default",
"rType": "mo",
"rn": "rsinstPCtx",
"state": "formed",
"stateQual": "none",
"status": "",
"tCl": "fvCtx",
"tContextDn": "",
"tDn": "uni/tn-mgmt/ctx-oob",
"tRn": "ctx-oob",
"tType": "name",
"tnFvCtxName": ""
}
}
}
]
}
}
]
Loading

0 comments on commit 4203b7e

Please sign in to comment.